Add alpha support for mobjs

This commit is contained in:
MIDIMan 2024-02-24 20:04:48 -05:00
parent 2c0622cd4d
commit de8464cd2f
8 changed files with 60 additions and 2 deletions

View file

@ -2825,7 +2825,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
}
HWR_Lighting(&sSurf, 0, colormap);
sSurf.PolyColor.s.alpha = alpha;
sSurf.PolyColor.s.alpha = FixedMul(thing->alpha, alpha);
if (HWR_UseShader())
{
@ -2999,11 +2999,16 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
// baseWallVerts is used to know the final shape to easily get the vertex
// co-ordinates
memcpy(wallVerts, baseWallVerts, sizeof(baseWallVerts));
UINT32 newalpha = spr->mobj->alpha;
// 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)
{
newalpha = spr->mobj->tracer->alpha;
occlusion = 0;
}
else
occlusion = PF_Occlude;
@ -3039,6 +3044,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
blend = HWR_GetBlendModeFlag(blendmode)|occlusion;
if (!occlusion) use_linkdraw_hack = true;
}
Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha);
if (HWR_UseShader())
{
@ -3488,11 +3495,15 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
FBITFIELD blend = 0;
FBITFIELD occlusion;
boolean use_linkdraw_hack = false;
UINT32 newalpha = spr->mobj->alpha;
// 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;
newalpha = spr->mobj->tracer->alpha;
}
else
occlusion = PF_Occlude;
@ -3528,6 +3539,8 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
blend = HWR_GetBlendModeFlag(blendmode)|occlusion;
if (!occlusion) use_linkdraw_hack = true;
}
Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha);
if (spr->renderflags & RF_SHADOWEFFECTS)
{

View file

@ -69,6 +69,7 @@ enum mobj_e {
mobj_color,
mobj_translation,
mobj_blendmode,
mobj_alpha,
mobj_bnext,
mobj_bprev,
mobj_hnext,
@ -150,6 +151,7 @@ static const char *const mobj_opt[] = {
"color",
"translation",
"blendmode",
"alpha",
"bnext",
"bprev",
"hnext",
@ -354,6 +356,9 @@ static int mobj_get(lua_State *L)
case mobj_blendmode:
lua_pushinteger(L, mo->blendmode);
break;
case mobj_alpha:
lua_pushinteger(L, mo->alpha);
break;
case mobj_bnext:
if (mo->blocknode && mo->blocknode->bnext) {
LUA_PushUserdata(L, mo->blocknode->bnext->mobj, META_MOBJ);
@ -733,6 +738,14 @@ static int mobj_set(lua_State *L)
mo->blendmode = blendmode;
break;
}
case mobj_alpha:
INT32 alpha = (INT32)luaL_checkinteger(L, 3);
if (alpha < 0)
alpha = 0;
else if (alpha > FRACUNIT)
alpha = FRACUNIT;
mo->alpha = alpha;
break;
case mobj_bnext:
return NOSETPOS;
case mobj_bprev:

View file

@ -10503,6 +10503,9 @@ void P_MobjThinker(mobj_t *mobj)
mobj->frame &= ~FF_TRANSMASK;
mobj->frame |= value << FF_TRANSSHIFT;
// TODO: Consider replacing the above with the commented-out line of code below
//mobj->alpha = FixedDiv(mobj->fuse, mobj->info->damage);
}
break;
default:
@ -10838,6 +10841,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
// Sprite rendering
mobj->blendmode = AST_TRANSLUCENT;
mobj->alpha = FRACUNIT;
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
mobj->spritexoffset = mobj->spriteyoffset = 0;
mobj->floorspriteslope = NULL;

View file

@ -313,6 +313,7 @@ typedef struct mobj_s
UINT32 renderflags; // render flags
INT32 blendmode; // blend mode
UINT32 alpha; // alpha
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale;

View file

@ -1742,7 +1742,8 @@ typedef enum
MD2_DISPOFFSET = 1<<23,
MD2_DRAWONLYFORPLAYER = 1<<24,
MD2_DONTDRAWFORVIEWMOBJ = 1<<25,
MD2_TRANSLATION = 1<<26
MD2_TRANSLATION = 1<<26,
MD2_ALPHA = 1<<27
} mobj_diff2_t;
typedef enum
@ -1985,6 +1986,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_DONTDRAWFORVIEWMOBJ;
if (mobj->dispoffset != mobj->info->dispoffset)
diff2 |= MD2_DISPOFFSET;
if (mobj->alpha < FRACUNIT)
diff2 |= MD2_ALPHA;
if (diff2 != 0)
diff |= MD_MORE;
@ -2168,6 +2171,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEINT32(save_p, mobj->dispoffset);
if (diff2 & MD2_TRANSLATION)
WRITEUINT16(save_p, mobj->translation);
if (diff2 & MD2_ALPHA)
WRITEUINT32(save_p, mobj->alpha);
WRITEUINT32(save_p, mobj->mobjnum);
}
@ -3234,6 +3239,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->dispoffset = mobj->info->dispoffset;
if (diff2 & MD2_TRANSLATION)
mobj->translation = READUINT16(save_p);
if (diff2 & MD2_ALPHA)
mobj->alpha = READUINT32(save_p);
if (diff & MD_REDFLAG)
{

View file

@ -2065,6 +2065,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->renderflags = mobj->renderflags;
ghost->blendmode = mobj->blendmode;
ghost->alpha = mobj->alpha;
ghost->spritexscale = mobj->spritexscale;
ghost->spriteyscale = mobj->spriteyscale;

View file

@ -763,6 +763,14 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans
return NULL;
}
transnum_t R_GetTransmapFromAlpha(UINT32 alpha, transnum_t transmap)
{
INT32 value = 10 - transmap;
value = 10 - (FixedCeil(alpha * value)>>FRACBITS);
return value;
}
//
// R_DrawVisSprite
// mfloorclip and mceilingclip should also be set.
@ -1268,6 +1276,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
floordiff = abs((isflipped ? interp.height : 0) + interp.z - groundz);
trans = floordiff / (100*FRACUNIT) + 3;
trans = R_GetTransmapFromAlpha(thing->alpha, trans);
if (trans >= 9) return;
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
@ -1952,6 +1961,11 @@ static void R_ProjectSprite(mobj_t *thing)
}
else
trans = 0;
if ((oldthing->flags2 & MF2_LINKDRAW) && oldthing->tracer)
trans = R_GetTransmapFromAlpha(oldthing->tracer->alpha, trans);
else
trans = R_GetTransmapFromAlpha(oldthing->alpha, trans);
// Check if this sprite needs to be rendered like a shadow
shadowdraw = (!!(thing->renderflags & RF_SHADOWDRAW) && !(papersprite || splat));
@ -3414,6 +3428,10 @@ boolean R_ThingVisible (mobj_t *thing)
(thing->sprite == SPR_NULL) || // Don't draw null-sprites
(thing->flags2 & MF2_DONTDRAW) || // Don't draw MF2_LINKDRAW objects
(thing->drawonlyforplayer && thing->drawonlyforplayer != viewplayer) || // Don't draw other players' personal objects
//(thing->alpha == 0) || // Don't draw objects with an alpha of 0
((rendermode == render_soft && R_GetTransmapFromAlpha(thing->alpha, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT) >= 10) ||
(rendermode == render_opengl && thing->alpha == 0)) || // TODO: Maybe rethink this
//(rendermode == render_soft && R_GetTransmapFromAlpha(thing->alpha, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT) >= 10) ||
(!P_MobjWasRemoved(r_viewmobj) && (
(r_viewmobj == thing) || // Don't draw first-person players or awayviewmobj objects
(r_viewmobj->player && r_viewmobj->player->followmobj == thing) || // Don't draw first-person players' followmobj

View file

@ -90,6 +90,7 @@ boolean R_ThingIsFullDark (mobj_t *thing);
boolean R_ThingIsFlashing (mobj_t *thing);
UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 translation);
transnum_t R_GetTransmapFromAlpha(UINT32 alpha, transnum_t transmap);
void R_ThingOffsetOverlay (mobj_t *thing, fixed_t *outx, fixed_t *outy);