From 35e56d3f42285a18debbf898ad22ad61f3691682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 6 Jan 2024 20:45:40 -0300 Subject: [PATCH] Minor optimizations to VisualThinker * remove duplicated fields * make native functions use direct calls * remove unnecessary pointer from particle_t * create HWSprite directly in Construct --- src/common/engine/renderstyle.h | 2 +- src/playsim/p_effect.cpp | 162 +++++++++--------- src/playsim/p_effect.h | 22 +-- src/rendering/hwrenderer/scene/hw_bsp.cpp | 8 +- .../hwrenderer/scene/hw_drawstructs.h | 2 +- src/rendering/hwrenderer/scene/hw_sprites.cpp | 9 +- wadsrc/static/zscript/visualthinker.zs | 28 +-- 7 files changed, 117 insertions(+), 116 deletions(-) diff --git a/src/common/engine/renderstyle.h b/src/common/engine/renderstyle.h index 272f23ba5..19d788e2c 100644 --- a/src/common/engine/renderstyle.h +++ b/src/common/engine/renderstyle.h @@ -55,7 +55,7 @@ enum ETexMode }; // Legacy render styles -enum ERenderStyle +enum ERenderStyle : int { STYLE_None, // Do not draw STYLE_Normal, // Normal; just copy the image to the screen diff --git a/src/playsim/p_effect.cpp b/src/playsim/p_effect.cpp index 55f3f1092..b861e7bff 100644 --- a/src/playsim/p_effect.cpp +++ b/src/playsim/p_effect.cpp @@ -51,6 +51,8 @@ #include "g_game.h" #include "serializer_doom.h" +#include "hwrenderer/scene/hw_drawstructs.h" + #ifdef _MSC_VER #pragma warning(disable: 6011) // dereference null pointer in thinker iterator #endif @@ -222,10 +224,9 @@ void P_FindParticleSubsectors (FLevelLocals *Level) DVisualThinker* sp; while (sp = it.Next()) { - if (sp->sub == nullptr) - sp->sub = Level->PointInRenderSubsector(sp->Pos); + if (!sp->PT.subsector) sp->PT.subsector = Level->PointInRenderSubsector(sp->PT.Pos); - sp->sub->sprites.Push(sp); + sp->PT.subsector->sprites.Push(sp); } // End VisualThinker hitching. Now onto the particles. if (Level->ParticlesInSubsec.Size() < Level->subsectors.Size()) @@ -994,20 +995,20 @@ void P_DisconnectEffect (AActor *actor) void DVisualThinker::Construct() { PT = {}; - PT.sprite = this; - Pos = Vel = { 0,0,0 }; + PT.Pos = PT.Vel = { 0,0,0 }; Offset = { 0,0 }; Scale = { 1,1 }; - Roll = 0.0; - Alpha = 1.0; + PT.Roll = 0.0; + PT.alpha = 1.0; LightLevel = -1; - Texture = FTextureID(); - Style = STYLE_Normal; - Flags = 0; + PT.texture = FTextureID(); + PT.style = STYLE_Normal; + PT.flags = 0; Translation = NO_TRANSLATION; - sub = nullptr; + PT.subsector = nullptr; cursector = nullptr; - scolor = 0xffffff; + PT.color = 0xffffff; + spr = new HWSprite(); } DVisualThinker::DVisualThinker() @@ -1015,16 +1016,14 @@ DVisualThinker::DVisualThinker() Construct(); } -void DVisualThinker::CallPostBeginPlay() -{ - PT.texture = Texture; - Super::CallPostBeginPlay(); -} - void DVisualThinker::OnDestroy() { PT.alpha = 0.0; // stops all rendering. - if (spr) delete spr; + if(spr) + { + delete spr; + spr = nullptr; + } Super::OnDestroy(); } @@ -1063,16 +1062,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SpawnVisualThinker, SpawnVisualThink void DVisualThinker::UpdateSpriteInfo() { - PT.color = scolor; - PT.Pos = Pos; - PT.Vel = Vel; - PT.Roll = Roll; - PT.alpha = Alpha; - PT.texture = Texture; PT.style = ERenderStyle(GetRenderStyle()); - PT.flags = Flags; - PT.subsector = sub; - PT.sprite = this; } // This runs just like Actor's, make sure to call Super.Tick() in ZScript. @@ -1082,8 +1072,8 @@ void DVisualThinker::Tick() return; // There won't be a standard particle for this, it's only for graphics. - if (!Texture.isValid()) - { + if (!PT.texture.isValid()) + { Printf("No valid texture, destroyed"); Destroy(); return; @@ -1091,38 +1081,38 @@ void DVisualThinker::Tick() if (isFrozen()) { // needed here because it won't retroactively update like actors do. - sub = Level->PointInRenderSubsector(Pos); - cursector = sub->sector; + PT.subsector = Level->PointInRenderSubsector(PT.Pos); + cursector = PT.subsector->sector; UpdateSpriteInfo(); return; } - Prev = Pos; - PrevRoll = Roll; + Prev = PT.Pos; + PrevRoll = PT.Roll; // Handle crossing a line portal - DVector2 newxy = Level->GetPortalOffsetPosition(Pos.X, Pos.Y, Vel.X, Vel.Y); - Pos.X = newxy.X; - Pos.Y = newxy.Y; - Pos.Z += Vel.Z; + DVector2 newxy = Level->GetPortalOffsetPosition(PT.Pos.X, PT.Pos.Y, PT.Vel.X, PT.Vel.Y); + PT.Pos.X = newxy.X; + PT.Pos.Y = newxy.Y; + PT.Pos.Z += PT.Vel.Z; - sub = Level->PointInRenderSubsector(Pos); - cursector = sub->sector; + PT.subsector = Level->PointInRenderSubsector(PT.Pos); + cursector = PT.subsector->sector; // Handle crossing a sector portal. if (!cursector->PortalBlocksMovement(sector_t::ceiling)) { - if (Pos.Z > cursector->GetPortalPlaneZ(sector_t::ceiling)) + if (PT.Pos.Z > cursector->GetPortalPlaneZ(sector_t::ceiling)) { - Pos += cursector->GetPortalDisplacement(sector_t::ceiling); - sub = nullptr; - cursector = nullptr; + PT.Pos += cursector->GetPortalDisplacement(sector_t::ceiling); + PT.subsector = Level->PointInRenderSubsector(PT.Pos); + cursector = PT.subsector->sector; } } else if (!cursector->PortalBlocksMovement(sector_t::floor)) { - if (Pos.Z < cursector->GetPortalPlaneZ(sector_t::floor)) + if (PT.Pos.Z < cursector->GetPortalPlaneZ(sector_t::floor)) { - Pos += cursector->GetPortalDisplacement(sector_t::floor); - sub = nullptr; - cursector = nullptr; + PT.Pos += cursector->GetPortalDisplacement(sector_t::floor); + PT.subsector = Level->PointInRenderSubsector(PT.Pos); + cursector = PT.subsector->sector; } } UpdateSpriteInfo(); @@ -1145,18 +1135,18 @@ int DVisualThinker::GetLightLevel(sector_t* rendersector) const FVector3 DVisualThinker::InterpolatedPosition(double ticFrac) const { - if (bDontInterpolate) return FVector3(Pos); + if (bDontInterpolate) return FVector3(PT.Pos); - DVector3 proc = Prev + (ticFrac * (Pos - Prev)); + DVector3 proc = Prev + (ticFrac * (PT.Pos - Prev)); return FVector3(proc); } float DVisualThinker::InterpolatedRoll(double ticFrac) const { - if (bDontInterpolate) return Roll; + if (bDontInterpolate) return PT.Roll; - return float(PrevRoll + (Roll - PrevRoll) * ticFrac); + return float(PrevRoll + (PT.Roll - PrevRoll) * ticFrac); } @@ -1179,7 +1169,13 @@ void DVisualThinker::SetTranslation(FName trname) // silently ignore if the name does not exist, this would create some insane message spam otherwise. } -DEFINE_ACTION_FUNCTION(DVisualThinker, SetTranslation) +void SetTranslation(DVisualThinker * self, int i_trans) +{ + FName trans {ENamedName(i_trans)}; + self->SetTranslation(trans); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, SetTranslation, SetTranslation) { PARAM_SELF_PROLOGUE(DVisualThinker); PARAM_NAME(trans); @@ -1187,33 +1183,42 @@ DEFINE_ACTION_FUNCTION(DVisualThinker, SetTranslation) return 0; } -bool DVisualThinker::isFrozen() +static int IsFrozen(DVisualThinker * self) { - return (Level->isFrozen() && !(Flags & SPF_NOTIMEFREEZE)); + return (self->Level->isFrozen() && !(self->PT.flags & SPF_NOTIMEFREEZE)); } -DEFINE_ACTION_FUNCTION(DVisualThinker, IsFrozen) +bool DVisualThinker::isFrozen() +{ + return IsFrozen(this); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, IsFrozen, IsFrozen) { PARAM_SELF_PROLOGUE(DVisualThinker); ACTION_RETURN_BOOL(self->isFrozen()); } -DEFINE_ACTION_FUNCTION(DVisualThinker, SetRenderStyle) +static void SetRenderStyle(DVisualThinker *self, int mode) +{ + if(mode >= 0 && mode < STYLE_Count) + { + self->PT.style = ERenderStyle(mode); + } +} + +DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, SetRenderStyle, SetRenderStyle) { PARAM_SELF_PROLOGUE(DVisualThinker); PARAM_INT(mode); - self->Style = ERenderStyle(mode); + self->PT.style = ERenderStyle(mode); return 0; } int DVisualThinker::GetRenderStyle() { - for (unsigned i = 0; i < STYLE_Count; i++) - { - if (Style == LegacyRenderStyles[i]) return i; - } - return -1; + return PT.style; } void DVisualThinker::Serialize(FSerializer& arc) @@ -1221,42 +1226,43 @@ void DVisualThinker::Serialize(FSerializer& arc) Super::Serialize(arc); arc - ("pos", Pos) - ("vel", Vel) + ("pos", PT.Pos) + ("vel", PT.Vel) ("prev", Prev) ("scale", Scale) - ("roll", Roll) + ("roll", PT.Roll) ("prevroll", PrevRoll) ("offset", Offset) - ("alpha", Alpha) - ("texture", Texture) - ("style", Style) + ("alpha", PT.alpha) + ("texture", PT.texture) + ("style", *reinterpret_cast(&PT.style)) ("translation", Translation) ("cursector", cursector) - ("scolor", scolor) + ("scolor", PT.color) ("flipx", bXFlip) ("flipy", bYFlip) ("dontinterpolate", bDontInterpolate) ("addlightlevel", bAddLightLevel) ("lightlevel", LightLevel) - ("flags", Flags); + ("flags", PT.flags); } IMPLEMENT_CLASS(DVisualThinker, false, false); -DEFINE_FIELD(DVisualThinker, Pos); -DEFINE_FIELD(DVisualThinker, Vel); +DEFINE_FIELD_NAMED(DVisualThinker, PT.color, SColor); +DEFINE_FIELD_NAMED(DVisualThinker, PT.Pos, Pos); +DEFINE_FIELD_NAMED(DVisualThinker, PT.Vel, Vel); +DEFINE_FIELD_NAMED(DVisualThinker, PT.Roll, Roll); +DEFINE_FIELD_NAMED(DVisualThinker, PT.alpha, Alpha); +DEFINE_FIELD_NAMED(DVisualThinker, PT.texture, Texture); +DEFINE_FIELD_NAMED(DVisualThinker, PT.flags, Flags); + DEFINE_FIELD(DVisualThinker, Prev); DEFINE_FIELD(DVisualThinker, Scale); DEFINE_FIELD(DVisualThinker, Offset); -DEFINE_FIELD(DVisualThinker, Roll); DEFINE_FIELD(DVisualThinker, PrevRoll); -DEFINE_FIELD(DVisualThinker, Alpha); -DEFINE_FIELD(DVisualThinker, Texture); DEFINE_FIELD(DVisualThinker, Translation); -DEFINE_FIELD(DVisualThinker, Flags); DEFINE_FIELD(DVisualThinker, LightLevel); -DEFINE_FIELD(DVisualThinker, scolor); DEFINE_FIELD(DVisualThinker, cursector); DEFINE_FIELD(DVisualThinker, bXFlip); DEFINE_FIELD(DVisualThinker, bYFlip); diff --git a/src/playsim/p_effect.h b/src/playsim/p_effect.h index c2101b568..796d6ba40 100644 --- a/src/playsim/p_effect.h +++ b/src/playsim/p_effect.h @@ -81,7 +81,6 @@ struct particle_t uint16_t tnext, snext, tprev; bool bright; uint16_t flags; - DVisualThinker *sprite; }; const uint16_t NO_PARTICLE = 0xffff; @@ -152,34 +151,25 @@ class DVisualThinker : public DThinker { DECLARE_CLASS(DVisualThinker, DThinker); public: - DVector3 Pos, Vel, Prev; - DVector2 Scale, Offset; - double Roll, PrevRoll, Alpha; + DVector3 Prev; + DVector2 Scale, + Offset; + double PrevRoll; int16_t LightLevel; - - int scolor; - - FRenderStyle Style; - FTextureID Texture; FTranslationID Translation; - - uint16_t Flags; sector_t *cursector; - bool bXFlip, bYFlip, // flip the sprite on the x/y axis. + bool bXFlip, + bYFlip, // flip the sprite on the x/y axis. bDontInterpolate, // disable all interpolation bAddLightLevel; // adds sector light level to 'LightLevel' // internal only variables - subsector_t *sub; particle_t PT; HWSprite *spr; //in an effort to cache the result. - - DVisualThinker(); void Construct(); - void CallPostBeginPlay() override; void OnDestroy() override; static DVisualThinker* NewVisualThinker(FLevelLocals* Level, PClass* type); diff --git a/src/rendering/hwrenderer/scene/hw_bsp.cpp b/src/rendering/hwrenderer/scene/hw_bsp.cpp index 3003341bc..12439669c 100644 --- a/src/rendering/hwrenderer/scene/hw_bsp.cpp +++ b/src/rendering/hwrenderer/scene/hw_bsp.cpp @@ -607,10 +607,10 @@ void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front) int clipres = mClipPortal->ClipPoint(sp->PT.Pos.XY()); if (clipres == PClip_InFront) continue; } - if (!sp->spr) - sp->spr = new HWSprite(); - sp->spr->ProcessParticle(this, &sp->PT, front); + assert(sp->spr); + + sp->spr->ProcessParticle(this, &sp->PT, front, sp); } for (int i = Level->ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Level->Particles[i].snext) { @@ -621,7 +621,7 @@ void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front) } HWSprite sprite; - sprite.ProcessParticle(this, &Level->Particles[i], front); + sprite.ProcessParticle(this, &Level->Particles[i], front, nullptr); } SetupSprite.Unclock(); } diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 6664b943b..04179d250 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -402,7 +402,7 @@ public: void CreateVertices(HWDrawInfo *di); void PutSprite(HWDrawInfo *di, bool translucent); void Process(HWDrawInfo *di, AActor* thing,sector_t * sector, area_t in_area, int thruportal = false, bool isSpriteShadow = false); - void ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t *sector);//, int shade, int fakeside) + void ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *sector, class DVisualThinker *spr);//, int shade, int fakeside) void AdjustVisualThinker(HWDrawInfo *di, DVisualThinker *spr, sector_t *sector); void DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent); diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index be8289ef6..6052747d9 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -1263,13 +1263,12 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t // //========================================================================== -void HWSprite::ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t *sector)//, int shade, int fakeside) +void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *sector, DVisualThinker *spr)//, int shade, int fakeside) { if (!particle || particle->alpha <= 0) return; - DVisualThinker *spr = particle->sprite; - if (spr && spr->Texture.isNull()) + if (spr && spr->PT.texture.isNull()) return; lightlevel = hw_ClampLight(spr ? spr->GetLightLevel(sector) : sector->GetSpriteLight()); @@ -1427,7 +1426,7 @@ void HWSprite::ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t * void HWSprite::AdjustVisualThinker(HWDrawInfo* di, DVisualThinker* spr, sector_t* sector) { translation = spr->Translation; - texture = TexMan.GetGameTexture(spr->Texture, true); + texture = TexMan.GetGameTexture(spr->PT.texture, true); const auto& vp = di->Viewpoint; double timefrac = vp.TicFrac; @@ -1442,7 +1441,7 @@ void HWSprite::AdjustVisualThinker(HWDrawInfo* di, DVisualThinker* spr, sector_t offx = (float)spr->Offset.X; offy = (float)spr->Offset.Y; - if (spr->Flags & SPF_ROLL) + if (spr->PT.flags & SPF_ROLL) Angles.Roll = TAngle::fromDeg(spr->InterpolatedRoll(timefrac)); auto& spi = texture->GetSpritePositioning(0); diff --git a/wadsrc/static/zscript/visualthinker.zs b/wadsrc/static/zscript/visualthinker.zs index 877bd7abe..201dce9e9 100644 --- a/wadsrc/static/zscript/visualthinker.zs +++ b/wadsrc/static/zscript/visualthinker.zs @@ -1,18 +1,24 @@ Class VisualThinker : Thinker native { - native Vector3 Pos, Vel, Prev; - native Vector2 Scale, Offset; - native double Roll, Alpha, PrevRoll; - native TextureID Texture; + native Vector3 Pos, + Vel, + Prev; + native Vector2 Scale, + Offset; + native double Roll, + PrevRoll; + native float Alpha; + native TextureID Texture; native TranslationID Translation; - native uint16 Flags; - native int16 LightLevel; - native bool bXFlip, bYFlip, - bDontInterpolate, - bAddLightLevel; - native Color scolor; + native uint16 Flags; + native int16 LightLevel; + native bool bXFlip, + bYFlip, + bDontInterpolate, + bAddLightLevel; + native Color scolor; - native Sector CurSector; // can be null! + native Sector CurSector; // can be null! native void SetTranslation(Name trans); native void SetRenderStyle(int mode); // see ERenderStyle