Skip to content

Commit

Permalink
#5532: Introduce an extended IEditableShaderLayer interface.
Browse files Browse the repository at this point in the history
Just returning a const IShaderLayer reference for non-edit scenarios turns out to be impractical, since the render passes need to evaluate time-dependent expressions and update the stage's registers, requiring non-const access to the stages. The Material itself needs to know when it's being modified, so I went for intruducing a separate Material::getEditableLayer() method that is taking care of the backup clone as soon as it's called. This way it's possible to inspect and render a material without implicitly marking it as modified.
  • Loading branch information
codereader committed Mar 13, 2021
1 parent c9d942b commit d24d64f
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 6 deletions.
15 changes: 12 additions & 3 deletions include/ishaderlayer.h
Expand Up @@ -365,9 +365,6 @@ class IShaderLayer
// The map expression used to generate/define the texture of this stage
virtual shaders::IMapExpression::Ptr getMapExpression() const = 0;

// Update the "map" expression of this stage
virtual void setMapExpressionFromString(const std::string& expression) = 0;

// Parser information, to reconstruct the use of certain keywords
virtual int getParseFlags() const = 0;
};
Expand All @@ -378,3 +375,15 @@ class IShaderLayer
*/
typedef std::vector<IShaderLayer::Ptr> IShaderLayerVector;

// Interface extension to IShaderLayer, offering editing functions
class IEditableShaderLayer :
public IShaderLayer
{
public:
using Ptr = std::shared_ptr<IEditableShaderLayer>;

virtual ~IEditableShaderLayer() {}

// Update the "map" expression of this stage
virtual void setMapExpressionFromString(const std::string& expression) = 0;
};
4 changes: 4 additions & 0 deletions include/ishaders.h
Expand Up @@ -319,6 +319,10 @@ class Material
*/
virtual const IShaderLayerVector& getAllLayers() const = 0;

// Returns the edit interface for the given shader layer. Calling this method
// will immediately mark this Material as modified.
virtual const IEditableShaderLayer::Ptr& getEditableLayer(std::size_t index) = 0;

/// Return the 2D light falloff texture, if this is a light shader
virtual TexturePtr lightFalloffImage() = 0;

Expand Down
13 changes: 11 additions & 2 deletions radiantcore/shaders/CShader.cpp
Expand Up @@ -297,18 +297,27 @@ IShaderLayer* CShader::firstLayer() const
{
if (_layers.empty())
{
return NULL;
return nullptr;
}

return _layers.front().get();
}

// Get all layers
const IShaderLayerVector& CShader::getAllLayers() const
{
return _layers;
}

const IEditableShaderLayer::Ptr& CShader::getEditableLayer(std::size_t index)
{
ensureTemplateCopy();

const auto& layers = _template->getLayers();
assert(index >= 0 && index < layers.size());

return layers[index];
}

/* Required Material light type predicates */

bool CShader::isAmbientLight() const {
Expand Down
1 change: 1 addition & 0 deletions radiantcore/shaders/CShader.h
Expand Up @@ -93,6 +93,7 @@ class CShader final :
bool isVisible() const override;
void setVisible(bool visible) override;
const IShaderLayerVector& getAllLayers() const;
const IEditableShaderLayer::Ptr& getEditableLayer(std::size_t index) override;

IMapExpression::Ptr getLightFalloffExpression() override;
IMapExpression::Ptr getLightFalloffCubeMapExpression() override;
Expand Down
2 changes: 1 addition & 1 deletion radiantcore/shaders/Doom3ShaderLayer.h
Expand Up @@ -19,7 +19,7 @@ class ShaderTemplate;
* Implementation of IShaderLayer for Doom 3 shaders.
*/
class Doom3ShaderLayer :
public IShaderLayer
public IEditableShaderLayer
{
private:
// The owning material template
Expand Down

0 comments on commit d24d64f

Please sign in to comment.