Added scale and alpha interpolation

Similar to angles, needs to be enabled via flags to prevent breaking existing sprites.
This commit is contained in:
Boondorl 2025-07-22 10:35:20 -04:00 committed by GitHub
commit 7d1f2df404
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 21 additions and 4 deletions

View file

@ -510,6 +510,8 @@ enum ActorRenderFlag2
RF2_STRETCHPIXELS = 0x0200, // don't apply SQUAREPIXELS for ROLLSPRITES
RF2_LIGHTMULTALPHA = 0x0400, // attached lights use alpha as intensity multiplier
RF2_ANGLEDROLL = 0x0800, // Sprite roll amount depends on (actor.Angle - actor.AngledRollOffset)
RF2_INTERPOLATESCALE = 0x1000,
RF2_INTERPOLATEALPHA = 0x2000,
};
// This translucency value produces the closest match to Heretic's TINTTAB.
@ -1396,6 +1398,8 @@ public:
// [RH] Used to interpolate the view to get >35 FPS
DVector3 Prev;
DRotator PrevAngles;
DVector2 PrevScale;
double PrevAlpha;
DAngle PrevFOV;
TArray<FDynamicLight *> AttachedLights;
TDeletingArray<FLightDefaults *> UserLights;
@ -1544,7 +1548,7 @@ public:
DVector3 InterpolatedPosition(double ticFrac) const
{
if (renderflags & RF_DONTINTERPOLATE) return Pos();
else return Prev + (ticFrac * (Pos() - Prev));
else return Prev * (1.0 - ticFrac) + Pos() * ticFrac;
}
DRotator InterpolatedAngles(double ticFrac) const
{
@ -1554,6 +1558,14 @@ public:
result.Roll = PrevAngles.Roll + deltaangle(PrevAngles.Roll, Angles.Roll) * ticFrac;
return result;
}
DVector2 InterpolatedScale(double ticFrac) const
{
return (renderflags2 & RF2_INTERPOLATESCALE) ? PrevScale * (1.0 - ticFrac) + Scale * ticFrac : Scale;
}
double InterpolatedAlpha(double ticFrac) const
{
return (renderflags2 & RF2_INTERPOLATEALPHA) ? PrevAlpha * (1.0 - ticFrac) + Alpha * ticFrac : Alpha;
}
float GetSpriteOffset(bool y) const
{
if (y) return (float)(renderflags2 & RF2_FLIPSPRITEOFFSETY ? SpriteOffset.Y : -SpriteOffset.Y);

View file

@ -30,6 +30,8 @@ inline void AActor::ClearInterpolation()
{
Prev = Pos();
PrevAngles = Angles;
PrevScale = Scale;
PrevAlpha = Alpha;
if (Sector) PrevPortalGroup = Sector->PortalGroup;
else PrevPortalGroup = 0;
}

View file

@ -808,7 +808,8 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
const auto &vp = di->Viewpoint;
AActor *camera = vp.camera;
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha))
const double alpha = thing->InterpolatedAlpha(vp.TicFrac);
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(alpha))
{
if (!(thing->flags & MF_STEALTH) || !di->isStealthVision() || thing == camera)
return;
@ -821,7 +822,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
return;
int spritenum = thing->sprite;
DVector2 sprscale(thing->Scale.X, thing->Scale.Y);
DVector2 sprscale = thing->InterpolatedScale(vp.TicFrac);
if (thing->player != nullptr)
{
P_CheckPlayerSprite(thing, spritenum, sprscale);
@ -1281,7 +1282,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
translation = thing->Translation;
OverrideShader = -1;
trans = thing->Alpha;
trans = alpha;
hw_styleflags = STYLEHW_Normal;
if (RenderStyle.BlendOp >= STYLEOP_Fuzz && RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub)

View file

@ -392,6 +392,8 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(RF2, STRETCHPIXELS, AActor, renderflags2),
DEFINE_FLAG(RF2, LIGHTMULTALPHA, AActor, renderflags2),
DEFINE_FLAG(RF2, ANGLEDROLL, AActor, renderflags2),
DEFINE_FLAG(RF2, INTERPOLATESCALE, AActor, renderflags2),
DEFINE_FLAG(RF2, INTERPOLATEALPHA, AActor, renderflags2),
// Bounce flags
DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags),