diff --git a/source/core/r_data/a_dynlight.h b/source/core/r_data/a_dynlight.h new file mode 100644 index 000000000..866ce6bcc --- /dev/null +++ b/source/core/r_data/a_dynlight.h @@ -0,0 +1,284 @@ +#pragma once +#include "c_cvars.h" +//#include "actor.h" +#include "cycler.h" +//#include "g_levellocals.h" +#include "tflags.h" + +struct side_t; +struct seg_t; + +class FSerializer; +struct FSectionLine; + +enum ELightType +{ + PointLight, + PulseLight, + FlickerLight, + RandomFlickerLight, + SectorLight, + DummyLight, + ColorPulseLight, + ColorFlickerLight, + RandomColorFlickerLight +}; + +enum +{ + LIGHT_RED = 0, + LIGHT_GREEN = 1, + LIGHT_BLUE = 2, + LIGHT_INTENSITY = 3, + LIGHT_SECONDARY_INTENSITY = 4, +}; + +enum LightFlag +{ + LF_SUBTRACTIVE = 1, + LF_ADDITIVE = 2, + LF_DONTLIGHTSELF = 4, + LF_ATTENUATE = 8, + LF_NOSHADOWMAP = 16, + LF_DONTLIGHTACTORS = 32, + LF_SPOT = 64 +}; + +typedef TFlags LightFlags; +DEFINE_TFLAGS_OPERATORS(LightFlags) + +//========================================================================== +// +// Light definitions +// +//========================================================================== +#if 0 +class FLightDefaults +{ +public: + FLightDefaults(FName name, ELightType type = PointLight) + { + m_Name = name; + m_type = type; + } + + void ApplyProperties(FDynamicLight * light) const; + FName GetName() const { return m_Name; } + void SetParameter(double p) { m_Param = p; } + void SetArg(int arg, int val) { m_Args[arg] = val; } + 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) { 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; } + void SetSpotPitch(double pitch) + { + m_pitch = pitch; + m_explicitPitch = true; + } + void UnsetSpotPitch() + { + m_pitch = 0.; + m_explicitPitch = false; + } + void SetType(ELightType type) { m_type = type; } + void CopyFrom(const FLightDefaults &other) + { + auto n = m_Name; + *this = other; + m_Name = n; + } + void SetFlags(LightFlags lf) + { + m_lightFlags = lf; + m_attenuate = !!(m_lightFlags & LF_ATTENUATE); + } + static void SetAttenuationForLevel(bool); + + void OrderIntensities() + { + if (m_Args[LIGHT_INTENSITY] > m_Args[LIGHT_SECONDARY_INTENSITY]) + { + std::swap(m_Args[LIGHT_INTENSITY], m_Args[LIGHT_SECONDARY_INTENSITY]); + m_swapped = true; + } + } + +protected: + FName m_Name = NAME_None; + int m_Args[5] = { 0,0,0,0,0 }; + double m_Param = 0; + DVector3 m_Pos = { 0,0,0 }; + int m_type; + int8_t m_attenuate = -1; + LightFlags m_lightFlags = 0; + bool m_swapped = false; + bool m_spot = false; + bool m_explicitPitch = false; + DAngle m_spotInnerAngle = 10.0; + DAngle m_spotOuterAngle = 25.0; + DAngle m_pitch = 0.0; + + friend FSerializer &Serialize(FSerializer &arc, const char *key, FLightDefaults &value, FLightDefaults *def); +}; + +FSerializer &Serialize(FSerializer &arc, const char *key, TDeletingArray &value, TDeletingArray *def); +#endif +//========================================================================== +// +// Light associations (intermediate parser data) +// +//========================================================================== + +class FLightAssociation +{ +public: + //FLightAssociation(); + FLightAssociation(FName actorName, const char *frameName, FName lightName) + : m_ActorName(actorName), m_AssocLight(lightName) + { + strncpy(m_FrameName, frameName, 8); + } + + FName ActorName() { return m_ActorName; } + const char *FrameName() { return m_FrameName; } + FName Light() { return m_AssocLight; } + void ReplaceLightName(FName newName) { m_AssocLight = newName; } +protected: + char m_FrameName[8]; + FName m_ActorName, m_AssocLight; +}; + + +//========================================================================== +// +// Light associations per actor class +// +//========================================================================== +#if 0 +class FInternalLightAssociation +{ +public: + FInternalLightAssociation(FLightAssociation * asso); + int Sprite() const { return m_sprite; } + int Frame() const { return m_frame; } + const FLightDefaults *Light() const { return m_AssocLight; } +protected: + int m_sprite; + int m_frame; + FLightDefaults * m_AssocLight; +}; +#endif +#if 0 +struct FLightNode +{ + FLightNode ** prevTarget; + FLightNode * nextTarget; + FLightNode ** prevLight; + FLightNode * nextLight; + FDynamicLight * lightsource; + union + { + side_t * targLine; + subsector_t * targSubsector; + void * targ; + }; +}; +#endif +#if 0 +struct FDynamicLight +{ + friend class FLightDefaults; + + inline DVector3 PosRelative(int portalgroup) const + { + return Pos + Level->Displacements.getOffset(Sector->PortalGroup, portalgroup); + } + + bool ShouldLightActor(AActor *check) + { + return visibletoplayer && IsActive() && (!((*pLightFlags) & LF_DONTLIGHTSELF) || target != check) && !((*pLightFlags) & LF_DONTLIGHTACTORS); + } + + void SetOffset(const DVector3 &pos) + { + m_off = pos; + } + + + bool IsActive() const { return m_active; } + float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); } + int GetRed() const { return pArgs[LIGHT_RED]; } + int GetGreen() const { return pArgs[LIGHT_GREEN]; } + int GetBlue() const { return pArgs[LIGHT_BLUE]; } + int GetIntensity() const { return pArgs[LIGHT_INTENSITY]; } + int GetSecondaryIntensity() const { return pArgs[LIGHT_SECONDARY_INTENSITY]; } + + 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(); + + void SetActor(AActor *ac, bool isowned) { target = ac; owned = isowned; } + double X() const { return Pos.X; } + double Y() const { return Pos.Y; } + double Z() const { return Pos.Z; } + + void Tick(); + void UpdateLocation(); + void LinkLight(); + void UnlinkLight(); + void ReleaseLight(); + +private: + double DistToSeg(const DVector3 &pos, vertex_t *start, vertex_t *end); + void CollectWithinRadius(const DVector3 &pos, FSection *section, float radius); + +public: + FCycler m_cycler; + DVector3 Pos; + DVector3 m_off; + + // This date can either come from the owning actor or from a light definition + // To avoid having to copy these around every tic, these are pointers to the source data. + const DAngle *pSpotInnerAngle; + 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; + sector_t *Sector; + FLevelLocals *Level; + TObjPtr target; + FLightNode * touching_sides; + FLightNode * touching_sector; + float radius; // The maximum size the light can be with its current settings. + float m_currentRadius; // The current light size. + int m_tickCount; + int m_lastUpdate; + int mShadowmapIndex; + bool m_active; + bool visibletoplayer; + bool shadowmapped; + uint8_t lighttype; + bool owned; + bool swapped; + bool explicitpitch; + +}; +#endif + diff --git a/source/core/r_data/gldefs.cpp b/source/core/r_data/gldefs.cpp index 3332d41e4..727e47380 100644 --- a/source/core/r_data/gldefs.cpp +++ b/source/core/r_data/gldefs.cpp @@ -42,13 +42,14 @@ #include "stats.h" #include "v_text.h" //#include "g_levellocals.h" -//#include "a_dynlight.h" +#include "a_dynlight.h" #include "v_video.h" #include "skyboxtexture.h" #include "hwrenderer/postprocessing/hw_postprocessshader.h" #include "hw_material.h" #include "texturemanager.h" +#if 0 void AddLightDefaults(FLightDefaults *defaults, double attnFactor); void AddLightAssociation(const char *actor, const char *frame, const char *light); void InitializeActorLights(TArray &LightAssociations); @@ -56,6 +57,7 @@ void ParseColorization(FScanner& sc); extern TDeletingArray LightDefaults; extern int AttenuationIsSet; +#endif //----------------------------------------------------------------------------- @@ -63,7 +65,7 @@ extern int AttenuationIsSet; // ParseVavoomSkybox // //----------------------------------------------------------------------------- - +#if 0 static void ParseVavoomSkybox() { int lump = fileSystem.CheckNumForName("SKYBOXES"); @@ -112,7 +114,7 @@ static void ParseVavoomSkybox() } } } - +#endif //========================================================================== @@ -292,7 +294,7 @@ class GLDefsParser // The semantics of this are too horrible to comprehend (default detail texture???) // so if this ever gets done, the parser will look different. //========================================================================== - +#if 0 void ParseDetailTexture() { while (!sc.CheckToken('}')) @@ -331,7 +333,7 @@ class GLDefsParser } } } - +#endif //========================================================================== // @@ -374,7 +376,7 @@ class GLDefsParser // // //----------------------------------------------------------------------------- - +#if 0 void AddLightAssociation(const char *actor, const char *frame, const char *light) { FLightAssociation *temp; @@ -396,13 +398,13 @@ class GLDefsParser LightAssociations.Push(assoc); } - +#endif //----------------------------------------------------------------------------- // // Note: The different light type parsers really could use some consolidation... // //----------------------------------------------------------------------------- - +#if 0 void ParsePointLight() { int type; @@ -480,20 +482,22 @@ class GLDefsParser sc.ScriptError("Unknown tag: %s\n", sc.String); } } +#if 0 AddLightDefaults(defaults, lightSizeFactor); +#endif } else { sc.ScriptError("Expected '{'.\n"); } } - +#endif //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- - +#if 0 void ParsePulseLight() { int type; @@ -585,14 +589,14 @@ class GLDefsParser sc.ScriptError("Expected '{'.\n"); } } - +#endif //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- - +#if 0 void ParseFlickerLight() { int type; @@ -683,14 +687,14 @@ class GLDefsParser sc.ScriptError("Expected '{'.\n"); } } - +#endif //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- - +#if 0 void ParseFlickerLight2() { int type; @@ -786,14 +790,14 @@ class GLDefsParser sc.ScriptError("Expected '{'.\n"); } } - +#endif //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- - +#if 0 void ParseSectorLight() { int type; @@ -875,13 +879,13 @@ class GLDefsParser sc.ScriptError("Expected '{'.\n"); } } - +#endif //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- - +#if 0 void ParseFrame(const FString &name) { int type, startDepth; @@ -929,13 +933,13 @@ class GLDefsParser sc.ScriptError("Expected '{'.\n"); } } - +#endif //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- - +#if 0 void ParseObject() { int type; @@ -977,14 +981,14 @@ class GLDefsParser sc.ScriptError("Expected '{'.\n"); } } - +#endif //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- - +#if 0 void ParseGldefSkybox() { int facecount=0; @@ -1014,13 +1018,13 @@ class GLDefsParser sb->SetSize(); TexMan.AddGameTexture(MakeGameTexture(sb, s, ETextureType::Override)); } - +#endif //=========================================================================== // // Reads glow definitions from GLDEFS // //=========================================================================== - +#if 0 void ParseGlow() { sc.MustGetStringName("{"); @@ -1081,14 +1085,14 @@ class GLDefsParser } } } - +#endif //========================================================================== // // Parses a brightmap definition // //========================================================================== - +#if 0 void ParseBrightmap() { ETextureType type = ETextureType::Any; @@ -1166,7 +1170,8 @@ class GLDefsParser } tex->SetDisableFullbright(disable_fullbright); } - +#endif +#if 0 void SetShaderIndex(FGameTexture *tex, unsigned index) { auto desc = usershaders[index - FIRST_USER_SHADER]; @@ -1176,13 +1181,13 @@ class GLDefsParser } tex->SetShaderIndex(index); } - +#endif //========================================================================== // // Parses a material definition // //========================================================================== - +#if 0 void ParseMaterial() { ETextureType type = ETextureType::Any; @@ -1407,7 +1412,7 @@ class GLDefsParser } tex->SetShaderLayers(mlay); } - +#endif //========================================================================== // @@ -1501,6 +1506,7 @@ class GLDefsParser } else { +#if 0 // not ready for this yet ETextureType type = ETextureType::Any; if (sc.Compare("texture")) type = ETextureType::Wall; @@ -1650,9 +1656,10 @@ class GLDefsParser SetShaderIndex(tex, usershaders.Push(desc) + FIRST_USER_SHADER); } tex->SetShaderLayers(mlay); +#endif } } - +#if 0 void ParseColorization(FScanner& sc) { TextureManipulation tm = {}; @@ -1714,7 +1721,7 @@ class GLDefsParser TexMan.RemoveTextureManipulation(cname); } } - +#endif public: //========================================================================== @@ -1751,6 +1758,7 @@ public: newscanner.DoParseDefs(); break; } +#if 0 case LIGHT_POINT: ParsePointLight(); break; @@ -1772,11 +1780,13 @@ public: case LIGHT_CLEAR: // This has been intentionally removed break; +#endif case TAG_SHADER: ParseShader(); break; case TAG_CLEARSHADERS: break; +#if 0 case TAG_SKYBOX: ParseGldefSkybox(); break; @@ -1810,6 +1820,7 @@ public: case TAG_COLORIZATION: ParseColorization(sc); break; +#endif default: sc.ScriptError("Error parsing defs. Unknown tag: %s.\n", sc.String); break; @@ -1841,7 +1852,9 @@ void LoadGLDefs(const char *defsLump) GLDefsParser sc(workingLump, LightAssociations); sc.DoParseDefs(); } +#if 0 InitializeActorLights(LightAssociations); +#endif } @@ -1855,9 +1868,13 @@ void ParseGLDefs() { const char *defsLump = NULL; +#if 0 LightDefaults.DeleteAndClear(); AttenuationIsSet = -1; +#endif //gl_DestroyUserShaders(); function says 'todo' +#if 0 + // should we really use a system like this anymore with the advent of filter folders? switch (gameinfo.gametype) { case GAME_Heretic: @@ -1878,6 +1895,9 @@ void ParseGLDefs() default: // silence GCC break; } +#endif +#if 0 ParseVavoomSkybox(); +#endif LoadGLDefs(defsLump); }