diff --git a/libs/registry/CachedKey.h b/libs/registry/CachedKey.h index fe849b4a4a..3b361a7af3 100644 --- a/libs/registry/CachedKey.h +++ b/libs/registry/CachedKey.h @@ -6,8 +6,7 @@ namespace registry { /** - * \brief - * Simple value caching class for a registry key. + * \brief Simple value caching class for a registry key. * * This can be used when a registry key needs to be read frequently but only * written rarely. It stores a copy of the value converted to its given type, diff --git a/radiantcore/entity/light/LightNode.cpp b/radiantcore/entity/light/LightNode.cpp index d0e2082630..c554eb7a72 100644 --- a/radiantcore/entity/light/LightNode.cpp +++ b/radiantcore/entity/light/LightNode.cpp @@ -26,7 +26,8 @@ LightNode::LightNode(const IEntityClassPtr& eclass) : _lightEndInstance(_light.endTransformed(), std::bind(&LightNode::selectedChangedComponent, this, std::placeholders::_1)), _dragPlanes(std::bind(&LightNode::selectedChangedComponent, this, std::placeholders::_1)), _renderableRadius(_light._lightBox.origin), - _renderableFrustum(_light._lightBox.origin, _light._lightStartTransformed, _light._frustum) + _renderableFrustum(_light._lightBox.origin, _light._lightStartTransformed, _light._frustum), + _overrideColKey(colours::RKEY_OVERRIDE_LIGHTCOL) {} LightNode::LightNode(const LightNode& other) : @@ -46,7 +47,8 @@ LightNode::LightNode(const LightNode& other) : _lightEndInstance(_light.endTransformed(), std::bind(&LightNode::selectedChangedComponent, this,std::placeholders:: _1)), _dragPlanes(std::bind(&LightNode::selectedChangedComponent, this, std::placeholders::_1)), _renderableRadius(_light._lightBox.origin), - _renderableFrustum(_light._lightBox.origin, _light._lightStartTransformed, _light._frustum) + _renderableFrustum(_light._lightBox.origin, _light._lightStartTransformed, _light._frustum), + _overrideColKey(colours::RKEY_OVERRIDE_LIGHTCOL) {} LightNodePtr LightNode::Create(const IEntityClassPtr& eclass) @@ -303,9 +305,6 @@ void LightNode::renderLightVolume(RenderableCollector& collector, bool selected) const { // Obtain the appropriate Shader for the light volume colour - static registry::CachedKey _overrideColKey( - colours::RKEY_OVERRIDE_LIGHTCOL - ); Shader* colourShader = _overrideColKey.get() ? EntityNode::_wireShader.get() : _colourKey.getWireShader(); if (!colourShader) diff --git a/radiantcore/entity/light/LightNode.h b/radiantcore/entity/light/LightNode.h index 08ac3b4a28..d4d2f6d37f 100644 --- a/radiantcore/entity/light/LightNode.h +++ b/radiantcore/entity/light/LightNode.h @@ -1,6 +1,7 @@ #pragma once #include "ilightnode.h" +#include "registry/CachedKey.h" #include "Light.h" #include "dragplanes.h" @@ -45,6 +46,9 @@ class LightNode : // a temporary variable for calculating the AABB of all (selected) components mutable AABB m_aabb_component; + // Cached rkey to override light volume colour + registry::CachedKey _overrideColKey; + public: LightNode(const IEntityClassPtr& eclass); diff --git a/test/Entity.cpp b/test/Entity.cpp index 253e53ca33..a49a44fe4b 100644 --- a/test/Entity.cpp +++ b/test/Entity.cpp @@ -6,10 +6,12 @@ #include "iselectable.h" #include "iselection.h" #include "ishaders.h" +#include "icolourscheme.h" #include "render/NopVolumeTest.h" #include "string/convert.h" #include "transformlib.h" +#include "registry/registry.h" namespace test { @@ -465,6 +467,46 @@ TEST_F(EntityTest, LightVolumeColorFromColorKey) } } +TEST_F(EntityTest, OverrideLightVolumeColour) +{ + // Create a light with an arbitrary colour + auto light = createByClassName("light"); + light->getEntity().setKeyValue("_color", "0.25 0.55 0.9"); + + // Set the "override light volume colour" key + registry::setValue(colours::RKEY_OVERRIDE_LIGHTCOL, true); + + { + RenderFixture rf; + rf.renderSubGraph(light); + + // The shader should ignore the _color key and render based on the entity + // class colour + EXPECT_EQ(rf.collector.renderables, 1); + const Shader* shader = rf.collector.renderablePtrs.at(0).first; + EXPECT_EQ(shader->getMaterial()->getName(), "<0.000000 1.000000 0.000000>"); + } + + // Unset the override key + registry::setValue(colours::RKEY_OVERRIDE_LIGHTCOL, false); + + { + RenderFixture rf; + rf.renderSubGraph(light); + + // Light should be rendered with its original _color key again + EXPECT_EQ(rf.collector.renderables, 1); + const Shader* shader = rf.collector.renderablePtrs.at(0).first; + EXPECT_EQ(shader->getMaterial()->getName(), "<0.250000 0.550000 0.900000>"); + } + + // Changing the override key after deleting the light must not crash + // (because the LightNode's CachedKey is sigc::trackable) + light.reset(); + registry::setValue(colours::RKEY_OVERRIDE_LIGHTCOL, true); + registry::setValue(colours::RKEY_OVERRIDE_LIGHTCOL, false); +} + TEST_F(EntityTest, FuncStaticLocalToWorld) { auto funcStatic = createByClassName("func_static");