mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-22 02:42:20 +00:00
Merge branch 'next' of https://git.magicalgirl.moe/STJr/SRB2/ into udmf-next
This commit is contained in:
commit
2cdfb8ffc6
5 changed files with 242 additions and 25 deletions
|
@ -126,7 +126,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
{
|
||||
case 2 : // uhhhhhhhh..........
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha);
|
||||
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
|
||||
texelu16 = (UINT16)((alpha<<8) | texel);
|
||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||
break;
|
||||
|
@ -135,7 +135,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
{
|
||||
RGBA_t rgbatexel;
|
||||
rgbatexel.rgba = *(UINT32 *)dest;
|
||||
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
break;
|
||||
|
@ -145,14 +145,14 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
{
|
||||
RGBA_t rgbatexel;
|
||||
rgbatexel.rgba = *(UINT32 *)dest;
|
||||
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t));
|
||||
break;
|
||||
// default is 1
|
||||
default:
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
*dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha);
|
||||
*dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
|
||||
else
|
||||
*dest = texel;
|
||||
break;
|
||||
|
@ -238,7 +238,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
{
|
||||
case 2 : // uhhhhhhhh..........
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha);
|
||||
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
|
||||
texelu16 = (UINT16)((alpha<<8) | texel);
|
||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||
break;
|
||||
|
@ -247,7 +247,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
{
|
||||
RGBA_t rgbatexel;
|
||||
rgbatexel.rgba = *(UINT32 *)dest;
|
||||
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
break;
|
||||
|
@ -257,14 +257,14 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
{
|
||||
RGBA_t rgbatexel;
|
||||
rgbatexel.rgba = *(UINT32 *)dest;
|
||||
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t));
|
||||
break;
|
||||
// default is 1
|
||||
default:
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
*dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha);
|
||||
*dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
|
||||
else
|
||||
*dest = texel;
|
||||
break;
|
||||
|
|
|
@ -63,6 +63,7 @@ typedef struct gr_vissprite_s
|
|||
{
|
||||
float x1, x2;
|
||||
float tz, ty;
|
||||
float tracertz; // for MF2_LINKDRAW sprites, this contains tracer's tz for use in sorting
|
||||
//lumpnum_t patchlumpnum;
|
||||
GLPatch_t *gpatch;
|
||||
boolean flip;
|
||||
|
|
|
@ -3454,6 +3454,54 @@ static gr_vissprite_t *HWR_NewVisSprite(void)
|
|||
return HWR_GetVisSprite(gr_visspritecount++);
|
||||
}
|
||||
|
||||
// A hack solution for transparent surfaces appearing on top of linkdraw sprites.
|
||||
// Keep a list of linkdraw sprites and draw their shapes to the z-buffer after all other
|
||||
// sprite drawing is done. (effectively the z-buffer drawing of linkdraw sprites is delayed)
|
||||
// NOTE: This will no longer be necessary once full translucent sorting is implemented, where
|
||||
// translucent sprites and surfaces are sorted together.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FOutVector verts[4];
|
||||
gr_vissprite_t *spr;
|
||||
} zbuffersprite_t;
|
||||
|
||||
// this list is used to store data about linkdraw sprites
|
||||
zbuffersprite_t linkdrawlist[MAXVISSPRITES];
|
||||
UINT32 linkdrawcount = 0;
|
||||
|
||||
// add the necessary data to the list for delayed z-buffer drawing
|
||||
static void HWR_LinkDrawHackAdd(FOutVector *verts, gr_vissprite_t *spr)
|
||||
{
|
||||
if (linkdrawcount < MAXVISSPRITES)
|
||||
{
|
||||
memcpy(linkdrawlist[linkdrawcount].verts, verts, sizeof(FOutVector) * 4);
|
||||
linkdrawlist[linkdrawcount].spr = spr;
|
||||
linkdrawcount++;
|
||||
}
|
||||
}
|
||||
|
||||
// process and clear the list of sprites for delayed z-buffer drawing
|
||||
static void HWR_LinkDrawHackFinish(void)
|
||||
{
|
||||
UINT32 i;
|
||||
FSurfaceInfo surf;
|
||||
surf.PolyColor.rgba = 0xFFFFFFFF;
|
||||
surf.TintColor.rgba = 0xFFFFFFFF;
|
||||
surf.FadeColor.rgba = 0xFFFFFFFF;
|
||||
surf.LightInfo.light_level = 0;
|
||||
surf.LightInfo.fade_start = 0;
|
||||
surf.LightInfo.fade_end = 31;
|
||||
for (i = 0; i < linkdrawcount; i++)
|
||||
{
|
||||
// draw sprite shape, only to z-buffer
|
||||
HWR_GetPatch(linkdrawlist[i].spr->gpatch);
|
||||
HWR_ProcessPolygon(&surf, linkdrawlist[i].verts, 4, PF_Translucent|PF_Occlude|PF_Invisible|PF_Clip, 0, false);
|
||||
}
|
||||
// reset list
|
||||
linkdrawcount = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// HWR_DoCulling
|
||||
// Hardware version of R_DoCulling
|
||||
|
@ -3640,6 +3688,8 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
extracolormap_t *colormap;
|
||||
FUINT lightlevel;
|
||||
FBITFIELD blend = 0;
|
||||
FBITFIELD occlusion;
|
||||
boolean use_linkdraw_hack = false;
|
||||
UINT8 alpha;
|
||||
|
||||
INT32 i;
|
||||
|
@ -3733,10 +3783,18 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
// co-ordinates
|
||||
memcpy(wallVerts, baseWallVerts, sizeof(baseWallVerts));
|
||||
|
||||
// if sprite has linkdraw, then dont write to z-buffer (by not using PF_Occlude)
|
||||
// this will result in sprites drawn afterwards to be drawn on top like intended when using linkdraw.
|
||||
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
|
||||
occlusion = 0;
|
||||
else
|
||||
occlusion = PF_Occlude;
|
||||
|
||||
if (!cv_translucency.value) // translucency disabled
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
blend = PF_Translucent|PF_Occlude;
|
||||
blend = PF_Translucent|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
else if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
{
|
||||
|
@ -3752,7 +3810,8 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
// Hurdler: PF_Environement would be cool, but we need to fix
|
||||
// the issue with the fog before
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
blend = PF_Translucent|PF_Occlude;
|
||||
blend = PF_Translucent|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
|
||||
alpha = Surf.PolyColor.s.alpha;
|
||||
|
@ -3857,6 +3916,9 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader
|
||||
|
||||
if (use_linkdraw_hack)
|
||||
HWR_LinkDrawHackAdd(wallVerts, spr);
|
||||
|
||||
top = bot;
|
||||
endtop = endbot;
|
||||
}
|
||||
|
@ -3882,6 +3944,9 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
Surf.PolyColor.s.alpha = alpha;
|
||||
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader
|
||||
|
||||
if (use_linkdraw_hack)
|
||||
HWR_LinkDrawHackAdd(wallVerts, spr);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
|
@ -4004,10 +4069,21 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
|
||||
{
|
||||
FBITFIELD blend = 0;
|
||||
FBITFIELD occlusion;
|
||||
boolean use_linkdraw_hack = false;
|
||||
|
||||
// if sprite has linkdraw, then dont write to z-buffer (by not using PF_Occlude)
|
||||
// this will result in sprites drawn afterwards to be drawn on top like intended when using linkdraw.
|
||||
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
|
||||
occlusion = 0;
|
||||
else
|
||||
occlusion = PF_Occlude;
|
||||
|
||||
if (!cv_translucency.value) // translucency disabled
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
blend = PF_Translucent|PF_Occlude;
|
||||
blend = PF_Translucent|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
else if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
{
|
||||
|
@ -4023,10 +4099,14 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
// Hurdler: PF_Environement would be cool, but we need to fix
|
||||
// the issue with the fog before
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
blend = PF_Translucent|PF_Occlude;
|
||||
blend = PF_Translucent|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader
|
||||
|
||||
if (use_linkdraw_hack)
|
||||
HWR_LinkDrawHackAdd(wallVerts, spr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4142,6 +4222,7 @@ static int CompareVisSprites(const void *p1, const void *p2)
|
|||
gr_vissprite_t* spr2 = *(gr_vissprite_t*const*)p2;
|
||||
int idiff;
|
||||
float fdiff;
|
||||
float tz1, tz2;
|
||||
|
||||
// Make transparent sprites last. Comment from the previous sort implementation:
|
||||
// Sryder: Oh boy, while it's nice having ALL the sprites sorted properly, it fails when we bring MD2's into the
|
||||
|
@ -4149,12 +4230,52 @@ static int CompareVisSprites(const void *p1, const void *p2)
|
|||
// everything else, but still ordered of course, the depth buffer can handle the opaque ones plenty fine.
|
||||
// We just need to move all translucent ones to the end in order
|
||||
// TODO: Fully sort all sprites and MD2s with walls and floors, this part will be unnecessary after that
|
||||
int transparency1 = (spr1->mobj->flags2 & MF2_SHADOW) || (spr1->mobj->frame & FF_TRANSMASK);
|
||||
int transparency2 = (spr2->mobj->flags2 & MF2_SHADOW) || (spr2->mobj->frame & FF_TRANSMASK);
|
||||
int transparency1;
|
||||
int transparency2;
|
||||
|
||||
int linkdraw1 = (spr1->mobj->flags2 & MF2_LINKDRAW) && spr1->mobj->tracer;
|
||||
int linkdraw2 = (spr2->mobj->flags2 & MF2_LINKDRAW) && spr2->mobj->tracer;
|
||||
|
||||
// ^ is the XOR operation
|
||||
// if comparing a linkdraw and non-linkdraw sprite or 2 linkdraw sprites with different tracers, then use
|
||||
// the tracer's properties instead of the main sprite's.
|
||||
if ((linkdraw1 && linkdraw2 && spr1->mobj->tracer != spr2->mobj->tracer) || (linkdraw1 ^ linkdraw2))
|
||||
{
|
||||
if (linkdraw1)
|
||||
{
|
||||
tz1 = spr1->tracertz;
|
||||
transparency1 = (spr1->mobj->tracer->flags2 & MF2_SHADOW) || (spr1->mobj->tracer->frame & FF_TRANSMASK);
|
||||
}
|
||||
else
|
||||
{
|
||||
tz1 = spr1->tz;
|
||||
transparency1 = (spr1->mobj->flags2 & MF2_SHADOW) || (spr1->mobj->frame & FF_TRANSMASK);
|
||||
}
|
||||
if (linkdraw2)
|
||||
{
|
||||
tz2 = spr2->tracertz;
|
||||
transparency2 = (spr2->mobj->tracer->flags2 & MF2_SHADOW) || (spr2->mobj->tracer->frame & FF_TRANSMASK);
|
||||
}
|
||||
else
|
||||
{
|
||||
tz2 = spr2->tz;
|
||||
transparency2 = (spr2->mobj->flags2 & MF2_SHADOW) || (spr2->mobj->frame & FF_TRANSMASK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tz1 = spr1->tz;
|
||||
transparency1 = (spr1->mobj->flags2 & MF2_SHADOW) || (spr1->mobj->frame & FF_TRANSMASK);
|
||||
tz2 = spr2->tz;
|
||||
transparency2 = (spr2->mobj->flags2 & MF2_SHADOW) || (spr2->mobj->frame & FF_TRANSMASK);
|
||||
}
|
||||
|
||||
// first compare transparency flags, then compare tz, then compare dispoffset
|
||||
|
||||
idiff = transparency1 - transparency2;
|
||||
if (idiff != 0) return idiff;
|
||||
|
||||
fdiff = spr2->tz - spr1->tz; // this order seems correct when checking with apitrace. Back to front.
|
||||
fdiff = tz2 - tz1; // this order seems correct when checking with apitrace. Back to front.
|
||||
if (fabsf(fdiff) < 1.0E-36f)
|
||||
return spr1->dispoffset - spr2->dispoffset; // smallest dispoffset first if sprites are at (almost) same location.
|
||||
else if (fdiff > 0)
|
||||
|
@ -4478,6 +4599,7 @@ static void HWR_CreateDrawNodes(void)
|
|||
static void HWR_DrawSprites(void)
|
||||
{
|
||||
UINT32 i;
|
||||
boolean skipshadow = false; // skip shadow if it was drawn already for a linkdraw sprite encountered earlier in the list
|
||||
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value);
|
||||
for (i = 0; i < gr_visspritecount; i++)
|
||||
{
|
||||
|
@ -4488,11 +4610,32 @@ static void HWR_DrawSprites(void)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value)
|
||||
if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value && !skipshadow)
|
||||
{
|
||||
HWR_DrawDropShadow(spr->mobj, spr->mobj->shadowscale);
|
||||
}
|
||||
|
||||
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
|
||||
{
|
||||
// If this linkdraw sprite is behind a sprite that has a shadow,
|
||||
// then that shadow has to be drawn first, otherwise the shadow ends up on top of
|
||||
// the linkdraw sprite because the linkdraw sprite does not modify the z-buffer.
|
||||
// The !skipshadow check is there in case there are multiple linkdraw sprites connected
|
||||
// to the same tracer, so the tracer's shadow only gets drawn once.
|
||||
if (cv_shadow.value && !skipshadow && spr->dispoffset < 0 && spr->mobj->tracer->shadowscale)
|
||||
{
|
||||
HWR_DrawDropShadow(spr->mobj->tracer, spr->mobj->tracer->shadowscale);
|
||||
skipshadow = true;
|
||||
// The next sprite in this loop should be either another linkdraw sprite or the tracer.
|
||||
// When the tracer is inevitably encountered, skipshadow will cause it's shadow
|
||||
// to get skipped and skipshadow will get set to false by the 'else' clause below.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skipshadow = false;
|
||||
}
|
||||
|
||||
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
{
|
||||
if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
|
||||
|
@ -4516,6 +4659,16 @@ static void HWR_DrawSprites(void)
|
|||
}
|
||||
}
|
||||
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, 0);
|
||||
|
||||
// At the end of sprite drawing, draw shapes of linkdraw sprites to z-buffer, so they
|
||||
// don't get drawn over by transparent surfaces.
|
||||
HWR_LinkDrawHackFinish();
|
||||
// Work around a r_opengl.c bug with PF_Invisible by making this SetBlend call
|
||||
// where PF_Invisible is off and PF_Masked is on.
|
||||
// (Other states probably don't matter. Here I left them same as in LinkDrawHackFinish)
|
||||
// Without this workaround the rest of the draw calls in this frame (including UI, screen texture)
|
||||
// can get drawn using an incorrect glBlendFunc, resulting in a occasional black screen.
|
||||
HWD.pfnSetBlend(PF_Translucent|PF_Occlude|PF_Clip|PF_Masked);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
@ -4577,6 +4730,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
gr_vissprite_t *vis;
|
||||
float tr_x, tr_y;
|
||||
float tz;
|
||||
float tracertz = 0.0f;
|
||||
float x1, x2;
|
||||
float rightsin, rightcos;
|
||||
float this_scale;
|
||||
|
@ -4591,6 +4745,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
|
||||
boolean mirrored = thing->mirrored;
|
||||
boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored);
|
||||
INT32 dispoffset;
|
||||
|
||||
angle_t ang;
|
||||
INT32 heightsec, phs;
|
||||
|
@ -4608,6 +4763,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
if (!thing)
|
||||
return;
|
||||
|
||||
dispoffset = thing->info->dispoffset;
|
||||
|
||||
this_scale = FIXED_TO_FLOAT(thing->scale);
|
||||
|
||||
// transform the origin point
|
||||
|
@ -4820,9 +4977,28 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
|
||||
{
|
||||
// bodge support - not nearly as comprehensive as r_things.c, but better than nothing
|
||||
if (! R_ThingVisible(thing->tracer))
|
||||
return;
|
||||
|
||||
// calculate tz for tracer, same way it is calculated for this sprite
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thing->tracer->x) - gr_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thing->tracer->y) - gr_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tracertz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||
|
||||
// Software does not render the linkdraw sprite if the tracer is behind the view plane,
|
||||
// so do the same check here.
|
||||
// NOTE: This check has the same flaw as the view plane check at the beginning of HWR_ProjectSprite:
|
||||
// the view aiming angle is not taken into account, leading to sprites disappearing too early when they
|
||||
// can still be seen when looking down/up at steep angles.
|
||||
if (tracertz < ZCLIP_PLANE)
|
||||
return;
|
||||
|
||||
// if the sprite is behind the tracer, invert dispoffset, putting the sprite behind the tracer
|
||||
if (tz > tracertz)
|
||||
dispoffset *= -1;
|
||||
}
|
||||
|
||||
// store information in a vissprite
|
||||
|
@ -4830,7 +5006,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
vis->x1 = x1;
|
||||
vis->x2 = x2;
|
||||
vis->tz = tz; // Keep tz for the simple sprite sorting that happens
|
||||
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
|
||||
vis->tracertz = tracertz;
|
||||
vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
|
||||
//vis->patchlumpnum = sprframe->lumppat[rot];
|
||||
#ifdef ROTSPRITE
|
||||
if (rotsprite)
|
||||
|
|
48
src/r_data.c
48
src/r_data.c
|
@ -227,6 +227,8 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex
|
|||
}
|
||||
}
|
||||
|
||||
// Blends two pixels together, using the equation
|
||||
// that matches the specified alpha style.
|
||||
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
|
||||
{
|
||||
RGBA_t output;
|
||||
|
@ -245,7 +247,13 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph
|
|||
// if the background pixel is empty,
|
||||
// match software and don't blend anything
|
||||
if (!background.s.alpha)
|
||||
output.s.alpha = 0;
|
||||
{
|
||||
// ...unless the foreground pixel ISN'T actually translucent.
|
||||
if (alpha == 0xFF)
|
||||
output.rgba = foreground.rgba;
|
||||
else
|
||||
output.rgba = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 beta = (0xFF - alpha);
|
||||
|
@ -302,18 +310,46 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph
|
|||
return 0;
|
||||
}
|
||||
|
||||
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha)
|
||||
INT32 ASTTextureBlendingThreshold[2] = {255/11, (10*255/11)};
|
||||
|
||||
// Blends a pixel for a texture patch.
|
||||
UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
|
||||
{
|
||||
// Alpha style set to translucent?
|
||||
if (style == AST_TRANSLUCENT)
|
||||
{
|
||||
// Is the alpha small enough for translucency?
|
||||
if (alpha <= (10*255/11))
|
||||
if (alpha <= ASTTextureBlendingThreshold[1])
|
||||
{
|
||||
// Is the patch way too translucent? Don't blend then.
|
||||
if (alpha < ASTTextureBlendingThreshold[0])
|
||||
return background.rgba;
|
||||
|
||||
return ASTBlendPixel(background, foreground, style, alpha);
|
||||
}
|
||||
else // just copy the pixel
|
||||
return foreground.rgba;
|
||||
}
|
||||
else
|
||||
return ASTBlendPixel(background, foreground, style, alpha);
|
||||
}
|
||||
|
||||
// Blends two palette indexes for a texture patch, then
|
||||
// finds the nearest palette index from the blended output.
|
||||
UINT8 ASTBlendPaletteIndexes(UINT8 background, UINT8 foreground, int style, UINT8 alpha)
|
||||
{
|
||||
// Alpha style set to translucent?
|
||||
if (style == AST_TRANSLUCENT)
|
||||
{
|
||||
// Is the alpha small enough for translucency?
|
||||
if (alpha <= ASTTextureBlendingThreshold[1])
|
||||
{
|
||||
UINT8 *mytransmap;
|
||||
|
||||
// Is the patch way too translucent? Don't blend then.
|
||||
if (alpha < 255/11)
|
||||
if (alpha < ASTTextureBlendingThreshold[0])
|
||||
return background;
|
||||
|
||||
// The equation's not exact but it works as intended. I'll call it a day for now.
|
||||
mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT);
|
||||
if (background != 0xFF)
|
||||
|
@ -378,7 +414,7 @@ static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpa
|
|||
{
|
||||
for (; dest < cache + position + count; source++, dest++)
|
||||
if (*source != 0xFF)
|
||||
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha);
|
||||
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
|
||||
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
|
||||
|
@ -422,7 +458,7 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache
|
|||
{
|
||||
for (; dest < cache + position + count; --source, dest++)
|
||||
if (*source != 0xFF)
|
||||
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha);
|
||||
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
|
||||
}
|
||||
|
||||
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
|
||||
|
|
|
@ -26,7 +26,10 @@
|
|||
enum patchalphastyle {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY};
|
||||
|
||||
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
|
||||
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha);
|
||||
UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
|
||||
UINT8 ASTBlendPaletteIndexes(UINT8 background, UINT8 foreground, int style, UINT8 alpha);
|
||||
|
||||
extern INT32 ASTTextureBlendingThreshold[2];
|
||||
|
||||
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||
|
||||
|
|
Loading…
Reference in a new issue