mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-19 08:01:50 +00:00
Minor optimizations to VisualThinker
* remove duplicated fields * make native functions use direct calls * remove unnecessary pointer from particle_t * create HWSprite directly in Construct
This commit is contained in:
parent
5895b88799
commit
35e56d3f42
7 changed files with 117 additions and 116 deletions
|
@ -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
|
||||
|
|
|
@ -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,7 +1072,7 @@ 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();
|
||||
|
@ -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<int*>(&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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<double>::fromDeg(spr->InterpolatedRoll(timefrac));
|
||||
|
||||
auto& spi = texture->GetSpritePositioning(0);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue