diff --git a/src/playsim/a_dynlight.cpp b/src/playsim/a_dynlight.cpp index 71dc8db7d..7be30a73b 100644 --- a/src/playsim/a_dynlight.cpp +++ b/src/playsim/a_dynlight.cpp @@ -139,6 +139,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->shadowMinQuality = std::clamp(self->IntVar(NAME_shadowMinQuality), 0, 4); @@ -1030,7 +1031,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)]; @@ -1046,6 +1047,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); @@ -1075,7 +1077,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 f580ab87d..03aeea8b4 100644 --- a/src/playsim/a_dynlight.h +++ b/src/playsim/a_dynlight.h @@ -84,6 +84,7 @@ public: { shadowMinQuality = quality; } + 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); } @@ -138,6 +139,7 @@ protected: double SoftShadowRadius = 5.0; double Linearity = 0.0; int shadowMinQuality = 1; // default medium, 0 = low, 1 = medium, 2 = high, 3 = ultra + 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); }; @@ -238,6 +240,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); } @@ -312,6 +315,8 @@ public: float lightStrength; + double lightDefIntensity; + TArray ActorList; TArray ActorResult; diff --git a/src/r_data/a_dynlightdata.cpp b/src/r_data/a_dynlightdata.cpp index 471a5e67b..24d299314 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; @@ -127,6 +128,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->pSoftShadowRadius = &SoftShadowRadius; diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 7eb88724b..b5d8a1091 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -552,6 +552,7 @@ static const char *LightTags[]= "dontlightmap", "trace", "shadowminquality", + "intensity", nullptr }; @@ -580,6 +581,7 @@ enum { LIGHTTAG_DONTLIGHTMAP, LIGHTTAG_TRACE, LIGHTTAG_SHADOW_MINQUALITY, + LIGHTTAG_INTENSITY, }; //========================================================================== @@ -903,6 +905,9 @@ class GLDefsParser defaults->SetSpotOuterAngle(outerAngle); } break; + case LIGHTTAG_INTENSITY: + defaults->SetLightDefIntensity(ParseFloat(sc)); + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -1011,6 +1016,9 @@ class GLDefsParser defaults->SetSpotOuterAngle(outerAngle); } break; + case LIGHTTAG_INTENSITY: + defaults->SetLightDefIntensity(ParseFloat(sc)); + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -1122,6 +1130,9 @@ class GLDefsParser defaults->SetSpotOuterAngle(outerAngle); } break; + case LIGHTTAG_INTENSITY: + defaults->SetLightDefIntensity(ParseFloat(sc)); + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -1232,6 +1243,9 @@ class GLDefsParser defaults->SetSpotOuterAngle(outerAngle); } break; + case LIGHTTAG_INTENSITY: + defaults->SetLightDefIntensity(ParseFloat(sc)); + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -1339,6 +1353,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 b4eb326ed..d1bdd0e1b 100644 --- a/src/rendering/hwrenderer/hw_dynlightdata.cpp +++ b/src/rendering/hwrenderer/hw_dynlightdata.cpp @@ -101,6 +101,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(); + info.r = light->GetRed() / 255.0f * cs; info.g = light->GetGreen() / 255.0f * cs; info.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 523a14f63..48394d7db 100644 --- a/src/rendering/hwrenderer/scene/hw_spritelight.cpp +++ b/src/rendering/hwrenderer/scene/hw_spritelight.cpp @@ -225,6 +225,11 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache, 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 48588bcb6..50f8a8118 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -1322,7 +1322,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); //================================================