mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-04-02 07:51:14 +00:00
Added particle rendering to VisualThinkers.
To activate, use `SetParticleType(int type)`. To deactivate, use `DisableParticle()`. Types are: - PT_DEFAULT (default value; uses `gl_particles_style`) - PT_SQUARE - PT_ROUND - PT_SMOOTH While in this mode: - `Texture` & `Translation` are ignored - `Scale.X` sets the size - `SColor` sets the color Misc changes: - Removed warning on textureless destruction
This commit is contained in:
parent
74594e4c34
commit
210ee1780e
6 changed files with 110 additions and 14 deletions
|
@ -1108,7 +1108,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SpawnVisualThinker, SpawnVisualThink
|
|||
void DVisualThinker::UpdateSpriteInfo()
|
||||
{
|
||||
PT.style = ERenderStyle(GetRenderStyle());
|
||||
if((PT.flags & SPF_LOCAL_ANIM) && PT.texture != AnimatedTexture)
|
||||
|
||||
if ((PT.flags & SPF_LOCAL_ANIM) && PT.texture != AnimatedTexture)
|
||||
{
|
||||
AnimatedTexture = PT.texture;
|
||||
TexAnim.InitStandaloneAnimation(PT.animData, PT.texture, Level->maptime);
|
||||
|
@ -1127,6 +1128,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, UpdateSpriteInfo, UpdateSpriteInfo
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool DVisualThinker::ValidTexture()
|
||||
{
|
||||
return ((flags & VTF_IsParticle) || PT.texture.isValid());
|
||||
}
|
||||
|
||||
// This runs just like Actor's, make sure to call Super.Tick() in ZScript.
|
||||
void DVisualThinker::Tick()
|
||||
|
@ -1134,10 +1139,8 @@ void DVisualThinker::Tick()
|
|||
if (ObjectFlags & OF_EuthanizeMe)
|
||||
return;
|
||||
|
||||
// There won't be a standard particle for this, it's only for graphics.
|
||||
if (!PT.texture.isValid())
|
||||
if (!ValidTexture())
|
||||
{
|
||||
Printf("No valid texture, destroyed");
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
|
@ -1156,7 +1159,6 @@ void DVisualThinker::Tick()
|
|||
PT.Pos.X = newxy.X;
|
||||
PT.Pos.Y = newxy.Y;
|
||||
PT.Pos.Z += PT.Vel.Z;
|
||||
|
||||
subsector_t * ss = Level->PointInRenderSubsector(PT.Pos);
|
||||
|
||||
// Handle crossing a sector portal.
|
||||
|
@ -1246,7 +1248,33 @@ DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, SetTranslation, SetTranslation)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int IsFrozen(DVisualThinker * self)
|
||||
int DVisualThinker::GetParticleType() const
|
||||
{
|
||||
int flag = (flags & VTF_IsParticle);
|
||||
switch (flag)
|
||||
{
|
||||
case VTF_ParticleSquare:
|
||||
return PT_SQUARE;
|
||||
case VTF_ParticleRound:
|
||||
return PT_ROUND;
|
||||
case VTF_ParticleSmooth:
|
||||
return PT_SMOOTH;
|
||||
}
|
||||
return PT_DEFAULT;
|
||||
}
|
||||
|
||||
static int GetParticleType(DVisualThinker* self)
|
||||
{
|
||||
return self->GetParticleType();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, GetParticleType, GetParticleType)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DVisualThinker);
|
||||
ACTION_RETURN_INT(self->GetParticleType());
|
||||
}
|
||||
|
||||
static int IsFrozen(DVisualThinker* self)
|
||||
{
|
||||
return !!(self->Level->isFrozen() && !(self->PT.flags & SPF_NOTIMEFREEZE));
|
||||
}
|
||||
|
|
|
@ -53,6 +53,14 @@ struct FLevelLocals;
|
|||
|
||||
// [RH] Particle details
|
||||
|
||||
enum EParticleStyle
|
||||
{
|
||||
PT_DEFAULT = -1, // Use gl_particles_style
|
||||
PT_SQUARE = 0,
|
||||
PT_ROUND = 1,
|
||||
PT_SMOOTH = 2,
|
||||
};
|
||||
|
||||
enum EParticleFlags
|
||||
{
|
||||
SPF_FULLBRIGHT = 1 << 0,
|
||||
|
|
|
@ -20,6 +20,12 @@ enum EVisualThinkerFlags
|
|||
VTF_FlipY = 1 << 3, // flip the sprite on the x/y axis.
|
||||
VTF_DontInterpolate = 1 << 4, // disable all interpolation
|
||||
VTF_AddLightLevel = 1 << 5, // adds sector light level to 'LightLevel'
|
||||
|
||||
VTF_ParticleDefault = 0x40,
|
||||
VTF_ParticleSquare = 0x80,
|
||||
VTF_ParticleRound = 0xC0,
|
||||
VTF_ParticleSmooth = 0x100,
|
||||
VTF_IsParticle = 0x1C0, // Renders as a particle instead
|
||||
};
|
||||
|
||||
class DVisualThinker : public DThinker
|
||||
|
@ -53,6 +59,8 @@ public:
|
|||
void SetTranslation(FName trname);
|
||||
int GetRenderStyle() const;
|
||||
bool isFrozen();
|
||||
bool ValidTexture();
|
||||
int GetParticleType() const;
|
||||
int GetLightLevel(sector_t *rendersector) const;
|
||||
FVector3 InterpolatedPosition(double ticFrac) const;
|
||||
float InterpolatedRoll(double ticFrac) const;
|
||||
|
|
|
@ -1409,7 +1409,7 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *s
|
|||
if (!particle || particle->alpha <= 0)
|
||||
return;
|
||||
|
||||
if (spr && spr->PT.texture.isNull())
|
||||
if (spr && !spr->ValidTexture())
|
||||
return;
|
||||
|
||||
lightlevel = hw_ClampLight(spr ? spr->GetLightLevel(sector) : sector->GetSpriteLight());
|
||||
|
@ -1477,17 +1477,29 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *s
|
|||
if (paused || (di->Level->isFrozen() && !(particle->flags & SPF_NOTIMEFREEZE)))
|
||||
timefrac = 0.;
|
||||
|
||||
if (spr)
|
||||
|
||||
if (spr && !(spr->flags & VTF_IsParticle))
|
||||
{
|
||||
AdjustVisualThinker(di, spr, sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool has_texture = particle->texture.isValid();
|
||||
bool custom_animated_texture = (particle->flags & SPF_LOCAL_ANIM) && particle->animData.ok;
|
||||
|
||||
int particle_style = has_texture ? 2 : gl_particles_style; // Treat custom texture the same as smooth particles
|
||||
|
||||
bool has_texture = false;
|
||||
bool custom_animated_texture = false;
|
||||
int particle_style = 0;
|
||||
float size = particle->size;
|
||||
if (!spr)
|
||||
{
|
||||
has_texture = particle->texture.isValid();
|
||||
custom_animated_texture = (particle->flags & SPF_LOCAL_ANIM) && particle->animData.ok;
|
||||
particle_style = has_texture ? 2 : gl_particles_style; // Treat custom texture the same as smooth particles
|
||||
}
|
||||
else
|
||||
{
|
||||
size = float(spr->Scale.X);
|
||||
const int ptype = spr->GetParticleType();
|
||||
particle_style = (ptype != PT_DEFAULT) ? ptype : gl_particles_style;
|
||||
}
|
||||
// [BB] Load the texture for round or smooth particles
|
||||
if (particle_style)
|
||||
{
|
||||
|
@ -1549,7 +1561,7 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *s
|
|||
if (particle_style == 1) factor = 1.3f / 7.f;
|
||||
else if (particle_style == 2) factor = 2.5f / 7.f;
|
||||
else factor = 1 / 7.f;
|
||||
float scalefac=particle->size * factor;
|
||||
float scalefac= size * factor;
|
||||
|
||||
float ps = di->Level->pixelstretch;
|
||||
|
||||
|
|
|
@ -1532,4 +1532,18 @@ enum EVisualThinkerFlags
|
|||
VTF_FlipY = 1 << 3, // flip the sprite on the x/y axis.
|
||||
VTF_DontInterpolate = 1 << 4, // disable all interpolation
|
||||
VTF_AddLightLevel = 1 << 5, // adds sector light level to 'LightLevel'
|
||||
|
||||
VTF_ParticleDefault = 0x40,
|
||||
VTF_ParticleSquare = 0x80,
|
||||
VTF_ParticleRound = 0xC0,
|
||||
VTF_ParticleSmooth = 0x100,
|
||||
VTF_IsParticle = 0x1C0
|
||||
};
|
||||
|
||||
enum EParticleStyle
|
||||
{
|
||||
PT_DEFAULT = -1, // Use gl_particles_style
|
||||
PT_SQUARE = 0,
|
||||
PT_ROUND = 1,
|
||||
PT_SMOOTH = 2,
|
||||
};
|
||||
|
|
|
@ -60,4 +60,30 @@ Class VisualThinker : Thinker native
|
|||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
native int GetParticleType() const;
|
||||
|
||||
void SetParticleType(EParticleStyle type = PT_DEFAULT)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
Default:
|
||||
VisualThinkerFlags = (VisualThinkerFlags & ~VTF_IsParticle) | VTF_ParticleDefault;
|
||||
break;
|
||||
case PT_SQUARE:
|
||||
VisualThinkerFlags = (VisualThinkerFlags & ~VTF_IsParticle) | VTF_ParticleSquare;
|
||||
break;
|
||||
case PT_ROUND:
|
||||
VisualThinkerFlags = (VisualThinkerFlags & ~VTF_IsParticle) | VTF_ParticleRound;
|
||||
break;
|
||||
case PT_SMOOTH:
|
||||
VisualThinkerFlags = (VisualThinkerFlags & ~VTF_IsParticle) | VTF_ParticleSmooth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DisableParticle()
|
||||
{
|
||||
VisualThinkerFlags &= ~VTF_IsParticle;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue