diff --git a/src/playsim/a_dynlight.cpp b/src/playsim/a_dynlight.cpp index c8982528b..4025abfb7 100644 --- a/src/playsim/a_dynlight.cpp +++ b/src/playsim/a_dynlight.cpp @@ -113,6 +113,7 @@ void AttachLight(AActor *self) light->pSpotInnerAngle = &self->AngleVar(NAME_SpotInnerAngle); light->pSpotOuterAngle = &self->AngleVar(NAME_SpotOuterAngle); + light->lightDefIntensity = 1.0; light->pPitch = &self->Angles.Pitch; light->pLightFlags = (LightFlags*)&self->IntVar(NAME_lightflags); light->pArgs = self->args; @@ -863,7 +864,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_AttachLightDef, AttachLightDef) // //========================================================================== -int AttachLightDirect(AActor *self, int _lightid, int type, int color, int radius1, int radius2, int flags, double ofs_x, double ofs_y, double ofs_z, double param, double spoti, double spoto, double spotp) +int AttachLightDirect(AActor *self, int _lightid, int type, int color, int radius1, int radius2, int flags, double ofs_x, double ofs_y, double ofs_z, double param, double spoti, double spoto, double spotp, double intensity) { FName lightid = FName(ENamedName(_lightid)); auto userlight = self->UserLights[FindUserLight(self, lightid, true)]; @@ -879,6 +880,7 @@ int AttachLightDirect(AActor *self, int _lightid, int type, int color, int radiu userlight->SetParameter(type == PulseLight? param*TICRATE : param*360.); userlight->SetSpotInnerAngle(spoti); userlight->SetSpotOuterAngle(spoto); + userlight->SetLightDefIntensity(intensity); if (spotp >= -90. && spotp <= 90.) { userlight->SetSpotPitch(spotp); @@ -908,7 +910,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_AttachLight, AttachLightDirect) PARAM_FLOAT(spoti); PARAM_FLOAT(spoto); PARAM_FLOAT(spotp); - ACTION_RETURN_BOOL(AttachLightDirect(self, lightid.GetIndex(), type, color, radius1, radius2, flags, ofs_x, ofs_y, ofs_z, parami, spoti, spoto, spotp)); + PARAM_FLOAT(intensity); + ACTION_RETURN_BOOL(AttachLightDirect(self, lightid.GetIndex(), type, color, radius1, radius2, flags, ofs_x, ofs_y, ofs_z, parami, spoti, spoto, spotp, intensity)); } //========================================================================== diff --git a/src/playsim/a_dynlight.h b/src/playsim/a_dynlight.h index 5424a4a53..2f8bea462 100644 --- a/src/playsim/a_dynlight.h +++ b/src/playsim/a_dynlight.h @@ -77,6 +77,7 @@ public: void SetDontLightOthers(bool on) { if (on) m_lightFlags |= LF_DONTLIGHTOTHERS; else m_lightFlags &= ~LF_DONTLIGHTOTHERS; } void SetDontLightMap(bool on) { if (on) m_lightFlags |= LF_DONTLIGHTMAP; else m_lightFlags &= ~LF_DONTLIGHTMAP; } void SetNoShadowmap(bool on) { if (on) m_lightFlags |= LF_NOSHADOWMAP; else m_lightFlags &= ~LF_NOSHADOWMAP; } + void SetLightDefIntensity(double i) { m_LightDefIntensity = i; } void SetSpot(bool spot) { if (spot) m_lightFlags |= LF_SPOT; else m_lightFlags &= ~LF_SPOT; } void SetSpotInnerAngle(double angle) { m_spotInnerAngle = DAngle::fromDeg(angle); } void SetSpotOuterAngle(double angle) { m_spotOuterAngle = DAngle::fromDeg(angle); } @@ -128,6 +129,7 @@ protected: DAngle m_spotInnerAngle = DAngle::fromDeg(10.0); DAngle m_spotOuterAngle = DAngle::fromDeg(25.0); DAngle m_pitch = nullAngle; + double m_LightDefIntensity = 1.0; // Light over/underbright multiplication for GLDEFS-defined lights friend FSerializer &Serialize(FSerializer &arc, const char *key, FLightDefaults &value, FLightDefaults *def); }; @@ -231,6 +233,7 @@ struct FDynamicLight int GetBlue() const { return pArgs[LIGHT_BLUE]; } int GetIntensity() const { return pArgs[LIGHT_INTENSITY]; } int GetSecondaryIntensity() const { return pArgs[LIGHT_SECONDARY_INTENSITY]; } + double GetLightDefIntensity() const { return lightDefIntensity; } bool IsSubtractive() const { return !!((*pLightFlags) & LF_SUBTRACTIVE); } bool IsAdditive() const { return !!((*pLightFlags) & LF_ADDITIVE); } @@ -293,6 +296,8 @@ public: bool swapped; bool explicitpitch; + double lightDefIntensity; + FDynamicLightTouchLists touchlists; }; diff --git a/src/r_data/a_dynlightdata.cpp b/src/r_data/a_dynlightdata.cpp index c20c8d2e9..081eb1089 100644 --- a/src/r_data/a_dynlightdata.cpp +++ b/src/r_data/a_dynlightdata.cpp @@ -81,6 +81,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FLightDefaults &value, ("spotinner", value.m_spotInnerAngle) ("spotouter", value.m_spotOuterAngle) ("pitch", value.m_pitch) + ("lightdefintensity", value.m_LightDefIntensity) .EndObject(); } return arc; @@ -125,6 +126,7 @@ void FLightDefaults::ApplyProperties(FDynamicLight * light) const light->m_active = true; light->lighttype = m_type; light->specialf1 = m_Param; + light->lightDefIntensity = m_LightDefIntensity; light->pArgs = m_Args; light->pLightFlags = &m_lightFlags; if (m_lightFlags & LF_SPOT) diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 6bdb4f2d5..4b6812d69 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -200,6 +200,7 @@ static const char *LightTags[]= "noshadowmap", "dontlightothers", "dontlightmap", + "intensity", nullptr }; @@ -226,6 +227,7 @@ enum { LIGHTTAG_NOSHADOWMAP, LIGHTTAG_DONTLIGHTOTHERS, LIGHTTAG_DONTLIGHTMAP, + LIGHTTAG_INTENSITY, }; //========================================================================== @@ -541,6 +543,9 @@ class GLDefsParser defaults->SetSpotOuterAngle(outerAngle); } break; + case LIGHTTAG_INTENSITY: + defaults->SetLightDefIntensity(ParseFloat(sc)); + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -643,6 +648,9 @@ class GLDefsParser defaults->SetSpotOuterAngle(outerAngle); } break; + case LIGHTTAG_INTENSITY: + defaults->SetLightDefIntensity(ParseFloat(sc)); + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -748,6 +756,9 @@ class GLDefsParser defaults->SetSpotOuterAngle(outerAngle); } break; + case LIGHTTAG_INTENSITY: + defaults->SetLightDefIntensity(ParseFloat(sc)); + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -852,6 +863,9 @@ class GLDefsParser defaults->SetSpotOuterAngle(outerAngle); } break; + case LIGHTTAG_INTENSITY: + defaults->SetLightDefIntensity(ParseFloat(sc)); + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -953,6 +967,9 @@ class GLDefsParser defaults->SetSpotOuterAngle(outerAngle); } break; + case LIGHTTAG_INTENSITY: + defaults->SetLightDefIntensity(ParseFloat(sc)); + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } diff --git a/src/rendering/hwrenderer/hw_dynlightdata.cpp b/src/rendering/hwrenderer/hw_dynlightdata.cpp index bf516e637..1bb7ec33a 100644 --- a/src/rendering/hwrenderer/hw_dynlightdata.cpp +++ b/src/rendering/hwrenderer/hw_dynlightdata.cpp @@ -95,6 +95,9 @@ void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool f if (light->target && (light->target->renderflags2 & RF2_LIGHTMULTALPHA)) cs *= (float)light->target->Alpha; + // Multiply intensity from GLDEFS + cs *= (float)light->GetLightDefIntensity(); + float r = light->GetRed() / 255.0f * cs; float g = light->GetGreen() / 255.0f * cs; float b = light->GetBlue() / 255.0f * cs; diff --git a/src/rendering/hwrenderer/scene/hw_spritelight.cpp b/src/rendering/hwrenderer/scene/hw_spritelight.cpp index ad2c59d7f..d3b164ba0 100644 --- a/src/rendering/hwrenderer/scene/hw_spritelight.cpp +++ b/src/rendering/hwrenderer/scene/hw_spritelight.cpp @@ -194,6 +194,11 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FSec lb *= alpha; } + // Get GLDEFS intensity + lr *= light->GetLightDefIntensity(); + lg *= light->GetLightDefIntensity(); + lb *= light->GetLightDefIntensity(); + if (light->IsSubtractive()) { float bright = (float)FVector3(lr, lg, lb).Length(); diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 4ce112424..aae41c81b 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -1356,7 +1356,7 @@ class Actor : Thinker native action native void A_OverlayTranslation(int layer, name trname); native bool A_AttachLightDef(Name lightid, Name lightdef); - native bool A_AttachLight(Name lightid, int type, Color lightcolor, int radius1, int radius2, int flags = 0, Vector3 ofs = (0,0,0), double param = 0, double spoti = 10, double spoto = 25, double spotp = 0); + native bool A_AttachLight(Name lightid, int type, Color lightcolor, int radius1, int radius2, int flags = 0, Vector3 ofs = (0,0,0), double param = 0, double spoti = 10, double spoto = 25, double spotp = 0, double intensity = 1.0); native bool A_RemoveLight(Name lightid); //================================================