MD2 & Patch drawing fixes

MD2's can be translucent again.
MD2's can use sprites instead of another random texture if they have no
texture.
Patches are drawn in the correct place on non aspect correct
resolutions.
Cropped Patches are drawn.
This commit is contained in:
Sryder13 2014-03-19 23:10:37 +00:00
parent 2fed5d1270
commit ba0c93d814
7 changed files with 100 additions and 59 deletions

View file

@ -469,7 +469,7 @@ extern const char *compdate, *comptime, *comprevision;
#if !defined (_NDS) && !defined (_PSP) #if !defined (_NDS) && !defined (_PSP)
/// Shuffle's incomplete OpenGL sorting code. /// Shuffle's incomplete OpenGL sorting code.
//#define SHUFFLE #define SHUFFLE // This has nothing to do with sorting, why was it disabled?
#endif #endif
#if !defined (_NDS) && !defined (_PSP) #if !defined (_NDS) && !defined (_PSP)

View file

@ -209,6 +209,76 @@ void HWR_DrawSciencePatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, INT32 option,
HWD.pfnDrawPolygon(NULL, v, 4, flags); HWD.pfnDrawPolygon(NULL, v, 4, flags);
} }
void HWR_DrawCroppedPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option, fixed_t scale, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h)
{
FOutVector v[4];
FBITFIELD flags;
float cx = FIXED_TO_FLOAT(x);
float cy = FIXED_TO_FLOAT(y);
// 3--2
// | /|
// |/ |
// 0--1
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(scale);
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(scale);
// make patch ready in hardware cache
HWR_GetPatch(gpatch);
switch (option & V_SCALEPATCHMASK)
{
case V_NOSCALEPATCH:
pdupx = pdupy = 2.0f;
break;
case V_SMALLSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx);
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy);
break;
case V_MEDSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx);
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy);
break;
}
if (option & V_NOSCALESTART)
sdupx = sdupy = 2.0f;
v[0].x = v[3].x = (cx*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1;
v[2].x = v[1].x = ((cx-sx)*sdupx+(w-gpatch->leftoffset)*pdupx)/vid.width - 1;
v[0].y = v[1].y = 1-(cy*sdupy-gpatch->topoffset*pdupy)/vid.height;
v[2].y = v[3].y = 1-((cy-sy)*sdupy+(h-gpatch->topoffset)*pdupy)/vid.height;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = ((float)sx/(float)gpatch->height);
v[2].sow = v[1].sow = gpatch->max_s*((float)w/(float)gpatch->width);
v[0].tow = v[1].tow = ((float)sy/(float)gpatch->height);
v[2].tow = v[3].tow = gpatch->max_t*((float)h/(float)gpatch->height);
flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
if (option & V_WRAPY)
flags |= PF_ForceWrapY;
// clip it since it is used for bunny scroll in doom I
if (option & V_TRANSLUCENT)
{
FSurfaceInfo Surf;
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff;
Surf.FlatColor.s.alpha = (UINT8)cv_grtranslucenthud.value;
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
}
else
HWD.pfnDrawPolygon(NULL, v, 4, flags);
}
void HWR_DrawClippedPatch (GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) void HWR_DrawClippedPatch (GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option)
{ {
// hardware clips the patch quite nicely anyway :) // hardware clips the patch quite nicely anyway :)

View file

@ -1212,23 +1212,17 @@ static void HWR_SplitFog(sector_t *sector, wallVert3D *wallVerts, FSurfaceInfo*
if (list[i].caster) if (list[i].caster)
{ {
if (sector->lightlist[i].caster->flags & FF_SOLID && !(cutflag & FF_EXTRA)) if (sector->lightlist[i].caster->flags & FF_FOG && cutflag & FF_FOG) // Only fog cuts fog
solid = true;
else if (sector->lightlist[i].caster->flags & FF_CUTEXTRA && cutflag & FF_EXTRA)
{ {
if (sector->lightlist[i].caster->flags & FF_EXTRA) if (sector->lightlist[i].caster->flags & FF_EXTRA)
{ {
if (sector->lightlist[i].caster->flags == cutflag) if (sector->lightlist[i].caster->flags == cutflag) // only cut by the same
solid = true; solid = true;
} }
else else
solid = true; solid = true;
} }
else
solid = false;
} }
else
solid = false;
height = FIXED_TO_FLOAT(list[i].height); height = FIXED_TO_FLOAT(list[i].height);
@ -3385,30 +3379,17 @@ noshadow:
if (sector->numlights) if (sector->numlights)
{ {
INT32 light = R_GetPlaneLight(sector, spr->mobj->z, false); INT32 light;
if ((sector->lightlist[light].height > (spr->mobj->z + spr->mobj->height)) && !(sector->lightlist[light].flags & FF_NOSHADE)) light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel);
else
lightlevel = LightLevelToLum(255);
if (sector->lightlist[light].extra_colormap) if (!(spr->mobj->frame & FF_FULLBRIGHT))
colormap = sector->lightlist[light].extra_colormap; lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel);
} else
else // If we can't use the light at its bottom, we'll use the light at its top lightlevel = LightLevelToLum(255);
{
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false);
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (sector->lightlist[light].extra_colormap)
lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel); colormap = sector->lightlist[light].extra_colormap;
else
lightlevel = LightLevelToLum(255);
if (sector->lightlist[light].extra_colormap)
colormap = sector->lightlist[light].extra_colormap;
}
} }
else else
{ {

View file

@ -45,6 +45,7 @@ void HWR_SetViewSize(void);
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawClippedPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawClippedPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawSciencePatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, INT32 option, fixed_t scale); void HWR_DrawSciencePatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, INT32 option, fixed_t scale);
void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, INT32 option, fixed_t scale, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void HWR_DrawTranslucentPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawTranslucentPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawSmallPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option, const UINT8 *colormap); void HWR_DrawSmallPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option, const UINT8 *colormap);
void HWR_DrawMappedPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option, const UINT8 *colormap); void HWR_DrawMappedPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option, const UINT8 *colormap);

View file

@ -1087,30 +1087,17 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
if (sector->numlights) if (sector->numlights)
{ {
INT32 light = R_GetPlaneLight(sector, spr->mobj->z, false); INT32 light;
if (sector->lightlist[light].height > (spr->mobj->z + spr->mobj->height)) light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel);
else
lightlevel = LightLevelToLum(255);
if (sector->lightlist[light].extra_colormap) if (!(spr->mobj->frame & FF_FULLBRIGHT))
colormap = sector->lightlist[light].extra_colormap; lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel);
} else
else // If we can't use the light at its bottom, we'll use the light at its top lightlevel = LightLevelToLum(255);
{
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false);
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (sector->lightlist[light].extra_colormap)
lightlevel = LightLevelToLum(*sector->lightlist[light].lightlevel); colormap = sector->lightlist[light].extra_colormap;
else
lightlevel = LightLevelToLum(255);
if (sector->lightlist[light].extra_colormap)
colormap = sector->lightlist[light].extra_colormap;
}
} }
else else
{ {
@ -1156,7 +1143,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
else else
{ {
Surf.FlatColor.s.alpha = 0xFF; Surf.FlatColor.s.alpha = 0xFF;
blend = PF_Translucent; blend = PF_Translucent|PF_Occlude;
} }
// dont forget to enabled the depth test because we can't do this like // dont forget to enabled the depth test because we can't do this like
@ -1164,7 +1151,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
// 1. load model+texture if not already loaded // 1. load model+texture if not already loaded
// 2. draw model with correct position, rotation,... // 2. draw model with correct position, rotation,...
if (spr->mobj->skin) if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) // Use the player MD2 list if the mobj has a skin and is using the player sprites
{ {
md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins]; md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins];
md2->skin = (skin_t*)spr->mobj->skin-skins; md2->skin = (skin_t*)spr->mobj->skin-skins;
@ -1188,13 +1175,14 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
return; return;
} }
} }
HWD.pfnSetBlend(blend); //HWD.pfnSetBlend(blend); // This seems to actually break translucency?
finalscale = md2->scale; finalscale = md2->scale;
//Hurdler: arf, I don't like that implementation at all... too much crappy //Hurdler: arf, I don't like that implementation at all... too much crappy
gpatch = md2->grpatch; gpatch = md2->grpatch;
if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded) if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded)
md2_loadTexture(md2); md2_loadTexture(md2);
else if (gpatch->mipmap.grInfo.format)
if (gpatch && gpatch->mipmap.grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
{ {
// This is safe, since we know the texture has been downloaded // This is safe, since we know the texture has been downloaded
HWD.pfnSetTexture(&gpatch->mipmap); HWD.pfnSetTexture(&gpatch->mipmap);
@ -1211,7 +1199,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
buff = md2->model->glCommandBuffer; buff = md2->model->glCommandBuffer;
curr = &md2->model->frames[frame]; curr = &md2->model->frames[frame];
if (cv_grmd2.value == 1 if (cv_grmd2.value == 1
&& spr->mobj->state->nextstate != S_NULL && spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
&& !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND])) && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND]))
{ {
const INT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; const INT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;

View file

@ -227,7 +227,7 @@ void SCR_Startup(void)
vid.dupx = vid.dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); vid.dupx = vid.dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
vid.fdupx = FixedDiv(vid.width*FRACUNIT, BASEVIDWIDTH*FRACUNIT); vid.fdupx = FixedDiv(vid.width*FRACUNIT, BASEVIDWIDTH*FRACUNIT);
vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT); vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT);
vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy); //vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy); // This was just placing it incorrectly at non aspect correct resolutions
vid.meddupx = (UINT8)(vid.dupx >> 1) + 1; vid.meddupx = (UINT8)(vid.dupx >> 1) + 1;
vid.meddupy = (UINT8)(vid.dupy >> 1) + 1; vid.meddupy = (UINT8)(vid.dupy >> 1) + 1;
@ -269,7 +269,7 @@ void SCR_Recalc(void)
vid.dupx = vid.dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); vid.dupx = vid.dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
vid.fdupx = FixedDiv(vid.width*FRACUNIT, BASEVIDWIDTH*FRACUNIT); vid.fdupx = FixedDiv(vid.width*FRACUNIT, BASEVIDWIDTH*FRACUNIT);
vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT); vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT);
vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy); //vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy); // This was just placing it incorrectly at non aspect correct resolutions
//vid.baseratio = FixedDiv(vid.height << FRACBITS, BASEVIDHEIGHT << FRACBITS); //vid.baseratio = FixedDiv(vid.height << FRACBITS, BASEVIDHEIGHT << FRACBITS);
vid.baseratio = FRACUNIT; vid.baseratio = FRACUNIT;

View file

@ -1040,8 +1040,9 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, INT32 scrn, patch_t *patch, fixed_
const UINT8 *source, *deststop; const UINT8 *source, *deststop;
#ifdef HWRENDER #ifdef HWRENDER
// fuck off // Done
if (rendermode != render_soft && rendermode != render_none) if (rendermode != render_soft && rendermode != render_none)
HWR_DrawCroppedPatch((GLPatch_t *)patch, x, y, scrn, science, sx, sy, w, h);
return; return;
#endif #endif