mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- properly handle passing of the light flags.
Since these can be changed on the placed light actor they have to be read from there, so this is now a pointer in FDynamicLight, just like the other properties that can be user-changed. Also did some cleanup on the interface so that external code doesn't need to dereference the lightflags pointer but can use utility functions for all flags.
This commit is contained in:
parent
da735c0e87
commit
8da1b5c1b0
13 changed files with 75 additions and 65 deletions
|
@ -78,6 +78,7 @@
|
|||
#include "vm.h"
|
||||
#include "events.h"
|
||||
#include "i_music.h"
|
||||
#include "a_dynlight.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
@ -1532,6 +1533,7 @@ void G_InitLevelLocals ()
|
|||
level.lightadditivesurfaces = info->lightadditivesurfaces < 0 ? gl_lightadditivesurfaces : !!info->lightadditivesurfaces;
|
||||
level.notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill;
|
||||
|
||||
FLightDefaults::SetAttenuationForLevel();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -133,11 +133,11 @@ void AttachLight(AActor *self)
|
|||
light->pSpotInnerAngle = &self->AngleVar(NAME_SpotInnerAngle);
|
||||
light->pSpotOuterAngle = &self->AngleVar(NAME_SpotOuterAngle);
|
||||
light->pPitch = &self->Angles.Pitch;
|
||||
light->pLightFlags = (LightFlags*)&self->IntVar(NAME_lightflags);
|
||||
light->pArgs = self->args;
|
||||
light->specialf1 = DAngle(double(self->SpawnAngle)).Normalized360().Degrees;
|
||||
light->Sector = self->Sector;
|
||||
light->target = self;
|
||||
light->lightflags.FromInt(self->IntVar(NAME_lightflags));
|
||||
light->mShadowmapIndex = 1024;
|
||||
light->m_active = false;
|
||||
light->visibletoplayer = true;
|
||||
|
@ -665,7 +665,7 @@ void FDynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
}
|
||||
}
|
||||
}
|
||||
shadowmapped = hitonesidedback && !(lightflags & LF_NOSHADOWMAP);
|
||||
shadowmapped = hitonesidedback && !DontShadowmap();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -886,7 +886,7 @@ CCMD(listlights)
|
|||
Printf("%s at (%f, %f, %f), color = 0x%02x%02x%02x, radius = %f %s %s",
|
||||
dl->target->GetClass()->TypeName.GetChars(),
|
||||
dl->X(), dl->Y(), dl->Z(), dl->GetRed(), dl->GetGreen(), dl->GetBlue(),
|
||||
dl->radius, (dl->lightflags & LF_ATTENUATE)? "attenuated" : "", dl->shadowmapped? "shadowmapped" : "");
|
||||
dl->radius, dl->IsAttenuated()? "attenuated" : "", dl->shadowmapped? "shadowmapped" : "");
|
||||
i++;
|
||||
shadowcount += dl->shadowmapped;
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@ enum LightFlag
|
|||
LF_SPOT = 64
|
||||
};
|
||||
|
||||
typedef TFlags<LightFlag> LightFlags;
|
||||
DEFINE_TFLAGS_OPERATORS(LightFlags)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Light definitions
|
||||
|
@ -64,15 +67,16 @@ public:
|
|||
int GetArg(int arg) { return m_Args[arg]; }
|
||||
uint8_t GetAttenuate() const { return m_attenuate; }
|
||||
void SetOffset(float* ft) { m_Pos.X = ft[0]; m_Pos.Z = ft[1]; m_Pos.Y = ft[2]; }
|
||||
void SetSubtractive(bool subtract) { m_subtractive = subtract; }
|
||||
void SetAdditive(bool add) { m_additive = add; }
|
||||
void SetDontLightSelf(bool add) { m_dontlightself = add; }
|
||||
void SetAttenuate(bool on) { m_attenuate = on; }
|
||||
void SetHalo(bool halo) { m_halo = halo; }
|
||||
void SetDontLightActors(bool on) { m_dontlightactors = on; }
|
||||
void SetSpot(bool spot) { m_spot = spot; }
|
||||
void SetSubtractive(bool subtract) { if (subtract) m_lightFlags |= LF_SUBTRACTIVE; else m_lightFlags &= ~LF_SUBTRACTIVE; }
|
||||
void SetAdditive(bool add) { if (add) m_lightFlags |= LF_ADDITIVE; else m_lightFlags &= ~LF_ADDITIVE; }
|
||||
void SetDontLightSelf(bool add) { if (add) m_lightFlags |= LF_DONTLIGHTSELF; else m_lightFlags &= ~LF_DONTLIGHTSELF; }
|
||||
void SetAttenuate(bool on) { m_attenuate = on; if (on) m_lightFlags |= LF_ATTENUATE; else m_lightFlags &= ~LF_ATTENUATE; }
|
||||
void SetDontLightActors(bool on) { if (on) m_lightFlags |= LF_DONTLIGHTACTORS; else m_lightFlags &= ~LF_DONTLIGHTACTORS; }
|
||||
void SetNoShadowmap(bool on) { if (on) m_lightFlags |= LF_NOSHADOWMAP; else m_lightFlags &= ~LF_NOSHADOWMAP; }
|
||||
void SetSpot(bool spot) { if (spot) m_lightFlags |= LF_SPOT; else m_lightFlags &= ~LF_SPOT; }
|
||||
void SetSpotInnerAngle(double angle) { m_spotInnerAngle = angle; }
|
||||
void SetSpotOuterAngle(double angle) { m_spotOuterAngle = angle; }
|
||||
static void SetAttenuationForLevel();
|
||||
|
||||
void OrderIntensities()
|
||||
{
|
||||
|
@ -90,11 +94,7 @@ protected:
|
|||
DVector3 m_Pos = { 0,0,0 };
|
||||
ELightType m_type;
|
||||
int8_t m_attenuate = -1;
|
||||
bool m_subtractive = false;
|
||||
bool m_additive = false;
|
||||
bool m_halo = false;
|
||||
bool m_dontlightself = false;
|
||||
bool m_dontlightactors = false;
|
||||
LightFlags m_lightFlags = 0;
|
||||
bool m_swapped = false;
|
||||
bool m_spot = false;
|
||||
bool m_explicitPitch = false;
|
||||
|
@ -149,11 +149,6 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
|
||||
typedef TFlags<LightFlag> LightFlags;
|
||||
DEFINE_TFLAGS_OPERATORS(LightFlags)
|
||||
|
||||
|
||||
struct FLightNode
|
||||
{
|
||||
FLightNode ** prevTarget;
|
||||
|
@ -180,7 +175,7 @@ struct FDynamicLight
|
|||
|
||||
bool ShouldLightActor(AActor *check)
|
||||
{
|
||||
return visibletoplayer && IsActive() && (!(lightflags & LF_DONTLIGHTSELF) || target != check) && !(lightflags&LF_DONTLIGHTACTORS);
|
||||
return visibletoplayer && IsActive() && (!((*pLightFlags) & LF_DONTLIGHTSELF) || target != check) && !((*pLightFlags) & LF_DONTLIGHTACTORS);
|
||||
}
|
||||
|
||||
void SetOffset(const DVector3 &pos)
|
||||
|
@ -197,9 +192,13 @@ struct FDynamicLight
|
|||
int GetIntensity() const { return pArgs[LIGHT_INTENSITY]; }
|
||||
int GetSecondaryIntensity() const { return pArgs[LIGHT_SECONDARY_INTENSITY]; }
|
||||
|
||||
bool IsSubtractive() const { return !!(lightflags & LF_SUBTRACTIVE); }
|
||||
bool IsAdditive() const { return !!(lightflags & LF_ADDITIVE); }
|
||||
bool IsSpot() const { return !!(lightflags & LF_SPOT); }
|
||||
bool IsSubtractive() const { return !!((*pLightFlags) & LF_SUBTRACTIVE); }
|
||||
bool IsAdditive() const { return !!((*pLightFlags) & LF_ADDITIVE); }
|
||||
bool IsSpot() const { return !!((*pLightFlags) & LF_SPOT); }
|
||||
bool IsAttenuated() const { return !!((*pLightFlags) & LF_ATTENUATE); }
|
||||
bool DontShadowmap() const { return !!((*pLightFlags) & LF_NOSHADOWMAP); }
|
||||
bool DontLightSelf() const { return !!((*pLightFlags) & (LF_DONTLIGHTSELF|LF_DONTLIGHTACTORS)); } // dontlightactors implies dontlightself.
|
||||
bool DontLightActors() const { return !!((*pLightFlags) & LF_DONTLIGHTACTORS); }
|
||||
void Deactivate() { m_active = false; }
|
||||
void Activate();
|
||||
|
||||
|
@ -229,6 +228,7 @@ public:
|
|||
const DAngle *pSpotOuterAngle;
|
||||
const DAngle *pPitch; // This is to handle pitch overrides through GLDEFS, it can either point to the target's pitch or the light definition.
|
||||
const int *pArgs;
|
||||
const LightFlags *pLightFlags;
|
||||
|
||||
double specialf1;
|
||||
FDynamicLight *next, *prev;
|
||||
|
@ -236,7 +236,6 @@ public:
|
|||
TObjPtr<AActor *> target;
|
||||
FLightNode * touching_sides;
|
||||
FLightNode * touching_sector;
|
||||
LightFlags lightflags;
|
||||
float radius; // The maximum size the light can be with its current settings.
|
||||
float m_currentRadius; // The current light size.
|
||||
int m_tickCount;
|
||||
|
|
|
@ -42,8 +42,6 @@ thread_local FDynLightData lightdata;
|
|||
CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
||||
CVAR(Int, gl_attenuate, -1, 0); // This is mainly a debug option.
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -107,13 +105,9 @@ void FDynLightData::AddLightToList(int group, FDynamicLight * light, bool forceA
|
|||
}
|
||||
|
||||
float shadowIndex = light->mShadowmapIndex + 1.0f;
|
||||
bool attenuate;
|
||||
|
||||
// Store attenuate flag in the sign bit of the float.
|
||||
if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE) || forceAttenuate;
|
||||
else attenuate = !!gl_attenuate;
|
||||
|
||||
if (attenuate) shadowIndex = -shadowIndex;
|
||||
if (light->IsAttenuated() || forceAttenuate) shadowIndex = -shadowIndex;
|
||||
|
||||
float lightType = 0.0f;
|
||||
float spotInnerAngle = 0.0f;
|
||||
|
|
|
@ -155,7 +155,7 @@ void PolyModelRenderer::AddLights(AActor *actor)
|
|||
{
|
||||
FDynamicLight *lightsource = addedLights[i];
|
||||
|
||||
bool is_point_light = (lightsource->lightflags & LF_ATTENUATE) != 0;
|
||||
bool is_point_light = lightsource->IsAttenuated();
|
||||
|
||||
uint32_t red = lightsource->GetRed();
|
||||
uint32_t green = lightsource->GetGreen();
|
||||
|
|
|
@ -309,7 +309,7 @@ void RenderPolyPlane::SetDynLights(PolyRenderThread *thread, PolyDrawArgs &args,
|
|||
{
|
||||
if (cur_node->lightsource->IsActive())
|
||||
{
|
||||
bool is_point_light = (cur_node->lightsource->lightflags & LF_ATTENUATE) != 0;
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
|
||||
// To do: cull lights not touching subsector
|
||||
|
||||
|
|
|
@ -445,7 +445,7 @@ void RenderPolyWall::SetDynLights(PolyRenderThread *thread, PolyDrawArgs &args)
|
|||
{
|
||||
if (cur_node->lightsource->IsActive())
|
||||
{
|
||||
bool is_point_light = (cur_node->lightsource->lightflags & LF_ATTENUATE) != 0;
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
|
||||
// To do: cull lights not touching wall
|
||||
|
||||
|
|
|
@ -76,14 +76,9 @@ void FLightDefaults::ApplyProperties(FDynamicLight * light) const
|
|||
light->lighttype = m_type;
|
||||
light->specialf1 = m_Param;
|
||||
light->pArgs = m_Args;
|
||||
light->lightflags &= ~(LF_ADDITIVE | LF_SUBTRACTIVE | LF_DONTLIGHTSELF | LF_SPOT);
|
||||
if (m_subtractive) light->lightflags |= LF_SUBTRACTIVE;
|
||||
if (m_additive) light->lightflags |= LF_ADDITIVE;
|
||||
if (m_dontlightself) light->lightflags |= LF_DONTLIGHTSELF;
|
||||
if (m_dontlightactors) light->lightflags |= LF_DONTLIGHTACTORS;
|
||||
if (m_spot)
|
||||
light->pLightFlags = &m_lightFlags;
|
||||
if (m_lightFlags & LF_SPOT)
|
||||
{
|
||||
light->lightflags |= LF_SPOT;
|
||||
light->pSpotInnerAngle = &m_spotInnerAngle;
|
||||
light->pSpotOuterAngle = &m_spotOuterAngle;
|
||||
if (m_explicitPitch) light->pPitch = &m_pitch;
|
||||
|
@ -103,16 +98,19 @@ void FLightDefaults::ApplyProperties(FDynamicLight * light) const
|
|||
if (light->m_currentRadius <= 0) light->m_currentRadius = 1;
|
||||
light->swapped = m_swapped;
|
||||
}
|
||||
|
||||
switch (m_attenuate)
|
||||
{
|
||||
case 0: light->lightflags &= ~LF_ATTENUATE; break;
|
||||
case 1: light->lightflags |= LF_ATTENUATE; break;
|
||||
default: if (level.flags3 & LEVEL3_ATTENUATE) light->lightflags |= LF_ATTENUATE; else light->lightflags &= ~LF_ATTENUATE; break;
|
||||
}
|
||||
light->SetOffset(m_Pos); // this must be the last thing to do.
|
||||
}
|
||||
|
||||
void FLightDefaults::SetAttenuationForLevel()
|
||||
{
|
||||
for (auto ldef : LightDefaults)
|
||||
{
|
||||
if (ldef->m_attenuate == -1)
|
||||
{
|
||||
if (level.flags3 & LEVEL3_ATTENUATE) ldef->m_lightFlags |= LF_ATTENUATE; else ldef->m_lightFlags &= ~LF_ATTENUATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -138,6 +138,7 @@ static const char *LightTags[]=
|
|||
"attenuate",
|
||||
"dontlightactors",
|
||||
"spot",
|
||||
"noshadowmap",
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@ -160,7 +161,8 @@ enum {
|
|||
LIGHTTAG_DONTLIGHTSELF,
|
||||
LIGHTTAG_ATTENUATE,
|
||||
LIGHTTAG_DONTLIGHTACTORS,
|
||||
LIGHTTAG_SPOT
|
||||
LIGHTTAG_SPOT,
|
||||
LIGHTTAG_NOSHADOWMAP,
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -444,8 +446,11 @@ class GLDefsParser
|
|||
case LIGHTTAG_ADDITIVE:
|
||||
defaults->SetAdditive(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_HALO:
|
||||
defaults->SetHalo(ParseInt(sc) != 0);
|
||||
case LIGHTTAG_HALO: // old development garbage
|
||||
ParseInt(sc);
|
||||
break;
|
||||
case LIGHTTAG_NOSHADOWMAP:
|
||||
defaults->SetNoShadowmap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTSELF:
|
||||
defaults->SetDontLightSelf(ParseInt(sc) != 0);
|
||||
|
@ -537,8 +542,11 @@ class GLDefsParser
|
|||
case LIGHTTAG_SUBTRACTIVE:
|
||||
defaults->SetSubtractive(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_HALO:
|
||||
defaults->SetHalo(ParseInt(sc) != 0);
|
||||
case LIGHTTAG_HALO: // old development garbage
|
||||
ParseInt(sc);
|
||||
break;
|
||||
case LIGHTTAG_NOSHADOWMAP:
|
||||
defaults->SetNoShadowmap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTSELF:
|
||||
defaults->SetDontLightSelf(ParseInt(sc) != 0);
|
||||
|
@ -633,8 +641,11 @@ class GLDefsParser
|
|||
case LIGHTTAG_SUBTRACTIVE:
|
||||
defaults->SetSubtractive(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_HALO:
|
||||
defaults->SetHalo(ParseInt(sc) != 0);
|
||||
case LIGHTTAG_HALO: // old development garbage
|
||||
ParseInt(sc);
|
||||
break;
|
||||
case LIGHTTAG_NOSHADOWMAP:
|
||||
defaults->SetNoShadowmap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTSELF:
|
||||
defaults->SetDontLightSelf(ParseInt(sc) != 0);
|
||||
|
@ -728,8 +739,11 @@ class GLDefsParser
|
|||
case LIGHTTAG_SUBTRACTIVE:
|
||||
defaults->SetSubtractive(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_HALO:
|
||||
defaults->SetHalo(ParseInt(sc) != 0);
|
||||
case LIGHTTAG_HALO: // old development garbage
|
||||
ParseInt(sc);
|
||||
break;
|
||||
case LIGHTTAG_NOSHADOWMAP:
|
||||
defaults->SetNoShadowmap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTSELF:
|
||||
defaults->SetDontLightSelf(ParseInt(sc) != 0);
|
||||
|
@ -820,8 +834,11 @@ class GLDefsParser
|
|||
case LIGHTTAG_SUBTRACTIVE:
|
||||
defaults->SetSubtractive(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_HALO:
|
||||
defaults->SetHalo(ParseInt(sc) != 0);
|
||||
case LIGHTTAG_HALO: // old development garbage
|
||||
ParseInt(sc);
|
||||
break;
|
||||
case LIGHTTAG_NOSHADOWMAP:
|
||||
defaults->SetNoShadowmap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTSELF:
|
||||
defaults->SetDontLightSelf(ParseInt(sc) != 0);
|
||||
|
|
|
@ -385,7 +385,7 @@ namespace swrenderer
|
|||
float lz = (float)lightZ;
|
||||
|
||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||
bool is_point_light = (cur_node->lightsource->lightflags & LF_ATTENUATE) != 0;
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
float lconstant = lx * lx + ly * ly;
|
||||
float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f;
|
||||
|
||||
|
|
|
@ -236,7 +236,7 @@ namespace swrenderer
|
|||
float lz = (float)lightZ - drawerargs.dc_viewpos.Z;
|
||||
|
||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||
bool is_point_light = (cur_node->lightsource->lightflags & LF_ATTENUATE) != 0;
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
float lconstant = ly * ly + lz * lz;
|
||||
float nlconstant = is_point_light ? lz * drawerargs.dc_normal.Z : 0.0f;
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ namespace swrenderer
|
|||
{
|
||||
FDynamicLight *lightsource = addedLights[i];
|
||||
|
||||
bool is_point_light = (lightsource->lightflags & LF_ATTENUATE) != 0;
|
||||
bool is_point_light = lightsource->IsAttenuated();
|
||||
|
||||
uint32_t red = lightsource->GetRed();
|
||||
uint32_t green = lightsource->GetGreen();
|
||||
|
|
|
@ -52,8 +52,8 @@ public:
|
|||
typedef T EnumType;
|
||||
typedef TT IntType;
|
||||
|
||||
TFlags(){}
|
||||
TFlags (const Self& other) : Value (other.GetValue()) {}
|
||||
TFlags() = default;
|
||||
TFlags(const Self& other) = default;
|
||||
TFlags (T value) : Value (static_cast<TT> (value)) {}
|
||||
|
||||
// This allows initializing the flagset with 0, as 0 implicitly converts into a null pointer.
|
||||
|
|
Loading…
Reference in a new issue