Skip to content

Commit 210ee17

Browse files
MajorCookeRicardoLuis0
authored andcommitted
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
1 parent 74594e4 commit 210ee17

File tree

6 files changed

+110
-14
lines changed

6 files changed

+110
-14
lines changed

src/playsim/p_effect.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SpawnVisualThinker, SpawnVisualThink
11081108
void DVisualThinker::UpdateSpriteInfo()
11091109
{
11101110
PT.style = ERenderStyle(GetRenderStyle());
1111-
if((PT.flags & SPF_LOCAL_ANIM) && PT.texture != AnimatedTexture)
1111+
1112+
if ((PT.flags & SPF_LOCAL_ANIM) && PT.texture != AnimatedTexture)
11121113
{
11131114
AnimatedTexture = PT.texture;
11141115
TexAnim.InitStandaloneAnimation(PT.animData, PT.texture, Level->maptime);
@@ -1127,17 +1128,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, UpdateSpriteInfo, UpdateSpriteInfo
11271128
return 0;
11281129
}
11291130

1131+
bool DVisualThinker::ValidTexture()
1132+
{
1133+
return ((flags & VTF_IsParticle) || PT.texture.isValid());
1134+
}
11301135

11311136
// This runs just like Actor's, make sure to call Super.Tick() in ZScript.
11321137
void DVisualThinker::Tick()
11331138
{
11341139
if (ObjectFlags & OF_EuthanizeMe)
11351140
return;
11361141

1137-
// There won't be a standard particle for this, it's only for graphics.
1138-
if (!PT.texture.isValid())
1142+
if (!ValidTexture())
11391143
{
1140-
Printf("No valid texture, destroyed");
11411144
Destroy();
11421145
return;
11431146
}
@@ -1156,7 +1159,6 @@ void DVisualThinker::Tick()
11561159
PT.Pos.X = newxy.X;
11571160
PT.Pos.Y = newxy.Y;
11581161
PT.Pos.Z += PT.Vel.Z;
1159-
11601162
subsector_t * ss = Level->PointInRenderSubsector(PT.Pos);
11611163

11621164
// Handle crossing a sector portal.
@@ -1246,7 +1248,33 @@ DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, SetTranslation, SetTranslation)
12461248
return 0;
12471249
}
12481250

1249-
static int IsFrozen(DVisualThinker * self)
1251+
int DVisualThinker::GetParticleType() const
1252+
{
1253+
int flag = (flags & VTF_IsParticle);
1254+
switch (flag)
1255+
{
1256+
case VTF_ParticleSquare:
1257+
return PT_SQUARE;
1258+
case VTF_ParticleRound:
1259+
return PT_ROUND;
1260+
case VTF_ParticleSmooth:
1261+
return PT_SMOOTH;
1262+
}
1263+
return PT_DEFAULT;
1264+
}
1265+
1266+
static int GetParticleType(DVisualThinker* self)
1267+
{
1268+
return self->GetParticleType();
1269+
}
1270+
1271+
DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, GetParticleType, GetParticleType)
1272+
{
1273+
PARAM_SELF_PROLOGUE(DVisualThinker);
1274+
ACTION_RETURN_INT(self->GetParticleType());
1275+
}
1276+
1277+
static int IsFrozen(DVisualThinker* self)
12501278
{
12511279
return !!(self->Level->isFrozen() && !(self->PT.flags & SPF_NOTIMEFREEZE));
12521280
}

src/playsim/p_effect.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ struct FLevelLocals;
5353

5454
// [RH] Particle details
5555

56+
enum EParticleStyle
57+
{
58+
PT_DEFAULT = -1, // Use gl_particles_style
59+
PT_SQUARE = 0,
60+
PT_ROUND = 1,
61+
PT_SMOOTH = 2,
62+
};
63+
5664
enum EParticleFlags
5765
{
5866
SPF_FULLBRIGHT = 1 << 0,

src/playsim/p_visualthinker.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ enum EVisualThinkerFlags
2020
VTF_FlipY = 1 << 3, // flip the sprite on the x/y axis.
2121
VTF_DontInterpolate = 1 << 4, // disable all interpolation
2222
VTF_AddLightLevel = 1 << 5, // adds sector light level to 'LightLevel'
23+
24+
VTF_ParticleDefault = 0x40,
25+
VTF_ParticleSquare = 0x80,
26+
VTF_ParticleRound = 0xC0,
27+
VTF_ParticleSmooth = 0x100,
28+
VTF_IsParticle = 0x1C0, // Renders as a particle instead
2329
};
2430

2531
class DVisualThinker : public DThinker
@@ -53,6 +59,8 @@ class DVisualThinker : public DThinker
5359
void SetTranslation(FName trname);
5460
int GetRenderStyle() const;
5561
bool isFrozen();
62+
bool ValidTexture();
63+
int GetParticleType() const;
5664
int GetLightLevel(sector_t *rendersector) const;
5765
FVector3 InterpolatedPosition(double ticFrac) const;
5866
float InterpolatedRoll(double ticFrac) const;

src/rendering/hwrenderer/scene/hw_sprites.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,7 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *s
14091409
if (!particle || particle->alpha <= 0)
14101410
return;
14111411

1412-
if (spr && spr->PT.texture.isNull())
1412+
if (spr && !spr->ValidTexture())
14131413
return;
14141414

14151415
lightlevel = hw_ClampLight(spr ? spr->GetLightLevel(sector) : sector->GetSpriteLight());
@@ -1477,17 +1477,29 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *s
14771477
if (paused || (di->Level->isFrozen() && !(particle->flags & SPF_NOTIMEFREEZE)))
14781478
timefrac = 0.;
14791479

1480-
if (spr)
1480+
1481+
if (spr && !(spr->flags & VTF_IsParticle))
14811482
{
14821483
AdjustVisualThinker(di, spr, sector);
14831484
}
14841485
else
14851486
{
1486-
bool has_texture = particle->texture.isValid();
1487-
bool custom_animated_texture = (particle->flags & SPF_LOCAL_ANIM) && particle->animData.ok;
1488-
1489-
int particle_style = has_texture ? 2 : gl_particles_style; // Treat custom texture the same as smooth particles
1490-
1487+
bool has_texture = false;
1488+
bool custom_animated_texture = false;
1489+
int particle_style = 0;
1490+
float size = particle->size;
1491+
if (!spr)
1492+
{
1493+
has_texture = particle->texture.isValid();
1494+
custom_animated_texture = (particle->flags & SPF_LOCAL_ANIM) && particle->animData.ok;
1495+
particle_style = has_texture ? 2 : gl_particles_style; // Treat custom texture the same as smooth particles
1496+
}
1497+
else
1498+
{
1499+
size = float(spr->Scale.X);
1500+
const int ptype = spr->GetParticleType();
1501+
particle_style = (ptype != PT_DEFAULT) ? ptype : gl_particles_style;
1502+
}
14911503
// [BB] Load the texture for round or smooth particles
14921504
if (particle_style)
14931505
{
@@ -1549,7 +1561,7 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *s
15491561
if (particle_style == 1) factor = 1.3f / 7.f;
15501562
else if (particle_style == 2) factor = 2.5f / 7.f;
15511563
else factor = 1 / 7.f;
1552-
float scalefac=particle->size * factor;
1564+
float scalefac= size * factor;
15531565

15541566
float ps = di->Level->pixelstretch;
15551567

wadsrc/static/zscript/constants.zs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,4 +1532,18 @@ enum EVisualThinkerFlags
15321532
VTF_FlipY = 1 << 3, // flip the sprite on the x/y axis.
15331533
VTF_DontInterpolate = 1 << 4, // disable all interpolation
15341534
VTF_AddLightLevel = 1 << 5, // adds sector light level to 'LightLevel'
1535+
1536+
VTF_ParticleDefault = 0x40,
1537+
VTF_ParticleSquare = 0x80,
1538+
VTF_ParticleRound = 0xC0,
1539+
VTF_ParticleSmooth = 0x100,
1540+
VTF_IsParticle = 0x1C0
1541+
};
1542+
1543+
enum EParticleStyle
1544+
{
1545+
PT_DEFAULT = -1, // Use gl_particles_style
1546+
PT_SQUARE = 0,
1547+
PT_ROUND = 1,
1548+
PT_SMOOTH = 2,
15351549
};

wadsrc/static/zscript/visualthinker.zs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,30 @@ Class VisualThinker : Thinker native
6060
}
6161
return p;
6262
}
63+
64+
native int GetParticleType() const;
65+
66+
void SetParticleType(EParticleStyle type = PT_DEFAULT)
67+
{
68+
switch(type)
69+
{
70+
Default:
71+
VisualThinkerFlags = (VisualThinkerFlags & ~VTF_IsParticle) | VTF_ParticleDefault;
72+
break;
73+
case PT_SQUARE:
74+
VisualThinkerFlags = (VisualThinkerFlags & ~VTF_IsParticle) | VTF_ParticleSquare;
75+
break;
76+
case PT_ROUND:
77+
VisualThinkerFlags = (VisualThinkerFlags & ~VTF_IsParticle) | VTF_ParticleRound;
78+
break;
79+
case PT_SMOOTH:
80+
VisualThinkerFlags = (VisualThinkerFlags & ~VTF_IsParticle) | VTF_ParticleSmooth;
81+
break;
82+
}
83+
}
84+
85+
void DisableParticle()
86+
{
87+
VisualThinkerFlags &= ~VTF_IsParticle;
88+
}
6389
}

0 commit comments

Comments
 (0)