- did a complete workover of the weapon sprite translucency code that got inherited from QZDoom.

This was very poorly done without ever addressing the issues a composite render style can bring, it merely dealt with the known legacy render styles.
The same, identical code was also present in two different places.
The oversight that AlterWeaponSprite overrode even forced styles was also fixed.

OpenGL is not implemented yet but with the problems eliminated should be doable now.
This commit is contained in:
Christoph Oelckers 2017-04-15 16:41:00 +02:00
commit 1ee9256842
7 changed files with 96 additions and 229 deletions

View file

@ -122,7 +122,6 @@ DEFINE_FIELD(DPSprite, oldy)
DEFINE_FIELD(DPSprite, firstTic)
DEFINE_FIELD(DPSprite, Tics)
DEFINE_FIELD(DPSprite, alpha)
DEFINE_FIELD(DPSprite, RenderStyle)
DEFINE_FIELD_BIT(DPSprite, Flags, bAddWeapon, PSPF_ADDWEAPON)
DEFINE_FIELD_BIT(DPSprite, Flags, bAddBob, PSPF_ADDBOB)
DEFINE_FIELD_BIT(DPSprite, Flags, bPowDouble, PSPF_POWDOUBLE)
@ -147,7 +146,7 @@ DPSprite::DPSprite(player_t *owner, AActor *caller, int id)
processPending(true)
{
alpha = 1;
RenderStyle = STYLE_Normal;
Renderstyle = STYLE_Normal;
DPSprite *prev = nullptr;
DPSprite *next = Owner->psprites;
@ -298,6 +297,79 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, GetPSprite) // the underscore is needed to g
}
std::pair<FRenderStyle, float> DPSprite::GetRenderStyle(FRenderStyle ownerstyle, double owneralpha)
{
FRenderStyle returnstyle, mystyle;
double returnalpha;
ownerstyle.CheckFuzz();
mystyle = Renderstyle;
mystyle.CheckFuzz();
if (Flags & PSPF_RENDERSTYLE)
{
ownerstyle.CheckFuzz();
if (Flags & PSPF_FORCESTYLE)
{
returnstyle = mystyle;
}
else if (ownerstyle.BlendOp != STYLEOP_Add)
{
// all styles that do more than simple blending need to be fully preserved.
returnstyle = ownerstyle;
}
else
{
returnstyle = mystyle;
if (ownerstyle.DestAlpha == STYLEALPHA_One)
{
// If the owner is additive and the overlay translucent, force additive result.
returnstyle.DestAlpha = STYLEALPHA_One;
}
if (ownerstyle.Flags & (STYLEF_ColorIsFixed|STYLEF_RedIsAlpha))
{
// If the owner's style is a stencil type, this must be preserved.
returnstyle.Flags = ownerstyle.Flags;
}
}
}
else
{
returnstyle = ownerstyle;
}
if ((Flags & PSPF_FORCEALPHA) && returnstyle.BlendOp != STYLEOP_Fuzz && returnstyle.BlendOp != STYLEOP_Shadow)
{
// ALWAYS take priority if asked for, except fuzz. Fuzz does absolutely nothing
// no matter what way it's changed.
returnalpha = alpha;
returnstyle.Flags &= ~(STYLEF_Alpha1 | STYLEF_TransSoulsAlpha);
}
else if (Flags & PSPF_ALPHA)
{
// Set the alpha based on if using the overlay's own or not. Also adjust
// and override the alpha if not forced.
if (returnstyle.BlendOp != STYLEOP_Add)
{
returnalpha = owneralpha;
}
else
{
returnalpha = owneralpha * alpha;
}
}
// Should normal renderstyle come out on top at the end and we desire alpha,
// switch it to translucent. Normal never applies any sort of alpha.
if (returnstyle.BlendOp == STYLEOP_Add && returnstyle.SrcAlpha == STYLEALPHA_One && returnstyle.DestAlpha == STYLEALPHA_Zero && returnalpha < 1.)
{
returnstyle = LegacyRenderStyles[STYLE_Translucent];
returnalpha = owneralpha * alpha;
}
return{ returnstyle, clamp<float>(float(alpha), 0.f, 1.f) };
}
//---------------------------------------------------------------------------
//
// PROC P_NewPspriteTick
@ -1237,7 +1309,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayRenderStyle)
if (pspr == nullptr || style >= STYLE_Count || style < 0)
return 0;
pspr->RenderStyle = style;
pspr->Renderstyle = ERenderStyle(style);
}
return 0;
}
@ -1472,7 +1544,7 @@ void DPSprite::Serialize(FSerializer &arc)
("oldx", oldx)
("oldy", oldy)
("alpha", alpha)
("renderstyle", RenderStyle);
("renderstyle_", Renderstyle); // The underscore is intentional to avoid problems with old savegames which had this as an ERenderStyle (which is not future proof.)
}
//------------------------------------------------------------------------