diff --git a/include/ShaderLayer.h b/include/ShaderLayer.h index 0adad905e3..72e435f062 100644 --- a/include/ShaderLayer.h +++ b/include/ShaderLayer.h @@ -153,6 +153,9 @@ class ShaderLayer */ virtual float getTexGenParam(std::size_t index) const = 0; + // The expressions used to calcualte the tex gen params. Index in [0..2] + virtual shaders::IShaderExpressionPtr getTexGenExpression(std::size_t index) const = 0; + /** * \brief * Return the GL blend function for this layer. diff --git a/radiant/ui/materials/MaterialEditor.cpp b/radiant/ui/materials/MaterialEditor.cpp index efe48d8dfb..73d29e27f4 100644 --- a/radiant/ui/materials/MaterialEditor.cpp +++ b/radiant/ui/materials/MaterialEditor.cpp @@ -871,6 +871,14 @@ void MaterialEditor::updateStageControls() { getControl("MaterialStageWobblySkyPanel")->Show(); + auto wobbleSkyX = selectedStage->getTexGenExpression(0); + getControl("MaterialStageWobbleSkyX")->SetValue(wobbleSkyX ? wobbleSkyX->getExpressionString() : ""); + + auto wobbleSkyY = selectedStage->getTexGenExpression(1); + getControl("MaterialStageWobbleSkyY")->SetValue(wobbleSkyY ? wobbleSkyY->getExpressionString() : ""); + + auto wobbleSkyZ = selectedStage->getTexGenExpression(2); + getControl("MaterialStageWobbleSkyZ")->SetValue(wobbleSkyZ ? wobbleSkyZ->getExpressionString() : ""); } else { diff --git a/radiantcore/shaders/Doom3ShaderLayer.cpp b/radiantcore/shaders/Doom3ShaderLayer.cpp index 51db807bd4..c28a2ec988 100644 --- a/radiantcore/shaders/Doom3ShaderLayer.cpp +++ b/radiantcore/shaders/Doom3ShaderLayer.cpp @@ -119,7 +119,7 @@ Doom3ShaderLayer::Doom3ShaderLayer(ShaderTemplate& material, ShaderLayer::Type t _shear[0] = REG_ZERO; _shear[1] = REG_ZERO; - _texGenParams[0] = _texGenParams[1] = _texGenParams[2] = 0; + _texGenParams[0] = _texGenParams[1] = _texGenParams[2] = REG_ZERO; } TexturePtr Doom3ShaderLayer::getTexture() const diff --git a/radiantcore/shaders/Doom3ShaderLayer.h b/radiantcore/shaders/Doom3ShaderLayer.h index 7097f0c514..eec04a752c 100644 --- a/radiantcore/shaders/Doom3ShaderLayer.h +++ b/radiantcore/shaders/Doom3ShaderLayer.h @@ -85,7 +85,8 @@ class Doom3ShaderLayer // texgen normal, reflect, skybox, wobblesky TexGenType _texGenType; - float _texGenParams[3]; // 3 parameters for wobblesky texgen + std::size_t _texGenParams[3]; // 3 registers for wobblesky texgen + IShaderExpressionPtr _texGenExpressions[3]; // the 3 expressions // The register indices of this stage's scale expressions std::size_t _scale[2]; @@ -158,17 +159,17 @@ class Doom3ShaderLayer void evaluateExpressions(std::size_t time) { - for (Expressions::iterator i = _expressions.begin(); i != _expressions.end(); ++i) + for (const auto& i : _expressions) { - (*i)->evaluate(time); + i->evaluate(time); } } void evaluateExpressions(std::size_t time, const IRenderEntity& entity) { - for (Expressions::iterator i = _expressions.begin(); i != _expressions.end(); ++i) + for (const auto& i : _expressions) { - (*i)->evaluate(time, entity); + i->evaluate(time, entity); } } @@ -248,16 +249,26 @@ class Doom3ShaderLayer _texGenType = type; } - float getTexGenParam(std::size_t index) const + float getTexGenParam(std::size_t index) const override { assert(index < 3); - return _texGenParams[index]; + return _registers[_texGenParams[index]]; } - void setTexGenParam(std::size_t index, float value) + IShaderExpressionPtr getTexGenExpression(std::size_t index) const override { assert(index < 3); - _texGenParams[index] = value; + return _texGenExpressions[index]; + } + + void setTexGenExpression(std::size_t index, const IShaderExpressionPtr& expression) + { + assert(index < 3); + + // Store the expression in our list + _expressions.push_back(expression); + _texGenExpressions[index] = expression; + _texGenParams[index] = expression->linkToRegister(_registers); } /** diff --git a/radiantcore/shaders/ShaderTemplate.cpp b/radiantcore/shaders/ShaderTemplate.cpp index 01df2b40a8..54ecaeae76 100644 --- a/radiantcore/shaders/ShaderTemplate.cpp +++ b/radiantcore/shaders/ShaderTemplate.cpp @@ -580,13 +580,10 @@ bool ShaderTemplate::parseBlendMaps(parser::DefTokeniser& tokeniser, const std:: { _currentLayer->setTexGenType(ShaderLayer::TEXGEN_WOBBLESKY); - // Parse the 3 wobblesky parameters - // greebo: The D3 SDK says that registers could be used here (to support expressions), - // but no D3 material uses an expression for the texgen parameters - for (std::size_t i = 0; i < 3; ++i) - { - _currentLayer->setTexGenParam(i, string::convert(tokeniser.nextToken())); - } + // Parse the 3 wobblesky expressions + _currentLayer->setTexGenExpression(0, parseSingleExpressionTerm(tokeniser)); + _currentLayer->setTexGenExpression(1, parseSingleExpressionTerm(tokeniser)); + _currentLayer->setTexGenExpression(2, parseSingleExpressionTerm(tokeniser)); } } else if (token == "cubemap")