- moved dynamic lights out of the GL code into the common game code.

Since the true color software renderer also handles them there is no point keeping them on the GL side.
This also optimized how they are stored, because we no longer need to be aware of a base engine which doesn't have them.
This commit is contained in:
Christoph Oelckers 2017-03-12 16:56:00 +01:00
parent 6788b19e89
commit ef3421eee5
30 changed files with 330 additions and 429 deletions

View file

@ -175,7 +175,7 @@ if( MSVC )
set( ALL_C_FLAGS "/GF /Gy /GR-" ) set( ALL_C_FLAGS "/GF /Gy /GR-" )
# Use SSE 2 as minimum always as the true color drawers needs it for __vectorcall # Use SSE 2 as minimum always as the true color drawers needs it for __vectorcall
set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2") #set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2") # This is already the default
# if( CMAKE_SIZEOF_VOID_P MATCHES "4") # if( CMAKE_SIZEOF_VOID_P MATCHES "4")
# # SSE2 option (to allow x87 in 32 bit and disallow extended feature sets which have not yet been checked for precision) # # SSE2 option (to allow x87 in 32 bit and disallow extended feature sets which have not yet been checked for precision)

View file

@ -902,9 +902,7 @@ set( FASTMATH_SOURCES
sound/sndfile_decoder.cpp sound/sndfile_decoder.cpp
sound/mididevices/music_timiditypp_mididevice.cpp sound/mididevices/music_timiditypp_mididevice.cpp
gl/data/gl_matrix.cpp gl/data/gl_matrix.cpp
gl/dynlights/a_dynlight.cpp
gl/utility/gl_clock.cpp gl/utility/gl_clock.cpp
gl/utility/gl_cycler.cpp
gl/utility/gl_geometric.cpp gl/utility/gl_geometric.cpp
gl/renderer/gl_2ddrawer.cpp gl/renderer/gl_2ddrawer.cpp
gl/hqnx/init.cpp gl/hqnx/init.cpp
@ -957,6 +955,7 @@ set (PCH_SOURCES
compatibility.cpp compatibility.cpp
configfile.cpp configfile.cpp
ct_chat.cpp ct_chat.cpp
cycler.cpp
d_dehacked.cpp d_dehacked.cpp
d_iwad.cpp d_iwad.cpp
d_main.cpp d_main.cpp
@ -1085,6 +1084,8 @@ set (PCH_SOURCES
g_inventory/a_weapons.cpp g_inventory/a_weapons.cpp
g_shared/a_action.cpp g_shared/a_action.cpp
g_shared/a_decals.cpp g_shared/a_decals.cpp
g_shared/a_dynlight.cpp
g_shared/a_dynlightdata.cpp
g_shared/a_flashfader.cpp g_shared/a_flashfader.cpp
g_shared/a_lightning.cpp g_shared/a_lightning.cpp
g_shared/a_morph.cpp g_shared/a_morph.cpp
@ -1101,7 +1102,6 @@ set (PCH_SOURCES
gl/data/gl_portaldata.cpp gl/data/gl_portaldata.cpp
gl/data/gl_setup.cpp gl/data/gl_setup.cpp
gl/data/gl_vertexbuffer.cpp gl/data/gl_vertexbuffer.cpp
gl/dynlights/gl_dynlight.cpp
gl/dynlights/gl_glow.cpp gl/dynlights/gl_glow.cpp
gl/dynlights/gl_lightbuffer.cpp gl/dynlights/gl_lightbuffer.cpp
gl/dynlights/gl_aabbtree.cpp gl/dynlights/gl_aabbtree.cpp

View file

@ -47,6 +47,7 @@ struct subsector_t;
struct FBlockNode; struct FBlockNode;
struct FPortalGroupArray; struct FPortalGroupArray;
struct visstyle_t; struct visstyle_t;
class FLightDefaults;
// //
// NOTES: AActor // NOTES: AActor
// //
@ -974,6 +975,10 @@ public:
void ClearRenderSectorList(); void ClearRenderSectorList();
void ClearRenderLineList(); void ClearRenderLineList();
void AttachLight(unsigned int count, const FLightDefaults *lightdef);
void SetDynamicLights();
// info for drawing // info for drawing
// NOTE: The first member variable *must* be snext. // NOTE: The first member variable *must* be snext.
AActor *snext, **sprev; // links in sector (if needed) AActor *snext, **sprev; // links in sector (if needed)
@ -1191,6 +1196,7 @@ public:
DVector3 Prev; DVector3 Prev;
DRotator PrevAngles; DRotator PrevAngles;
int PrevPortalGroup; int PrevPortalGroup;
TArray<TObjPtr<AActor*> > AttachedLights;
// ThingIDs // ThingIDs
static void ClearTIDHashes (); static void ClearTIDHashes ();
@ -1432,12 +1438,10 @@ public:
int ApplyDamageFactor(FName damagetype, int damage) const; int ApplyDamageFactor(FName damagetype, int damage) const;
int GetModifiedDamage(FName damagetype, int damage, bool passive); int GetModifiedDamage(FName damagetype, int damage, bool passive);
static void DeleteAllAttachedLights();
static void RecreateAllAttachedLights();
// begin of GZDoom specific additions
TArray<TObjPtr<AActor*> > dynamiclights;
void * lightassociations;
bool hasmodel; bool hasmodel;
// end of GZDoom specific additions
size_t PropagateMark(); size_t PropagateMark();
}; };
@ -1469,6 +1473,7 @@ public:
{ {
base = nullptr; base = nullptr;
} }
private: private:
AActor *base; AActor *base;
int id; int id;

View file

@ -35,7 +35,7 @@
#include <math.h> #include <math.h>
#include "serializer.h" #include "serializer.h"
#include "gl/utility/gl_cycler.h" #include "cycler.h"
//========================================================================== //==========================================================================
// //
@ -68,11 +68,11 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FCycler &c, FCycler *d
FCycler::FCycler() FCycler::FCycler()
{ {
m_cycle = 0.f; m_cycle = 0.;
m_cycleType = CYCLE_Linear; m_cycleType = CYCLE_Linear;
m_shouldCycle = false; m_shouldCycle = false;
m_start = m_current = 0.f; m_start = m_current = 0.;
m_end = 0.f; m_end = 0.;
m_increment = true; m_increment = true;
} }
@ -83,19 +83,19 @@ FCycler::FCycler()
// //
//========================================================================== //==========================================================================
void FCycler::SetParams(float start, float end, float cycle, bool update) void FCycler::SetParams(double start, double end, double cycle, bool update)
{ {
if (!update || cycle != m_cycle) if (!update || cycle != m_cycle)
{ {
m_cycle = cycle; m_cycle = cycle;
m_time = 0.f; m_time = 0.;
m_increment = true; m_increment = true;
m_current = start; m_current = start;
} }
else else
{ {
// When updating and keeping the same cycle, scale the current light size to the new dimensions. // When updating and keeping the same cycle, scale the current light size to the new dimensions.
float fact = (m_current - m_start) / (m_end - m_start); double fact = (m_current - m_start) / (m_end - m_start);
m_current = start + fact *(end - start); m_current = start + fact *(end - start);
} }
m_start = start; m_start = start;
@ -109,10 +109,10 @@ void FCycler::SetParams(float start, float end, float cycle, bool update)
// //
//========================================================================== //==========================================================================
void FCycler::Update(float diff) void FCycler::Update(double diff)
{ {
float mult, angle; double mult, angle;
float step = m_end - m_start; double step = m_end - m_start;
if (!m_shouldCycle) if (!m_shouldCycle)
{ {
@ -140,15 +140,15 @@ void FCycler::Update(float diff)
} }
break; break;
case CYCLE_Sin: case CYCLE_Sin:
angle = float(M_PI * 2.f * mult); angle = double(M_PI * 2. * mult);
mult = sinf(angle); mult = g_sin(angle);
mult = (mult + 1.f) / 2.f; mult = (mult + 1.) / 2.;
m_current = m_start + (step * mult); m_current = m_start + (step * mult);
break; break;
case CYCLE_Cos: case CYCLE_Cos:
angle = float(M_PI * 2.f * mult); angle = double(M_PI * 2. * mult);
mult = cosf(angle); mult = g_cos(angle);
mult = (mult + 1.f) / 2.f; mult = (mult + 1.) / 2.;
m_current = m_start + (step * mult); m_current = m_start + (step * mult);
break; break;
case CYCLE_SawTooth: case CYCLE_SawTooth:
@ -168,7 +168,7 @@ void FCycler::Update(float diff)
if (m_time == m_cycle) if (m_time == m_cycle)
{ {
m_time = 0.f; m_time = 0.;
m_increment = !m_increment; m_increment = !m_increment;
} }
} }

View file

@ -21,17 +21,17 @@ class FCycler
public: public:
FCycler(); FCycler();
void Update(float diff); void Update(double diff);
void SetParams(float start, float end, float cycle, bool update = false); void SetParams(double start, double end, double cycle, bool update = false);
void ShouldCycle(bool sc) { m_shouldCycle = sc; } void ShouldCycle(bool sc) { m_shouldCycle = sc; }
void SetCycleType(CycleType ct) { m_cycleType = ct; } void SetCycleType(CycleType ct) { m_cycleType = ct; }
float GetVal() { return m_current; } double GetVal() { return m_current; }
inline operator float () const { return m_current; } inline operator double () const { return m_current; }
protected: protected:
float m_start, m_end, m_current; double m_start, m_end, m_current;
float m_time, m_cycle; double m_time, m_cycle;
bool m_increment, m_shouldCycle; bool m_increment, m_shouldCycle;
CycleType m_cycleType; CycleType m_cycleType;

View file

@ -138,6 +138,7 @@ void G_BuildTiccmd (ticcmd_t* cmd);
void D_DoAdvanceDemo (); void D_DoAdvanceDemo ();
void D_AddWildFile (TArray<FString> &wadfiles, const char *pattern); void D_AddWildFile (TArray<FString> &wadfiles, const char *pattern);
void D_LoadWadSettings (); void D_LoadWadSettings ();
void ParseGLDefs();
// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
@ -2500,6 +2501,8 @@ void D_DoomMain (void)
StartScreen->Progress (); StartScreen->Progress ();
ParseGLDefs();
if (!batchrun) Printf ("R_Init: Init %s refresh subsystem.\n", gameinfo.ConfigName.GetChars()); if (!batchrun) Printf ("R_Init: Init %s refresh subsystem.\n", gameinfo.ConfigName.GetChars());
StartScreen->LoadingStatus ("Loading graphics", 0x3f); StartScreen->LoadingStatus ("Loading graphics", 0x3f);
R_Init (); R_Init ();

View file

@ -1486,7 +1486,7 @@ bool FLevelLocals::IsJumpingAllowed() const
return false; return false;
if (dmflags & DF_YES_JUMP) if (dmflags & DF_YES_JUMP)
return true; return true;
return !(level.flags & LEVEL_JUMP_NO); return !(flags & LEVEL_JUMP_NO);
} }
//========================================================================== //==========================================================================
@ -1500,7 +1500,7 @@ bool FLevelLocals::IsCrouchingAllowed() const
return false; return false;
if (dmflags & DF_YES_CROUCH) if (dmflags & DF_YES_CROUCH)
return true; return true;
return !(level.flags & LEVEL_CROUCH_NO); return !(flags & LEVEL_CROUCH_NO);
} }
//========================================================================== //==========================================================================
@ -1514,7 +1514,7 @@ bool FLevelLocals::IsFreelookAllowed() const
return false; return false;
if (dmflags & DF_YES_FREELOOK) if (dmflags & DF_YES_FREELOOK)
return true; return true;
return !(level.flags & LEVEL_FREELOOK_NO); return !(flags & LEVEL_FREELOOK_NO);
} }
//========================================================================== //==========================================================================

View file

@ -238,6 +238,7 @@ enum ELevelFlags : unsigned int
// More flags! // More flags!
LEVEL3_FORCEFAKECONTRAST = 0x00000001, // forces fake contrast even with fog enabled LEVEL3_FORCEFAKECONTRAST = 0x00000001, // forces fake contrast even with fog enabled
LEVEL3_REMOVEITEMS = 0x00000002, // kills all INVBAR items on map change. LEVEL3_REMOVEITEMS = 0x00000002, // kills all INVBAR items on map change.
LEVEL3_ATTENUATE = 0x00000004, // attenuate lights?
}; };

View file

@ -1216,7 +1216,6 @@ DEFINE_MAP_OPTION(hazardflash, true)
info->hazardflash = V_GetColor(NULL, parse.sc); info->hazardflash = V_GetColor(NULL, parse.sc);
} }
//========================================================================== //==========================================================================
// //
// All flag based map options // All flag based map options

View file

@ -83,6 +83,13 @@
#include "gl/system//gl_interface.h" #include "gl/system//gl_interface.h"
CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
if (self) AActor::RecreateAllAttachedLights();
else AActor::DeleteAllAttachedLights();
}
CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
//========================================================================== //==========================================================================
// //
@ -744,11 +751,11 @@ void ADynamicLight::UnlinkLight ()
if (owned && target != NULL) if (owned && target != NULL)
{ {
// Delete reference in owning actor // Delete reference in owning actor
for(int c=target->dynamiclights.Size()-1; c>=0; c--) for(int c=target->AttachedLights.Size()-1; c>=0; c--)
{ {
if (target->dynamiclights[c] == this) if (target->AttachedLights[c] == this)
{ {
target->dynamiclights.Delete(c); target->AttachedLights.Delete(c);
break; break;
} }
} }
@ -765,23 +772,6 @@ void ADynamicLight::OnDestroy()
} }
//==========================================================================
//
// Needed for garbage collection
//
//==========================================================================
size_t AActor::PropagateMark()
{
for (unsigned i=0; i<dynamiclights.Size(); i++)
{
GC::Mark(dynamiclights[i]);
}
return Super::PropagateMark();
}
CCMD(listlights) CCMD(listlights)
{ {
int walls, sectors, subsecs; int walls, sectors, subsecs;

123
src/g_shared/a_dynlight.h Normal file
View file

@ -0,0 +1,123 @@
#pragma once
#include "c_cvars.h"
#include "actor.h"
#include "cycler.h"
EXTERN_CVAR(Bool, gl_lights)
EXTERN_CVAR(Bool, gl_attachedlights)
class ADynamicLight;
class FSerializer;
class FLightDefaults;
enum
{
LIGHT_RED = 0,
LIGHT_GREEN = 1,
LIGHT_BLUE = 2,
LIGHT_INTENSITY = 3,
LIGHT_SECONDARY_INTENSITY = 4,
LIGHT_SCALE = 3,
};
// This is as good as something new - and it can be set directly in the ActorInfo!
#define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE
#define MF4_ADDITIVE MF4_MISSILEMORE
#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS
#define MF4_ATTENUATE MF4_INCOMBAT
enum ELightType
{
PointLight,
PulseLight,
FlickerLight,
RandomFlickerLight,
SectorLight,
SpotLight,
ColorPulseLight,
ColorFlickerLight,
RandomColorFlickerLight
};
struct FLightNode
{
FLightNode ** prevTarget;
FLightNode * nextTarget;
FLightNode ** prevLight;
FLightNode * nextLight;
ADynamicLight * lightsource;
union
{
side_t * targLine;
subsector_t * targSubsector;
void * targ;
};
};
//
// Base class
//
// [CO] I merged everything together in this one class so that I don't have
// to create and re-create an excessive amount of objects
//
class ADynamicLight : public AActor
{
friend class FLightDefaults;
DECLARE_CLASS (ADynamicLight, AActor)
public:
virtual void Tick();
void Serialize(FSerializer &arc);
void PostSerialize();
uint8_t GetRed() const { return args[LIGHT_RED]; }
uint8_t GetGreen() const { return args[LIGHT_GREEN]; }
uint8_t GetBlue() const { return args[LIGHT_BLUE]; }
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
void LinkLight();
void UnlinkLight();
size_t PointerSubstitution (DObject *old, DObject *notOld);
void BeginPlay();
void SetOrigin (double x, double y, double z, bool moving = false);
void PostBeginPlay();
void OnDestroy() override;
void Activate(AActor *activator);
void Deactivate(AActor *activator);
void SetOffset(const DVector3 &pos);
void UpdateLocation();
bool IsOwned() const { return owned; }
bool IsActive() const { return !(flags2&MF2_DORMANT); }
bool IsSubtractive() { return !!(flags4&MF4_SUBTRACTIVE); }
bool IsAdditive() { return !!(flags4&MF4_ADDITIVE); }
FState *targetState;
FLightNode * touching_sides;
FLightNode * touching_subsectors;
FLightNode * touching_sector;
private:
double DistToSeg(const DVector3 &pos, seg_t *seg);
void CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius);
protected:
DVector3 m_off;
float m_currentRadius;
unsigned int m_lastUpdate;
FCycler m_cycler;
subsector_t * subsector;
public:
int m_tickCount;
uint8_t lightflags;
uint8_t lighttype;
bool owned;
bool halo;
uint8_t color2[3];
bool visibletoplayer;
bool swapped;
int bufferindex;
};

View file

@ -1,5 +1,5 @@
/* /*
** gl_dynlight.cpp ** _gl_dynlight.cpp
** Light definitions for actors. ** Light definitions for actors.
** **
**--------------------------------------------------------------------------- **---------------------------------------------------------------------------
@ -50,15 +50,9 @@
#include "d_dehacked.h" #include "d_dehacked.h"
#include "v_text.h" #include "v_text.h"
#include "g_levellocals.h" #include "g_levellocals.h"
#include "a_dynlight.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/textures/gl_skyboxtexture.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_convert.h"
#include "gl/data/gl_data.h"
#include "gl/system//gl_interface.h"
int ScriptDepth; int ScriptDepth;
void gl_InitGlow(FScanner &sc); void gl_InitGlow(FScanner &sc);
void gl_ParseBrightmap(FScanner &sc, int); void gl_ParseBrightmap(FScanner &sc, int);
@ -205,7 +199,7 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
else light->m_cycler.SetParams(float(light->args[LIGHT_INTENSITY]), float(light->args[LIGHT_SECONDARY_INTENSITY]), pulseTime, oldtype == PulseLight); else light->m_cycler.SetParams(float(light->args[LIGHT_INTENSITY]), float(light->args[LIGHT_SECONDARY_INTENSITY]), pulseTime, oldtype == PulseLight);
light->m_cycler.ShouldCycle(true); light->m_cycler.ShouldCycle(true);
light->m_cycler.SetCycleType(CYCLE_Sin); light->m_cycler.SetCycleType(CYCLE_Sin);
light->m_currentRadius = light->m_cycler.GetVal(); light->m_currentRadius = (float)light->m_cycler.GetVal();
if (light->m_currentRadius <= 0) light->m_currentRadius = 1; if (light->m_currentRadius <= 0) light->m_currentRadius = 1;
light->swapped = m_swapped; light->swapped = m_swapped;
} }
@ -214,7 +208,7 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
{ {
case 0: light->flags4 &= ~MF4_ATTENUATE; break; case 0: light->flags4 &= ~MF4_ATTENUATE; break;
case 1: light->flags4 |= MF4_ATTENUATE; break; case 1: light->flags4 |= MF4_ATTENUATE; break;
default: if (glset.attenuate) light->flags4 |= MF4_ATTENUATE; else light->flags4 &= ~MF4_ATTENUATE; break; default: if (level.flags3 & LEVEL3_ATTENUATE) light->flags4 |= MF4_ATTENUATE; else light->flags4 &= ~MF4_ATTENUATE; break;
} }
} }
@ -277,7 +271,7 @@ extern int ScriptDepth;
// //
//========================================================================== //==========================================================================
inline float gl_ParseFloat(FScanner &sc) inline float ParseFloat(FScanner &sc)
{ {
sc.GetFloat(); sc.GetFloat();
@ -285,7 +279,7 @@ inline float gl_ParseFloat(FScanner &sc)
} }
inline int gl_ParseInt(FScanner &sc) inline int ParseInt(FScanner &sc)
{ {
sc.GetNumber(); sc.GetNumber();
@ -293,7 +287,7 @@ inline int gl_ParseInt(FScanner &sc)
} }
inline char *gl_ParseString(FScanner &sc) inline char *ParseString(FScanner &sc)
{ {
sc.GetString(); sc.GetString();
@ -301,16 +295,16 @@ inline char *gl_ParseString(FScanner &sc)
} }
void gl_ParseTriple(FScanner &sc, float floatVal[3]) static void ParseTriple(FScanner &sc, float floatVal[3])
{ {
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
floatVal[i] = gl_ParseFloat(sc); floatVal[i] = ParseFloat(sc);
} }
} }
void gl_AddLightDefaults(FLightDefaults *defaults) static void AddLightDefaults(FLightDefaults *defaults)
{ {
FLightDefaults *temp; FLightDefaults *temp;
unsigned int i; unsigned int i;
@ -327,7 +321,8 @@ void gl_AddLightDefaults(FLightDefaults *defaults)
} }
} }
if (gl.legacyMode && (defaults->GetAttenuate())) // If the current renderer cannot handle attenuated lights we need to reduce the radius here to account for the far more bright lights this would create.
if (/*!Renderer->CanAttenuate() &&*/ (defaults->GetAttenuate()))
{ {
defaults->SetArg(LIGHT_INTENSITY, defaults->GetArg(LIGHT_INTENSITY) * 2 / 3); defaults->SetArg(LIGHT_INTENSITY, defaults->GetArg(LIGHT_INTENSITY) * 2 / 3);
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_SECONDARY_INTENSITY) * 2 / 3); defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_SECONDARY_INTENSITY) * 2 / 3);
@ -343,7 +338,7 @@ void gl_AddLightDefaults(FLightDefaults *defaults)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gl_ParsePointLight(FScanner &sc) static void ParsePointLight(FScanner &sc)
{ {
int type; int type;
float floatTriple[3]; float floatTriple[3];
@ -373,39 +368,39 @@ void gl_ParsePointLight(FScanner &sc)
ScriptDepth--; ScriptDepth--;
break; break;
case LIGHTTAG_COLOR: case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255)); defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255)); defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255)); defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break; break;
case LIGHTTAG_OFFSET: case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple); defaults->SetOffset(floatTriple);
break; break;
case LIGHTTAG_SIZE: case LIGHTTAG_SIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024); intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_INTENSITY, intVal); defaults->SetArg(LIGHT_INTENSITY, intVal);
break; break;
case LIGHTTAG_SUBTRACTIVE: case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0); defaults->SetSubtractive(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_ADDITIVE: case LIGHTTAG_ADDITIVE:
defaults->SetAdditive(gl_ParseInt(sc) != 0); defaults->SetAdditive(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_HALO: case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0); defaults->SetHalo(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_DONTLIGHTSELF: case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0); defaults->SetDontLightSelf(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_ATTENUATE: case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0); defaults->SetAttenuate(ParseInt(sc) != 0);
break; break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
} }
} }
gl_AddLightDefaults(defaults); AddLightDefaults(defaults);
} }
else else
{ {
@ -420,7 +415,7 @@ void gl_ParsePointLight(FScanner &sc)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gl_ParsePulseLight(FScanner &sc) static void ParsePulseLight(FScanner &sc)
{ {
int type; int type;
float floatVal, floatTriple[3]; float floatVal, floatTriple[3];
@ -450,38 +445,38 @@ void gl_ParsePulseLight(FScanner &sc)
ScriptDepth--; ScriptDepth--;
break; break;
case LIGHTTAG_COLOR: case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255)); defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255)); defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255)); defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break; break;
case LIGHTTAG_OFFSET: case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple); defaults->SetOffset(floatTriple);
break; break;
case LIGHTTAG_SIZE: case LIGHTTAG_SIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024); intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_INTENSITY, intVal); defaults->SetArg(LIGHT_INTENSITY, intVal);
break; break;
case LIGHTTAG_SECSIZE: case LIGHTTAG_SECSIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024); intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal);
break; break;
case LIGHTTAG_INTERVAL: case LIGHTTAG_INTERVAL:
floatVal = gl_ParseFloat(sc); floatVal = ParseFloat(sc);
defaults->SetParameter(floatVal * TICRATE); defaults->SetParameter(floatVal * TICRATE);
break; break;
case LIGHTTAG_SUBTRACTIVE: case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0); defaults->SetSubtractive(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_HALO: case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0); defaults->SetHalo(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_DONTLIGHTSELF: case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0); defaults->SetDontLightSelf(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_ATTENUATE: case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0); defaults->SetAttenuate(ParseInt(sc) != 0);
break; break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
@ -489,7 +484,7 @@ void gl_ParsePulseLight(FScanner &sc)
} }
defaults->OrderIntensities(); defaults->OrderIntensities();
gl_AddLightDefaults(defaults); AddLightDefaults(defaults);
} }
else else
{ {
@ -504,7 +499,7 @@ void gl_ParsePulseLight(FScanner &sc)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gl_ParseFlickerLight(FScanner &sc) void ParseFlickerLight(FScanner &sc)
{ {
int type; int type;
float floatVal, floatTriple[3]; float floatVal, floatTriple[3];
@ -534,45 +529,45 @@ void gl_ParseFlickerLight(FScanner &sc)
ScriptDepth--; ScriptDepth--;
break; break;
case LIGHTTAG_COLOR: case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255)); defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255)); defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255)); defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break; break;
case LIGHTTAG_OFFSET: case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple); defaults->SetOffset(floatTriple);
break; break;
case LIGHTTAG_SIZE: case LIGHTTAG_SIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024); intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_INTENSITY, intVal); defaults->SetArg(LIGHT_INTENSITY, intVal);
break; break;
case LIGHTTAG_SECSIZE: case LIGHTTAG_SECSIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024); intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal);
break; break;
case LIGHTTAG_CHANCE: case LIGHTTAG_CHANCE:
floatVal = gl_ParseFloat(sc); floatVal = ParseFloat(sc);
defaults->SetParameter(floatVal*360.); defaults->SetParameter(floatVal*360.);
break; break;
case LIGHTTAG_SUBTRACTIVE: case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0); defaults->SetSubtractive(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_HALO: case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0); defaults->SetHalo(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_DONTLIGHTSELF: case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0); defaults->SetDontLightSelf(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_ATTENUATE: case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0); defaults->SetAttenuate(ParseInt(sc) != 0);
break; break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
} }
} }
defaults->OrderIntensities(); defaults->OrderIntensities();
gl_AddLightDefaults(defaults); AddLightDefaults(defaults);
} }
else else
{ {
@ -587,7 +582,7 @@ void gl_ParseFlickerLight(FScanner &sc)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gl_ParseFlickerLight2(FScanner &sc) void ParseFlickerLight2(FScanner &sc)
{ {
int type; int type;
float floatVal, floatTriple[3]; float floatVal, floatTriple[3];
@ -617,38 +612,38 @@ void gl_ParseFlickerLight2(FScanner &sc)
ScriptDepth--; ScriptDepth--;
break; break;
case LIGHTTAG_COLOR: case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255)); defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255)); defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255)); defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break; break;
case LIGHTTAG_OFFSET: case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple); defaults->SetOffset(floatTriple);
break; break;
case LIGHTTAG_SIZE: case LIGHTTAG_SIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024); intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_INTENSITY, intVal); defaults->SetArg(LIGHT_INTENSITY, intVal);
break; break;
case LIGHTTAG_SECSIZE: case LIGHTTAG_SECSIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024); intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal);
break; break;
case LIGHTTAG_INTERVAL: case LIGHTTAG_INTERVAL:
floatVal = gl_ParseFloat(sc); floatVal = ParseFloat(sc);
defaults->SetParameter(floatVal * 360.); defaults->SetParameter(floatVal * 360.);
break; break;
case LIGHTTAG_SUBTRACTIVE: case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0); defaults->SetSubtractive(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_HALO: case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0); defaults->SetHalo(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_DONTLIGHTSELF: case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0); defaults->SetDontLightSelf(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_ATTENUATE: case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0); defaults->SetAttenuate(ParseInt(sc) != 0);
break; break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
@ -660,7 +655,7 @@ void gl_ParseFlickerLight2(FScanner &sc)
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_INTENSITY)); defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_INTENSITY));
defaults->SetArg(LIGHT_INTENSITY, v); defaults->SetArg(LIGHT_INTENSITY, v);
} }
gl_AddLightDefaults(defaults); AddLightDefaults(defaults);
} }
else else
{ {
@ -675,7 +670,7 @@ void gl_ParseFlickerLight2(FScanner &sc)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gl_ParseSectorLight(FScanner &sc) static void ParseSectorLight(FScanner &sc)
{ {
int type; int type;
float floatVal; float floatVal;
@ -705,36 +700,36 @@ void gl_ParseSectorLight(FScanner &sc)
ScriptDepth--; ScriptDepth--;
break; break;
case LIGHTTAG_COLOR: case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255)); defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255)); defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255)); defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break; break;
case LIGHTTAG_OFFSET: case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple); ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple); defaults->SetOffset(floatTriple);
break; break;
case LIGHTTAG_SCALE: case LIGHTTAG_SCALE:
floatVal = gl_ParseFloat(sc); floatVal = ParseFloat(sc);
defaults->SetArg(LIGHT_SCALE, clamp((int)(floatVal * 255), 1, 1024)); defaults->SetArg(LIGHT_SCALE, clamp((int)(floatVal * 255), 1, 1024));
break; break;
case LIGHTTAG_SUBTRACTIVE: case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0); defaults->SetSubtractive(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_HALO: case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0); defaults->SetHalo(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_DONTLIGHTSELF: case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0); defaults->SetDontLightSelf(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_ATTENUATE: case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0); defaults->SetAttenuate(ParseInt(sc) != 0);
break; break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
} }
} }
gl_AddLightDefaults(defaults); AddLightDefaults(defaults);
} }
else else
{ {
@ -749,7 +744,7 @@ void gl_ParseSectorLight(FScanner &sc)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gl_AddLightAssociation(const char *actor, const char *frame, const char *light) static void AddLightAssociation(const char *actor, const char *frame, const char *light)
{ {
FLightAssociation *temp; FLightAssociation *temp;
unsigned int i; unsigned int i;
@ -778,7 +773,7 @@ void gl_AddLightAssociation(const char *actor, const char *frame, const char *li
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gl_ParseFrame(FScanner &sc, FString name) static void ParseFrame(FScanner &sc, FString name)
{ {
int type, startDepth; int type, startDepth;
FString frameName; FString frameName;
@ -811,8 +806,8 @@ void gl_ParseFrame(FScanner &sc, FString name)
ScriptDepth--; ScriptDepth--;
break; break;
case LIGHTTAG_LIGHT: case LIGHTTAG_LIGHT:
gl_ParseString(sc); ParseString(sc);
gl_AddLightAssociation(name, frameName, sc.String); AddLightAssociation(name, frameName, sc.String);
break; break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
@ -832,7 +827,7 @@ void gl_ParseFrame(FScanner &sc, FString name)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gl_ParseObject(FScanner &sc) void ParseObject(FScanner &sc)
{ {
int type; int type;
FString name; FString name;
@ -840,7 +835,7 @@ void gl_ParseObject(FScanner &sc)
// get name // get name
sc.GetString(); sc.GetString();
name = sc.String; name = sc.String;
if (!PClass::FindClass(name)) if (!PClass::FindActor(name))
sc.ScriptMessage("Warning: dynamic lights attached to non-existent actor %s\n", name.GetChars()); sc.ScriptMessage("Warning: dynamic lights attached to non-existent actor %s\n", name.GetChars());
// check for opening brace // check for opening brace
@ -861,7 +856,7 @@ void gl_ParseObject(FScanner &sc)
ScriptDepth--; ScriptDepth--;
break; break;
case LIGHTTAG_FRAME: case LIGHTTAG_FRAME:
gl_ParseFrame(sc, name); ParseFrame(sc, name);
break; break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
@ -881,7 +876,7 @@ void gl_ParseObject(FScanner &sc)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gl_ReleaseLights() static void ReleaseLights()
{ {
unsigned int i; unsigned int i;
@ -950,7 +945,7 @@ enum
// There is no functionality for this stuff! // There is no functionality for this stuff!
// //
//========================================================================== //==========================================================================
bool gl_ParseShader(FScanner &sc) bool _gl_ParseShader(FScanner &sc)
{ {
int ShaderDepth = 0; int ShaderDepth = 0;
@ -983,8 +978,6 @@ bool gl_ParseShader(FScanner &sc)
// //
// Light associations per actor class // Light associations per actor class
// //
// Turn this inefficient mess into something that can be used at run time.
//
//========================================================================== //==========================================================================
class FInternalLightAssociation class FInternalLightAssociation
@ -1039,20 +1032,6 @@ FInternalLightAssociation::FInternalLightAssociation(FLightAssociation * asso)
} }
} }
//==========================================================================
//
//
//
//==========================================================================
inline TDeletingArray<FInternalLightAssociation *> * gl_GetActorLights(AActor * actor)
{
return (TDeletingArray<FInternalLightAssociation *>*)actor->lightassociations;
}
TDeletingArray< TDeletingArray<FInternalLightAssociation *> * > AssoDeleter;
//========================================================================== //==========================================================================
// //
// State lights // State lights
@ -1069,7 +1048,7 @@ TArray<FLightDefaults *> StateLights;
// //
//========================================================================== //==========================================================================
void gl_InitializeActorLights() void InitializeActorLights()
{ {
for(unsigned int i=0;i<LightAssociations.Size();i++) for(unsigned int i=0;i<LightAssociations.Size();i++)
{ {
@ -1077,28 +1056,11 @@ void gl_InitializeActorLights()
if (ti) if (ti)
{ {
ti = GetRealType(ti); ti = GetRealType(ti);
AActor * defaults = GetDefaultByType(ti); // put this in the class data arena so that we do not have to worry about deleting it ourselves.
if (defaults) void *mem = ClassDataAllocator.Alloc(sizeof(FInternalLightAssociation));
{ FInternalLightAssociation * iasso = new(mem) FInternalLightAssociation(&LightAssociations[i]);
FInternalLightAssociation * iasso = new FInternalLightAssociation(&LightAssociations[i]); if (iasso->Light() != nullptr)
ti->LightAssociations.Push(iasso);
if (!defaults->lightassociations)
{
TDeletingArray<FInternalLightAssociation*> *p =new TDeletingArray<FInternalLightAssociation*>;
defaults->lightassociations = p;
AssoDeleter.Push(p);
}
TDeletingArray<FInternalLightAssociation *> * lights = gl_GetActorLights(defaults);
if (iasso->Light()==NULL)
{
// The definition was not valid.
delete iasso;
}
else
{
lights->Push(iasso);
}
}
} }
} }
// we don't need the parser data for the light associations anymore // we don't need the parser data for the light associations anymore
@ -1134,24 +1096,23 @@ void gl_InitializeActorLights()
// //
//========================================================================== //==========================================================================
void gl_AttachLight(AActor *actor, unsigned int count, const FLightDefaults *lightdef) void AActor::AttachLight(unsigned int count, const FLightDefaults *lightdef)
{ {
ADynamicLight *light; ADynamicLight *light;
// I'm skipping the single rotations because that really doesn't make sense! if (count < AttachedLights.Size())
if (count < actor->dynamiclights.Size())
{ {
light = barrier_cast<ADynamicLight*>(actor->dynamiclights[count]); light = barrier_cast<ADynamicLight*>(AttachedLights[count]);
assert(light != NULL); assert(light != NULL);
} }
else else
{ {
light = Spawn<ADynamicLight>(actor->Pos(), NO_REPLACE); light = Spawn<ADynamicLight>(Pos(), NO_REPLACE);
light->target = actor; light->target = this;
light->owned = true; light->owned = true;
light->ObjectFlags |= OF_Transient; light->ObjectFlags |= OF_Transient;
//light->flags4 |= MF4_ATTENUATE; //light->flags4 |= MF4_ATTENUATE;
actor->dynamiclights.Push(light); AttachedLights.Push(light);
} }
light->flags2&=~MF2_DORMANT; light->flags2&=~MF2_DORMANT;
lightdef->ApplyProperties(light); lightdef->ApplyProperties(light);
@ -1163,51 +1124,59 @@ void gl_AttachLight(AActor *actor, unsigned int count, const FLightDefaults *lig
// //
//========================================================================== //==========================================================================
void gl_SetActorLights(AActor *actor) void AActor::SetDynamicLights()
{ {
TArray<FInternalLightAssociation *> * l = gl_GetActorLights(actor); TArray<FInternalLightAssociation *> & LightAssociations = GetClass()->LightAssociations;
unsigned int count = 0; unsigned int count = 0;
All.Clock(); if (state == NULL) return;
if (actor->state == NULL) return; if (LightAssociations.Size() > 0)
if (l)
{ {
TArray<FInternalLightAssociation *> & LightAssociations=*l;
ADynamicLight *lights, *tmpLight; ADynamicLight *lights, *tmpLight;
unsigned int i; unsigned int i;
int sprite = actor->sprite;
int frame = actor->frame;
lights = tmpLight = NULL; lights = tmpLight = NULL;
for (i = 0; i < LightAssociations.Size(); i++) for (i = 0; i < LightAssociations.Size(); i++)
{ {
if (LightAssociations[i]->Sprite() == sprite && if (LightAssociations[i]->Sprite() == sprite &&
(LightAssociations[i]->Frame()==frame || LightAssociations[i]->Frame()==-1)) (LightAssociations[i]->Frame()==frame || LightAssociations[i]->Frame()==-1))
{ {
gl_AttachLight(actor, count++, LightAssociations[i]->Light()); AttachLight(count++, LightAssociations[i]->Light());
} }
} }
} }
if (count == 0 && actor->state->Light > 0) if (count == 0 && state->Light > 0)
{ {
for(int i= actor->state->Light; StateLights[i] != NULL; i++) for(int i= state->Light; StateLights[i] != NULL; i++)
{ {
if (StateLights[i] != (FLightDefaults*)-1) if (StateLights[i] != (FLightDefaults*)-1)
{ {
gl_AttachLight(actor, count++, StateLights[i]); AttachLight(count++, StateLights[i]);
} }
} }
} }
for(;count<actor->dynamiclights.Size();count++) for(;count<AttachedLights.Size();count++)
{ {
actor->dynamiclights[count]->flags2 |= MF2_DORMANT; AttachedLights[count]->flags2 |= MF2_DORMANT;
memset(actor->dynamiclights[count]->args, 0, 3*sizeof(actor->args[0])); memset(AttachedLights[count]->args, 0, 3*sizeof(args[0]));
} }
All.Unclock(); }
//==========================================================================
//
// Needed for garbage collection
//
//==========================================================================
size_t AActor::PropagateMark()
{
for (unsigned i = 0; i<AttachedLights.Size(); i++)
{
GC::Mark(AttachedLights[i]);
}
return Super::PropagateMark();
} }
//========================================================================== //==========================================================================
@ -1216,7 +1185,7 @@ void gl_SetActorLights(AActor *actor)
// //
//========================================================================== //==========================================================================
void gl_DeleteAllAttachedLights() void AActor::DeleteAllAttachedLights()
{ {
TThinkerIterator<AActor> it; TThinkerIterator<AActor> it;
AActor * a; AActor * a;
@ -1224,7 +1193,7 @@ void gl_DeleteAllAttachedLights()
while ((a=it.Next())) while ((a=it.Next()))
{ {
a->dynamiclights.Clear(); a->AttachedLights.Clear();
} }
TThinkerIterator<ADynamicLight> it2; TThinkerIterator<ADynamicLight> it2;
@ -1236,8 +1205,6 @@ void gl_DeleteAllAttachedLights()
if (l->owned) l->Destroy(); if (l->owned) l->Destroy();
l=ll; l=ll;
} }
} }
//========================================================================== //==========================================================================
@ -1246,14 +1213,14 @@ void gl_DeleteAllAttachedLights()
// //
//========================================================================== //==========================================================================
void gl_RecreateAllAttachedLights() void AActor::RecreateAllAttachedLights()
{ {
TThinkerIterator<AActor> it; TThinkerIterator<AActor> it;
AActor * a; AActor * a;
while ((a=it.Next())) while ((a=it.Next()))
{ {
gl_SetActorLights(a); a->SetDynamicLights();
} }
} }
@ -1264,7 +1231,7 @@ void gl_RecreateAllAttachedLights()
// by LoadDynLightDefs, which wasn't simply integrated into ParseDefs // by LoadDynLightDefs, which wasn't simply integrated into ParseDefs
// because of the way the code needs to load two out of five lumps. // because of the way the code needs to load two out of five lumps.
//========================================================================== //==========================================================================
void gl_DoParseDefs(FScanner &sc, int workingLump) static void DoParseDefs(FScanner &sc, int workingLump)
{ {
int recursion=0; int recursion=0;
int lump, type; int lump, type;
@ -1289,32 +1256,32 @@ void gl_DoParseDefs(FScanner &sc, int workingLump)
sc.ScriptError("Lump '%s' not found", sc.String); sc.ScriptError("Lump '%s' not found", sc.String);
FScanner newscanner(lump); FScanner newscanner(lump);
gl_DoParseDefs(newscanner, lump); DoParseDefs(newscanner, lump);
break; break;
} }
case LIGHT_POINT: case LIGHT_POINT:
gl_ParsePointLight(sc); ParsePointLight(sc);
break; break;
case LIGHT_PULSE: case LIGHT_PULSE:
gl_ParsePulseLight(sc); ParsePulseLight(sc);
break; break;
case LIGHT_FLICKER: case LIGHT_FLICKER:
gl_ParseFlickerLight(sc); ParseFlickerLight(sc);
break; break;
case LIGHT_FLICKER2: case LIGHT_FLICKER2:
gl_ParseFlickerLight2(sc); ParseFlickerLight2(sc);
break; break;
case LIGHT_SECTOR: case LIGHT_SECTOR:
gl_ParseSectorLight(sc); ParseSectorLight(sc);
break; break;
case LIGHT_OBJECT: case LIGHT_OBJECT:
gl_ParseObject(sc); ParseObject(sc);
break; break;
case LIGHT_CLEAR: case LIGHT_CLEAR:
gl_ReleaseLights(); // This has been intentionally removed
break; break;
case TAG_SHADER: case TAG_SHADER:
gl_ParseShader(sc); _gl_ParseShader(sc);
break; break;
case TAG_CLEARSHADERS: case TAG_CLEARSHADERS:
break; break;
@ -1355,7 +1322,7 @@ void gl_DoParseDefs(FScanner &sc, int workingLump)
// //
//========================================================================== //==========================================================================
void gl_LoadGLDefs(const char *defsLump) static void LoadGLDefs(const char *defsLump)
{ {
int workingLump, lastLump; int workingLump, lastLump;
static const char *gldefsnames[] = { "GLDEFS", defsLump, nullptr }; static const char *gldefsnames[] = { "GLDEFS", defsLump, nullptr };
@ -1364,7 +1331,7 @@ void gl_LoadGLDefs(const char *defsLump)
while ((workingLump = Wads.FindLumpMulti(gldefsnames, &lastLump)) != -1) while ((workingLump = Wads.FindLumpMulti(gldefsnames, &lastLump)) != -1)
{ {
FScanner sc(workingLump); FScanner sc(workingLump);
gl_DoParseDefs(sc, workingLump); DoParseDefs(sc, workingLump);
} }
} }
@ -1375,12 +1342,12 @@ void gl_LoadGLDefs(const char *defsLump)
// //
//========================================================================== //==========================================================================
void gl_ParseDefs() void ParseGLDefs()
{ {
const char *defsLump = NULL; const char *defsLump = NULL;
atterm( gl_ReleaseLights ); atterm(ReleaseLights );
gl_ReleaseLights(); ReleaseLights();
gl_DestroyUserShaders(); gl_DestroyUserShaders();
switch (gameinfo.gametype) switch (gameinfo.gametype)
{ {
@ -1403,11 +1370,10 @@ void gl_ParseDefs()
break; break;
} }
gl_ParseVavoomSkybox(); gl_ParseVavoomSkybox();
gl_LoadGLDefs(defsLump); LoadGLDefs(defsLump);
gl_InitializeActorLights(); InitializeActorLights();
} }
//========================================================================== //==========================================================================
// //
// //

View file

@ -61,7 +61,6 @@ long gl_frameCount;
EXTERN_CVAR(Int, gl_lightmode) EXTERN_CVAR(Int, gl_lightmode)
EXTERN_CVAR(Bool, gl_brightfog) EXTERN_CVAR(Bool, gl_brightfog)
EXTERN_CVAR(Bool, gl_lightadditivesurfaces) EXTERN_CVAR(Bool, gl_lightadditivesurfaces)
EXTERN_CVAR(Bool, gl_attenuate)
CUSTOM_CVAR(Float, maxviewpitch, 90.f, CVAR_ARCHIVE|CVAR_SERVERINFO) CUSTOM_CVAR(Float, maxviewpitch, 90.f, CVAR_ARCHIVE|CVAR_SERVERINFO)
@ -240,7 +239,6 @@ struct FGLROptions : public FOptionalMapinfoData
skyfog = 0; skyfog = 0;
brightfog = false; brightfog = false;
lightmode = -1; lightmode = -1;
attenuate = -1;
nocoloredspritelighting = -1; nocoloredspritelighting = -1;
nolightfade = false; nolightfade = false;
notexturefill = -1; notexturefill = -1;
@ -257,7 +255,6 @@ struct FGLROptions : public FOptionalMapinfoData
newopt->outsidefogdensity = outsidefogdensity; newopt->outsidefogdensity = outsidefogdensity;
newopt->skyfog = skyfog; newopt->skyfog = skyfog;
newopt->lightmode = lightmode; newopt->lightmode = lightmode;
newopt->attenuate = attenuate;
newopt->nocoloredspritelighting = nocoloredspritelighting; newopt->nocoloredspritelighting = nocoloredspritelighting;
newopt->nolightfade = nolightfade; newopt->nolightfade = nolightfade;
newopt->notexturefill = notexturefill; newopt->notexturefill = notexturefill;
@ -272,7 +269,6 @@ struct FGLROptions : public FOptionalMapinfoData
int skyfog; int skyfog;
int lightmode; int lightmode;
int brightfog; int brightfog;
int8_t attenuate;
int8_t lightadditivesurfaces; int8_t lightadditivesurfaces;
int8_t nocoloredspritelighting; int8_t nocoloredspritelighting;
int8_t notexturefill; int8_t notexturefill;
@ -378,20 +374,6 @@ DEFINE_MAP_OPTION(lightadditivesurfaces, false)
} }
} }
DEFINE_MAP_OPTION(attenuate, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
if (parse.CheckAssign())
{
parse.sc.MustGetNumber();
opt->attenuate = !!parse.sc.Number;
}
else
{
opt->attenuate = true;
}
}
DEFINE_MAP_OPTION(skyrotate, false) DEFINE_MAP_OPTION(skyrotate, false)
{ {
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer"); FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
@ -450,8 +432,6 @@ static void ResetOpts()
else glset.brightfog = !!glset.map_brightfog; else glset.brightfog = !!glset.map_brightfog;
if (glset.map_lightadditivesurfaces == -1) glset.lightadditivesurfaces = gl_lightadditivesurfaces; if (glset.map_lightadditivesurfaces == -1) glset.lightadditivesurfaces = gl_lightadditivesurfaces;
else glset.lightadditivesurfaces = !!glset.map_lightadditivesurfaces; else glset.lightadditivesurfaces = !!glset.map_lightadditivesurfaces;
if (glset.map_attenuate == -1) glset.attenuate = gl_attenuate;
else glset.attenuate = !!glset.map_attenuate;
} }
void InitGLRMapinfoData() void InitGLRMapinfoData()
@ -463,7 +443,6 @@ void InitGLRMapinfoData()
gl_SetFogParams(clamp(opt->fogdensity, 0, 255), level.info->outsidefog, clamp(opt->outsidefogdensity, 0, 255), opt->skyfog); gl_SetFogParams(clamp(opt->fogdensity, 0, 255), level.info->outsidefog, clamp(opt->outsidefogdensity, 0, 255), opt->skyfog);
glset.map_lightmode = opt->lightmode; glset.map_lightmode = opt->lightmode;
glset.map_lightadditivesurfaces = opt->lightadditivesurfaces; glset.map_lightadditivesurfaces = opt->lightadditivesurfaces;
glset.map_attenuate = opt->attenuate;
glset.map_brightfog = opt->brightfog; glset.map_brightfog = opt->brightfog;
glset.map_nocoloredspritelighting = opt->nocoloredspritelighting; glset.map_nocoloredspritelighting = opt->nocoloredspritelighting;
glset.map_notexturefill = opt->notexturefill; glset.map_notexturefill = opt->notexturefill;
@ -478,7 +457,6 @@ void InitGLRMapinfoData()
glset.map_lightmode = -1; glset.map_lightmode = -1;
glset.map_lightadditivesurfaces = -1; glset.map_lightadditivesurfaces = -1;
glset.map_brightfog = -1; glset.map_brightfog = -1;
glset.map_attenuate = -1;
glset.map_nocoloredspritelighting = -1; glset.map_nocoloredspritelighting = -1;
glset.map_notexturefill = -1; glset.map_notexturefill = -1;
glset.skyrotatevector = FVector3(0, 0, 1); glset.skyrotatevector = FVector3(0, 0, 1);

View file

@ -8,21 +8,18 @@
struct GLRenderSettings struct GLRenderSettings
{ {
int8_t lightmode; int8_t lightmode;
bool nocoloredspritelighting; bool nocoloredspritelighting;
bool nolightfade; bool nolightfade;
bool notexturefill; bool notexturefill;
bool brightfog; bool brightfog;
bool lightadditivesurfaces; bool lightadditivesurfaces;
bool attenuate;
int8_t map_lightmode; int8_t map_lightmode;
int8_t map_nocoloredspritelighting; int8_t map_nocoloredspritelighting;
int8_t map_notexturefill; int8_t map_notexturefill;
int8_t map_brightfog; int8_t map_brightfog;
int8_t map_lightadditivesurfaces; int8_t map_lightadditivesurfaces;
int8_t map_attenuate;
FVector3 skyrotatevector; FVector3 skyrotatevector;
FVector3 skyrotatevector2; FVector3 skyrotatevector2;

View file

@ -24,135 +24,10 @@
#define __GLC_DYNLIGHT_H #define __GLC_DYNLIGHT_H
#include "c_cvars.h" #include "c_cvars.h"
#include "a_dynlight.h"
#include "gl/utility/gl_geometric.h" #include "gl/utility/gl_geometric.h"
#include "gl/utility/gl_cycler.h"
#include "actor.h"
EXTERN_CVAR(Bool, gl_lights)
EXTERN_CVAR(Bool, gl_attachedlights)
class ADynamicLight;
class FSerializer;
class FLightDefaults;
enum
{
LIGHT_RED = 0,
LIGHT_GREEN = 1,
LIGHT_BLUE = 2,
LIGHT_INTENSITY = 3,
LIGHT_SECONDARY_INTENSITY = 4,
LIGHT_SCALE = 3,
};
// This is as good as something new - and it can be set directly in the ActorInfo!
#define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE
#define MF4_ADDITIVE MF4_MISSILEMORE
#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS
#define MF4_ATTENUATE MF4_INCOMBAT
enum ELightType
{
PointLight,
PulseLight,
FlickerLight,
RandomFlickerLight,
SectorLight,
SpotLight,
ColorPulseLight,
ColorFlickerLight,
RandomColorFlickerLight
};
struct FLightNode
{
FLightNode ** prevTarget;
FLightNode * nextTarget;
FLightNode ** prevLight;
FLightNode * nextLight;
ADynamicLight * lightsource;
union
{
side_t * targLine;
subsector_t * targSubsector;
void * targ;
};
};
//
// Base class
//
// [CO] I merged everything together in this one class so that I don't have
// to create and re-create an excessive amount of objects
//
class ADynamicLight : public AActor
{
friend class FLightDefaults;
DECLARE_CLASS (ADynamicLight, AActor)
public:
virtual void Tick();
void Serialize(FSerializer &arc);
void PostSerialize();
uint8_t GetRed() const { return args[LIGHT_RED]; }
uint8_t GetGreen() const { return args[LIGHT_GREEN]; }
uint8_t GetBlue() const { return args[LIGHT_BLUE]; }
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
void LinkLight();
void UnlinkLight();
size_t PointerSubstitution (DObject *old, DObject *notOld);
void BeginPlay();
void SetOrigin (double x, double y, double z, bool moving = false);
void PostBeginPlay();
void OnDestroy() override;
void Activate(AActor *activator);
void Deactivate(AActor *activator);
void SetOffset(const DVector3 &pos);
void UpdateLocation();
bool IsOwned() const { return owned; }
bool IsActive() const { return !(flags2&MF2_DORMANT); }
bool IsSubtractive() { return !!(flags4&MF4_SUBTRACTIVE); }
bool IsAdditive() { return !!(flags4&MF4_ADDITIVE); }
FState *targetState;
FLightNode * touching_sides;
FLightNode * touching_subsectors;
FLightNode * touching_sector;
private:
double DistToSeg(const DVector3 &pos, seg_t *seg);
void CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius);
protected:
DVector3 m_off;
float m_currentRadius;
unsigned int m_lastUpdate;
FCycler m_cycler;
subsector_t * subsector;
public:
int m_tickCount;
uint8_t lightflags;
uint8_t lighttype;
bool owned;
bool halo;
uint8_t color2[3];
bool visibletoplayer;
bool swapped;
int bufferindex;
};
enum
{
STAT_DLIGHT=64
};
struct FDynLightData struct FDynLightData
{ {
TArray<float> arrays[3]; TArray<float> arrays[3];

View file

@ -32,6 +32,7 @@
#include "gl/gl_functions.h" #include "gl/gl_functions.h"
#include "g_level.h" #include "g_level.h"
#include "actorinlines.h" #include "actorinlines.h"
#include "a_dynlight.h"
#include "gl/system/gl_interface.h" #include "gl/system/gl_interface.h"
#include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderer.h"
@ -50,18 +51,13 @@
// //
//========================================================================== //==========================================================================
CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
if (self) gl_RecreateAllAttachedLights();
else gl_DeleteAllAttachedLights();
}
CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(Int, gl_attenuate, -1, 0); // This is mainly a debug option.
//========================================================================== //==========================================================================
// //
// Sets up the parameters to render one dynamic light onto one plane // Sets up the parameters to render one dynamic light onto one plane
@ -112,7 +108,11 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD
// Store attenuate flag in the sign bit of the float. // Store attenuate flag in the sign bit of the float.
float shadowIndex = GLRenderer->mShadowMap.ShadowMapIndex(light) + 1.0f; float shadowIndex = GLRenderer->mShadowMap.ShadowMapIndex(light) + 1.0f;
if (!!(light->flags4 & MF4_ATTENUATE)) bool attenuate;
if (gl_attenuate == -1) attenuate = !!(light->flags4 & MF4_ATTENUATE);
else attenuate = !!gl_attenuate;
shadowIndex = -shadowIndex; shadowIndex = -shadowIndex;
float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)]; float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)];

View file

@ -8,6 +8,5 @@ class AActor;
void gl_PreprocessLevel(); void gl_PreprocessLevel();
void gl_CleanLevelData(); void gl_CleanLevelData();
void gl_LinkLights(); void gl_LinkLights();
void gl_SetActorLights(AActor *);
#endif #endif

View file

@ -59,7 +59,6 @@ CUSTOM_CVAR(Bool, gl_enhanced_nightvision, true, CVAR_ARCHIVE|CVAR_NOINITCALL)
} }
CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE); CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE);
CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE); CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE);
CVAR(Bool, gl_attenuate, false, CVAR_ARCHIVE);

View file

@ -42,9 +42,6 @@ inline bool gl_isFullbright(PalEntry color, int lightlevel)
return gl_fixedcolormap || (gl_isWhite(color) && lightlevel==255); return gl_fixedcolormap || (gl_isWhite(color) && lightlevel==255);
} }
void gl_DeleteAllAttachedLights();
void gl_RecreateAllAttachedLights();
extern int fogdensity; extern int fogdensity;
extern int outsidefogdensity; extern int outsidefogdensity;
extern int skyfog; extern int skyfog;

View file

@ -189,7 +189,7 @@ void FGLRenderer::Initialize(int width, int height)
FGLRenderer::~FGLRenderer() FGLRenderer::~FGLRenderer()
{ {
gl_FlushModels(); gl_FlushModels();
gl_DeleteAllAttachedLights(); AActor::DeleteAllAttachedLights();
FMaterial::FlushAll(); FMaterial::FlushAll();
if (m2DDrawer != nullptr) delete m2DDrawer; if (m2DDrawer != nullptr) delete m2DDrawer;
if (mShaderManager != NULL) delete mShaderManager; if (mShaderManager != NULL) delete mShaderManager;

View file

@ -93,8 +93,6 @@ area_t in_area;
TArray<uint8_t> currentmapsection; TArray<uint8_t> currentmapsection;
int camtexcount; int camtexcount;
void gl_ParseDefs();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// R_FrustumAngle // R_FrustumAngle
@ -991,7 +989,6 @@ struct FGLInterface : public FRenderer
void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override; void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override;
void RenderView(player_t *player) override; void RenderView(player_t *player) override;
void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override; void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override;
void StateChanged(AActor *actor) override;
void StartSerialize(FSerializer &arc) override; void StartSerialize(FSerializer &arc) override;
void EndSerialize(FSerializer &arc) override; void EndSerialize(FSerializer &arc) override;
void RenderTextureView (FCanvasTexture *self, AActor *viewpoint, int fov) override; void RenderTextureView (FCanvasTexture *self, AActor *viewpoint, int fov) override;
@ -1030,17 +1027,6 @@ void FGLInterface::Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actor
gl_PrecacheTexture(texhitlist, actorhitlist); gl_PrecacheTexture(texhitlist, actorhitlist);
} }
//==========================================================================
//
// DFrameBuffer :: StateChanged
//
//==========================================================================
void FGLInterface::StateChanged(AActor *actor)
{
gl_SetActorLights(actor);
}
//=========================================================================== //===========================================================================
// //
// notify the renderer that serialization of the curent level is about to start/end // notify the renderer that serialization of the curent level is about to start/end
@ -1062,7 +1048,6 @@ void FGLInterface::EndSerialize(FSerializer &arc)
{ {
if (arc.isReading()) if (arc.isReading())
{ {
gl_RecreateAllAttachedLights();
gl_InitPortals(); gl_InitPortals();
} }
} }
@ -1126,7 +1111,6 @@ void FGLInterface::RenderView(player_t *player)
void FGLInterface::Init() void FGLInterface::Init()
{ {
gl_ParseDefs();
gl_InitData(); gl_InitData();
} }

View file

@ -5,7 +5,7 @@
#include "tarray.h" #include "tarray.h"
#include "zstring.h" #include "zstring.h"
#include "gl/utility/gl_cycler.h" #include "cycler.h"
enum enum

View file

@ -35,11 +35,7 @@
#define __INFO_H__ #define __INFO_H__
#include <stddef.h> #include <stddef.h>
#if !defined(_WIN32) #include <stdint.h>
#include <inttypes.h> // for intptr_t
#else
#include <stdint.h> // for mingw
#endif
#include "dobject.h" #include "dobject.h"
#include "doomdef.h" #include "doomdef.h"
@ -53,6 +49,7 @@ class FScanner;
struct FActorInfo; struct FActorInfo;
class FIntCVar; class FIntCVar;
class FStateDefinitions; class FStateDefinitions;
class FInternalLightAssociation;
enum EStateDefineFlags enum EStateDefineFlags
{ {
@ -118,7 +115,7 @@ struct FState
uint16_t StateFlags; uint16_t StateFlags;
uint8_t Frame; uint8_t Frame;
uint8_t UseFlags; uint8_t UseFlags;
uint8_t DefineFlags; // Unused byte so let's use it during state creation. uint8_t DefineFlags;
int32_t Misc1; // Was changed to int8_t, reverted to long for MBF compat int32_t Misc1; // Was changed to int8_t, reverted to long for MBF compat
int32_t Misc2; // Was changed to uint8_t, reverted to long for MBF compat int32_t Misc2; // Was changed to uint8_t, reverted to long for MBF compat
public: public:
@ -275,6 +272,7 @@ public:
PClassActor *GetReplacement(bool lookskill=true); PClassActor *GetReplacement(bool lookskill=true);
PClassActor *GetReplacee(bool lookskill=true); PClassActor *GetReplacee(bool lookskill=true);
TArray<FInternalLightAssociation *> LightAssociations;
FState *OwnedStates; FState *OwnedStates;
PClassActor *Replacement; PClassActor *Replacement;
PClassActor *Replacee; PClassActor *Replacee;

View file

@ -700,7 +700,7 @@ bool AActor::SetState (FState *newstate, bool nofunction)
if (Renderer != NULL) if (Renderer != NULL)
{ {
Renderer->StateChanged(this); SetDynamicLights();
} }
return true; return true;
} }
@ -5074,10 +5074,7 @@ void AActor::CallBeginPlay()
void AActor::PostBeginPlay () void AActor::PostBeginPlay ()
{ {
if (Renderer != NULL) SetDynamicLights();
{
Renderer->StateChanged(this);
}
PrevAngles = Angles; PrevAngles = Angles;
flags7 |= MF7_HANDLENODELAY; flags7 |= MF7_HANDLENODELAY;
} }

View file

@ -998,6 +998,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
} }
} }
} }
AActor::RecreateAllAttachedLights();
Renderer->EndSerialize(arc); Renderer->EndSerialize(arc);
} }

View file

@ -43,9 +43,6 @@ struct FRenderer
// draws player sprites with hardware acceleration (only useful for software rendering) // draws player sprites with hardware acceleration (only useful for software rendering)
virtual void DrawRemainingPlayerSprites() {} virtual void DrawRemainingPlayerSprites() {}
// notifies the renderer that an actor has changed state.
virtual void StateChanged(AActor *actor) {}
// notify the renderer that serialization of the curent level is about to start/end // notify the renderer that serialization of the curent level is about to start/end
virtual void StartSerialize(FSerializer &arc) {} virtual void StartSerialize(FSerializer &arc) {}
virtual void EndSerialize(FSerializer &arc) {} virtual void EndSerialize(FSerializer &arc) {}

View file

@ -59,6 +59,7 @@ enum
STAT_LIGHTTRANSFER, // A sector light transfer. These must be ticked after the light effects!!! STAT_LIGHTTRANSFER, // A sector light transfer. These must be ticked after the light effects!!!
STAT_EARTHQUAKE, // Earthquake actors STAT_EARTHQUAKE, // Earthquake actors
STAT_MAPMARKER, // Map marker actors STAT_MAPMARKER, // Map marker actors
STAT_DLIGHT,
STAT_DEFAULT = 100, // Thinkers go here unless specified otherwise. STAT_DEFAULT = 100, // Thinkers go here unless specified otherwise.
STAT_SECTOREFFECT, // All sector effects that cause floor and ceiling movement STAT_SECTOREFFECT, // All sector effects that cause floor and ceiling movement

View file

@ -50,9 +50,7 @@
#include "polyrenderer/poly_renderer.h" #include "polyrenderer/poly_renderer.h"
#include "p_setup.h" #include "p_setup.h"
void gl_ParseDefs();
void gl_InitData(); void gl_InitData();
void gl_SetActorLights(AActor *);
void gl_PreprocessLevel(); void gl_PreprocessLevel();
void gl_CleanLevelData(); void gl_CleanLevelData();
@ -85,8 +83,6 @@ FSoftwareRenderer::~FSoftwareRenderer()
void FSoftwareRenderer::Init() void FSoftwareRenderer::Init()
{ {
gl_ParseDefs();
mScene.Init(); mScene.Init();
} }
@ -362,11 +358,6 @@ sector_t *FSoftwareRenderer::FakeFlat(sector_t *sec, sector_t *tempsec, int *flo
return mScene.MainThread()->OpaquePass->FakeFlat(sec, tempsec, floorlightlevel, ceilinglightlevel, nullptr, 0, 0, 0, 0); return mScene.MainThread()->OpaquePass->FakeFlat(sec, tempsec, floorlightlevel, ceilinglightlevel, nullptr, 0, 0, 0, 0);
} }
void FSoftwareRenderer::StateChanged(AActor *actor)
{
gl_SetActorLights(actor);
}
void FSoftwareRenderer::PreprocessLevel() void FSoftwareRenderer::PreprocessLevel()
{ {
gl_PreprocessLevel(); gl_PreprocessLevel();

View file

@ -36,7 +36,6 @@ struct FSoftwareRenderer : public FRenderer
void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) override; void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) override;
sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel) override; sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel) override;
void StateChanged(AActor *actor) override;
void PreprocessLevel() override; void PreprocessLevel() override;
void CleanLevelData() override; void CleanLevelData() override;

View file

@ -316,6 +316,7 @@ class Thinker : Object native play
STAT_LIGHTTRANSFER, // A sector light transfer. These must be ticked after the light effects. STAT_LIGHTTRANSFER, // A sector light transfer. These must be ticked after the light effects.
STAT_EARTHQUAKE, // Earthquake actors STAT_EARTHQUAKE, // Earthquake actors
STAT_MAPMARKER, // Map marker actors STAT_MAPMARKER, // Map marker actors
STAT_DLIGHT, // Dynamic lights
STAT_DEFAULT = 100, // Thinkers go here unless specified otherwise. STAT_DEFAULT = 100, // Thinkers go here unless specified otherwise.
STAT_SECTOREFFECT, // All sector effects that cause floor and ceiling movement STAT_SECTOREFFECT, // All sector effects that cause floor and ceiling movement