diff --git a/include/ishaders.h b/include/ishaders.h
index a543442d3b..309f2ff896 100644
--- a/include/ishaders.h
+++ b/include/ishaders.h
@@ -341,14 +341,19 @@ class Material
// will immediately mark this Material as modified.
virtual IEditableShaderLayer::Ptr getEditableLayer(std::size_t index) = 0;
- /// Return the 2D light falloff texture, if this is a light shader
+ /// Return the light falloff texture, if this is a light shader
virtual TexturePtr lightFalloffImage() = 0;
- // Return the expression of the light falloff texture for use with this shader.
+ // Return the expression of the light falloff map for use with this shader.
virtual shaders::IMapExpression::Ptr getLightFalloffExpression() = 0;
- // Return the expression of the light falloff cubemap for use with this shader.
- virtual shaders::IMapExpression::Ptr getLightFalloffCubeMapExpression() = 0;
+ // Return the type of the light fall off image
+ // (can be MapType::Map (lightFalloffImage or MapType::CameraCubeMap for lightFalloffCubeMap)
+ virtual IShaderLayer::MapType getLightFalloffCubeMapType() = 0;
+
+ // Set the type of the light fall off image
+ // (can be MapType::Map (lightFalloffImage or MapType::CameraCubeMap for lightFalloffCubeMap)
+ virtual void setLightFalloffCubeMapType(IShaderLayer::MapType type) = 0;
// greebo: Returns the description as defined in the material
virtual std::string getDescription() const = 0;
diff --git a/install/ui/materialeditor.fbp b/install/ui/materialeditor.fbp
index a314477795..b65c8a4ad4 100644
--- a/install/ui/materialeditor.fbp
+++ b/install/ui/materialeditor.fbp
@@ -4142,193 +4142,204 @@
-1
-
-
- 0
- wxALIGN_CENTER_VERTICAL|wxALL
- 0
-
- 1
- 1
- 1
- 1
-
-
-
-
-
-
-
- 1
- 0
- 1
-
- 1
- 0
- Dock
- 0
- Left
- 1
-
- 1
-
- 0
- 0
- wxID_ANY
- lightFalloffCubeMap
- 0
-
- 0
-
-
- 0
-
- 1
- m_staticText421
- 1
-
-
- protected
- 1
-
- Resizable
- 1
-
-
- ; ; forward_declare
- 0
-
-
-
-
- -1
-
-
-
+
0
- wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND
- 0
-
- 1
- 1
- 1
- 1
-
-
-
-
-
-
-
- 1
- 0
- 1
-
- 1
- 0
- Dock
- 0
- Left
- 1
-
- 1
-
- 0
- 0
- wxID_ANY
-
- 0
-
-
-
- 0
+ wxEXPAND
+ 1
+
- 1
- MaterialLightFalloffCubeMap
- 1
-
-
- protected
- 1
-
- Resizable
- 1
-
-
- ; ; forward_declare
- 0
-
-
- wxFILTER_NONE
- wxDefaultValidator
-
-
-
-
-
+ bSizer75
+ wxHORIZONTAL
+ none
+
+ 0
+ wxALIGN_CENTER_VERTICAL
+ 1
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+
+
+ 0
+
+ 1
+ MaterialLightFalloffMap
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+
+
+
+
+ 6
+ wxALIGN_CENTER_VERTICAL|wxLEFT
+ 0
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ Type:
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_staticText53
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+ 6
+ wxALIGN_CENTER_VERTICAL|wxLEFT
+ 0
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ 1
+ 0
+
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+
+ 0
+
+ 1
+ MaterialLightFalloffCubeMapType
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 0
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+
+
diff --git a/install/ui/materialeditor.xrc b/install/ui/materialeditor.xrc
index 6732d9cc40..c19ad951ad 100644
--- a/install/ui/materialeditor.xrc
+++ b/install/ui/materialeditor.xrc
@@ -668,28 +668,37 @@
-
- wxALIGN_CENTER_VERTICAL|wxEXPAND
- 0
-
-
-
-
-
-
- wxALIGN_CENTER_VERTICAL|wxALL
- 0
-
-
- -1
-
-
-
-
- wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND
+
+ wxEXPAND
0
-
-
+
+ wxHORIZONTAL
+
+
+ wxALIGN_CENTER_VERTICAL
+ 0
+
+
+
+
+
+
+ wxALIGN_CENTER_VERTICAL|wxLEFT
+ 6
+
+
+ -1
+
+
+
+
+ wxALIGN_CENTER_VERTICAL|wxLEFT
+ 6
+
+ 0
+
+
+
diff --git a/radiant/ui/materials/MaterialEditor.cpp b/radiant/ui/materials/MaterialEditor.cpp
index 47328a9579..e6bdb1064c 100644
--- a/radiant/ui/materials/MaterialEditor.cpp
+++ b/radiant/ui/materials/MaterialEditor.cpp
@@ -234,10 +234,22 @@ void MaterialEditor::setupMaterialProperties()
getControl("MaterialSpectrumValue")->Enable(ev.IsChecked());
});
+ // For light fall off images, only cameracubemap and map are allowed
+ auto lightFallOffCubeMapType = getControl("MaterialLightFalloffCubeMapType");
+ lightFallOffCubeMapType->AppendString(shaders::getStringForMapType(IShaderLayer::MapType::Map));
+ lightFallOffCubeMapType->AppendString(shaders::getStringForMapType(IShaderLayer::MapType::CameraCubeMap));
+
+ lightFallOffCubeMapType->Bind(wxEVT_CHOICE, [this, lightFallOffCubeMapType] (wxCommandEvent& ev)
+ {
+ if (_materialUpdateInProgress || !_material) return;
+ _material->setLightFalloffCubeMapType(shaders::getMapTypeForString(lightFallOffCubeMapType->GetStringSelection().ToStdString()));
+ });
+
_materialBindings.emplace(std::make_shared>(getControl("MaterialSpectrumValue"),
[](const MaterialPtr& material) { return material->getSpectrum(); },
[this](const MaterialPtr& material, const int& value)
{
+ if (_materialUpdateInProgress || !_material) return;
material->setSpectrum(value);
},
[this]() { onMaterialChanged(); }));
@@ -1090,8 +1102,8 @@ void MaterialEditor::updateMaterialPropertiesFromMaterial()
auto lightFalloffMap = _material->getLightFalloffExpression();
getControl("MaterialLightFalloffMap")->SetValue(lightFalloffMap ? lightFalloffMap->getExpressionString() : "");
- auto lightFalloffCubeMap = _material->getLightFalloffCubeMapExpression();
- getControl("MaterialLightFalloffCubeMap")->SetValue(lightFalloffCubeMap ? lightFalloffCubeMap->getExpressionString() : "");
+ auto lightFalloffCubeMapType = _material->getLightFalloffCubeMapType();
+ getControl("MaterialLightFalloffCubeMapType")->SetStringSelection(shaders::getStringForMapType(lightFalloffCubeMapType));
// Spectrum
bool hasSpectrum = (_material->getParseFlags() & Material::PF_HasSpectrum) != 0 || _material->getSpectrum() != 0;
diff --git a/radiantcore/shaders/CShader.cpp b/radiantcore/shaders/CShader.cpp
index d170bf8e5e..9cbe1674c8 100644
--- a/radiantcore/shaders/CShader.cpp
+++ b/radiantcore/shaders/CShader.cpp
@@ -81,9 +81,15 @@ IMapExpression::Ptr CShader::getLightFalloffExpression()
return _template->getLightFalloff();
}
-IMapExpression::Ptr CShader::getLightFalloffCubeMapExpression()
+IShaderLayer::MapType CShader::getLightFalloffCubeMapType()
{
- return _template->getLightFalloffCubeMap();
+ return _template->getLightFalloffCubeMapType();
+}
+
+void CShader::setLightFalloffCubeMapType(IShaderLayer::MapType type)
+{
+ ensureTemplateCopy();
+ _template->setLightFalloffCubeMapType(type);
}
/*
diff --git a/radiantcore/shaders/CShader.h b/radiantcore/shaders/CShader.h
index 791fc5ac79..1c6a93b27d 100644
--- a/radiantcore/shaders/CShader.h
+++ b/radiantcore/shaders/CShader.h
@@ -102,7 +102,8 @@ class CShader final :
IEditableShaderLayer::Ptr getEditableLayer(std::size_t index) override;
IMapExpression::Ptr getLightFalloffExpression() override;
- IMapExpression::Ptr getLightFalloffCubeMapExpression() override;
+ IShaderLayer::MapType getLightFalloffCubeMapType() override;
+ void setLightFalloffCubeMapType(IShaderLayer::MapType type) override;
std::string getRenderBumpArguments() override;
std::string getRenderBumpFlatArguments() override;
diff --git a/radiantcore/shaders/ShaderTemplate.cpp b/radiantcore/shaders/ShaderTemplate.cpp
index 7dde943da7..a7cea96985 100644
--- a/radiantcore/shaders/ShaderTemplate.cpp
+++ b/radiantcore/shaders/ShaderTemplate.cpp
@@ -26,7 +26,7 @@ ShaderTemplate::ShaderTemplate(const ShaderTemplate& other) :
_name(other._name),
_currentLayer(new Doom3ShaderLayer(*this)),
_lightFalloff(other._lightFalloff),
- _lightFalloffCubeMap(other._lightFalloffCubeMap),
+ _lightFalloffCubeMapType(other._lightFalloffCubeMapType),
fogLight(other.fogLight),
ambientLight(other.ambientLight),
blendLight(other.blendLight),
@@ -473,11 +473,13 @@ bool ShaderTemplate::parseLightKeywords(parser::DefTokeniser& tokeniser, const s
}
else if (!fogLight && token == "lightfalloffimage")
{
+ _lightFalloffCubeMapType = IShaderLayer::MapType::Map;
_lightFalloff = MapExpression::createForToken(tokeniser);
}
else if (token == "lightfalloffcubemap")
{
- _lightFalloffCubeMap = MapExpression::createForToken(tokeniser);
+ _lightFalloffCubeMapType = IShaderLayer::MapType::CameraCubeMap;
+ _lightFalloff = MapExpression::createForToken(tokeniser);
}
else if (token == "spectrum")
{
diff --git a/radiantcore/shaders/ShaderTemplate.h b/radiantcore/shaders/ShaderTemplate.h
index d17b74f22d..fd989a5c5b 100644
--- a/radiantcore/shaders/ShaderTemplate.h
+++ b/radiantcore/shaders/ShaderTemplate.h
@@ -41,7 +41,7 @@ class ShaderTemplate final
// Map expressions
MapExpressionPtr _lightFalloff;
- MapExpressionPtr _lightFalloffCubeMap;
+ IShaderLayer::MapType _lightFalloffCubeMapType;
/* Light type booleans */
bool fogLight;
@@ -107,26 +107,27 @@ class ShaderTemplate final
* \brief
* Construct a ShaderTemplate.
*/
- ShaderTemplate(const std::string& name, const std::string& blockContents)
- : _name(name),
- _currentLayer(new Doom3ShaderLayer(*this)),
- fogLight(false),
- ambientLight(false),
- blendLight(false),
- _cubicLight(false),
- _materialFlags(0),
- _cullType(Material::CULL_BACK),
- _clampType(CLAMP_REPEAT),
- _surfaceFlags(0),
- _surfaceType(Material::SURFTYPE_DEFAULT),
- _deformType(Material::DEFORM_NONE),
- _spectrum(0),
- _sortReq(SORT_UNDEFINED), // will be set to default values after the shader has been parsed
- _polygonOffset(0.0f),
- _coverage(Material::MC_UNDETERMINED),
- _blockContents(blockContents),
- _parsed(false),
- _parseFlags(0)
+ ShaderTemplate(const std::string& name, const std::string& blockContents) :
+ _name(name),
+ _currentLayer(new Doom3ShaderLayer(*this)),
+ _lightFalloffCubeMapType(IShaderLayer::MapType::Map),
+ fogLight(false),
+ ambientLight(false),
+ blendLight(false),
+ _cubicLight(false),
+ _materialFlags(0),
+ _cullType(Material::CULL_BACK),
+ _clampType(CLAMP_REPEAT),
+ _surfaceFlags(0),
+ _surfaceType(Material::SURFTYPE_DEFAULT),
+ _deformType(Material::DEFORM_NONE),
+ _spectrum(0),
+ _sortReq(SORT_UNDEFINED), // will be set to default values after the shader has been parsed
+ _polygonOffset(0.0f),
+ _coverage(Material::MC_UNDETERMINED),
+ _blockContents(blockContents),
+ _parsed(false),
+ _parseFlags(0)
{
_decalInfo.stayMilliSeconds = 0;
_decalInfo.fadeMilliSeconds = 0;
@@ -330,11 +331,17 @@ class ShaderTemplate final
return _lightFalloff;
}
- const MapExpressionPtr& getLightFalloffCubeMap()
- {
- if (!_parsed) parseDefinition();
- return _lightFalloffCubeMap;
- }
+ IShaderLayer::MapType getLightFalloffCubeMapType()
+ {
+ if (!_parsed) parseDefinition();
+ return _lightFalloffCubeMapType;
+ }
+
+ void setLightFalloffCubeMapType(IShaderLayer::MapType type)
+ {
+ if (!_parsed) parseDefinition();
+ _lightFalloffCubeMapType = type;
+ }
std::size_t addLayer(IShaderLayer::Type type);
void removeLayer(std::size_t index);
diff --git a/test/Materials.cpp b/test/Materials.cpp
index c154b9b316..38cad8363a 100644
--- a/test/Materials.cpp
+++ b/test/Materials.cpp
@@ -787,4 +787,23 @@ TEST_F(MaterialsTest, MaterialParserRgbaExpressions)
EXPECT_EQ(diffuse->getColourExpression(IShaderLayer::COMP_ALPHA)->getExpressionString(), "time * 7.0");
}
+TEST_F(MaterialsTest, MaterialParserLightfallOff)
+{
+ auto material = GlobalMaterialManager().getMaterial("textures/parsertest/lights/lightfalloff1");
+
+ EXPECT_EQ(material->getLightFalloffCubeMapType(), IShaderLayer::MapType::Map);
+ EXPECT_EQ(material->getLightFalloffExpression()->getExpressionString(), "makeIntensity(lights/squarelight1a.tga)");
+
+ material = GlobalMaterialManager().getMaterial("textures/parsertest/lights/lightfalloff2");
+
+ EXPECT_EQ(material->getLightFalloffCubeMapType(), IShaderLayer::MapType::CameraCubeMap);
+ EXPECT_EQ(material->getLightFalloffExpression()->getExpressionString(), "lights/squarelight1a");
+
+ material = GlobalMaterialManager().getMaterial("textures/parsertest/lights/lightfalloff3");
+
+ // Second lightFallOff declaration overrides the first one in the material
+ EXPECT_EQ(material->getLightFalloffCubeMapType(), IShaderLayer::MapType::CameraCubeMap);
+ EXPECT_EQ(material->getLightFalloffExpression()->getExpressionString(), "lights/squarelight1a");
+}
+
}
diff --git a/test/resources/tdm/materials/parsertest.mtr b/test/resources/tdm/materials/parsertest.mtr
index ce77270668..973389994e 100644
--- a/test/resources/tdm/materials/parsertest.mtr
+++ b/test/resources/tdm/materials/parsertest.mtr
@@ -450,3 +450,41 @@ textures/parsertest/colourexpr10
alpha time*7
}
}
+
+textures/parsertest/lights/lightfalloff1
+{
+ lightFalloffImage makeintensity( lights/squarelight1a.tga )
+ spectrum 2
+ {
+ forceHighQuality
+ map lights/fullambient.tga
+ colored
+ zeroClamp
+ }
+}
+
+textures/parsertest/lights/lightfalloff2
+{
+ lightFalloffCubeMap lights/squarelight1a
+ spectrum 2
+ {
+ forceHighQuality
+ map lights/fullambient.tga
+ colored
+ zeroClamp
+ }
+}
+
+
+textures/parsertest/lights/lightfalloff3
+{
+ lightFalloffImage makeintensity( lights/squarelight1a.tga )
+ lightFalloffCubeMap lights/squarelight1a
+ spectrum 2
+ {
+ forceHighQuality
+ map lights/fullambient.tga
+ colored
+ zeroClamp
+ }
+}