Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
#5532: Refactor bindings to support a preparation step before modifyi…
…ng a shader stage
  • Loading branch information
codereader committed Mar 13, 2021
1 parent 8521dbe commit bd351c7
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 45 deletions.
5 changes: 4 additions & 1 deletion include/ShaderLayer.h
Expand Up @@ -146,7 +146,7 @@ class ShaderLayer
*/
virtual float getTexGenParam(std::size_t index) const = 0;

// The expressions used to calcualte the tex gen params. Index in [0..2]
// The expressions used to calculate the tex gen params. Index in [0..2]
virtual shaders::IShaderExpressionPtr getTexGenExpression(std::size_t index) const = 0;

/**
Expand Down Expand Up @@ -364,6 +364,9 @@ class ShaderLayer
// The map expression used to generate/define the texture of this stage
virtual shaders::IMapExpression::Ptr getMapExpression() = 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() = 0;
};
Expand Down
20 changes: 10 additions & 10 deletions radiant/ui/materials/Binding.h
Expand Up @@ -13,6 +13,8 @@ class Binding
Source _source;

public:
using Ptr = std::shared_ptr<Binding>;

virtual ~Binding()
{}

Expand All @@ -27,13 +29,11 @@ class Binding
onSourceChanged();
}

virtual void updateFromSource(const Source& source) = 0;
virtual void updateFromSource() = 0;

protected:
virtual void onSourceChanged()
{
updateFromSource(getSource());
}
{}
};

template<typename Source>
Expand All @@ -47,13 +47,13 @@ class CheckBoxBinding :

public:
CheckBoxBinding(wxCheckBox* checkbox,
const std::function<bool(const Source&)> loadFunc) :
const std::function<bool(const Source&)>& loadFunc) :
CheckBoxBinding(checkbox, loadFunc, std::function<void(const Source&, bool)>())
{}

CheckBoxBinding(wxCheckBox* checkbox,
const std::function<bool(const Source&)> loadFunc,
const std::function<void(const Source&, bool)> saveFunc) :
const std::function<bool(const Source&)>& loadFunc,
const std::function<void(const Source&, bool)>& saveFunc) :
_checkbox(checkbox),
_loadFunc(loadFunc),
_saveFunc(saveFunc)
Expand All @@ -72,15 +72,15 @@ class CheckBoxBinding :
}
}

virtual void updateFromSource(const Source& source) override
virtual void updateFromSource() override
{
if (!source)
if (!Binding<Source>::getSource())
{
_checkbox->SetValue(false);
return;
}

_checkbox->SetValue(_loadFunc(source));
_checkbox->SetValue(_loadFunc(Binding<Source>::getSource()));
}

private:
Expand Down
31 changes: 25 additions & 6 deletions radiant/ui/materials/ExpressionBinding.h
Expand Up @@ -13,24 +13,43 @@ class ExpressionBinding :
private:
wxTextCtrl* _textCtrl;
std::function<shaders::IShaderExpressionPtr(const Source&)> _getExpression;
std::function<void()> _prepareSave;
std::function<void(const Source&, const std::string&)> _updateExpression;

public:
ExpressionBinding(wxTextCtrl* textCtrl, const std::function<shaders::IShaderExpressionPtr(const Source&)> loadFunc) :
ExpressionBinding(wxTextCtrl* textCtrl,
const std::function<shaders::IShaderExpressionPtr(const Source&)>& loadFunc,
const std::function<void()>& prepareSaveFunc,
const std::function<void(const Source&, const std::string&)>& saveFunc) :
_textCtrl(textCtrl),
_getExpression(loadFunc)
{}
_getExpression(loadFunc),
_prepareSave(prepareSaveFunc),
_updateExpression(saveFunc)
{
if (saveFunc)
{
_textCtrl->Bind(wxEVT_TEXT, &ExpressionBinding<Source>::onTextChanged, this);
}
}

virtual void updateFromSource(const Source& source) override
virtual void updateFromSource() override
{
if (!source)
if (!Binding<Source>::getSource())
{
_textCtrl->SetValue("");
return;
}

auto expression = _getExpression(source);
auto expression = _getExpression(Binding<Source>::getSource());
_textCtrl->SetValue(expression ? expression->getExpressionString() : "");
}

private:
void onTextChanged(wxCommandEvent& ev)
{
_prepareSave();
_updateExpression(Binding<Source>::getSource(), _textCtrl->GetValue().ToStdString());
}
};

}
74 changes: 46 additions & 28 deletions radiant/ui/materials/MaterialEditor.cpp
Expand Up @@ -362,6 +362,22 @@ void MaterialEditor::setupStageFlag(const std::string& controlName, int flags)
}));
}

void MaterialEditor::prepareMaterialForSave()
{
// TODO
}

void MaterialEditor::createExpressionBinding(const std::string& textCtrlName,
const std::function<shaders::IShaderExpressionPtr(const ShaderLayerPtr&)>& loadFunc,
const std::function<void(const ShaderLayerPtr&, const std::string&)>& saveFunc)
{
_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(
getControl<wxTextCtrl>(textCtrlName),
loadFunc,
std::bind(&MaterialEditor::prepareMaterialForSave, this),
saveFunc));
}

void MaterialEditor::setupMaterialStageProperties()
{
setupStageFlag("MaterialStageFlagMaskRed", ShaderLayer::FLAG_MASK_RED);
Expand Down Expand Up @@ -434,43 +450,43 @@ void MaterialEditor::setupMaterialStageProperties()
texgenDropdown->AppendString(pair.first);
}

_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageTranslateX"),
[](const ShaderLayerPtr& layer) { return layer->getTranslationExpression(0); }));
_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageTranslateY"),
[](const ShaderLayerPtr& layer) { return layer->getTranslationExpression(1); }));
createExpressionBinding("MaterialStageTranslateX",
[](const ShaderLayerPtr& layer) { return layer->getTranslationExpression(0); });
createExpressionBinding("MaterialStageTranslateY",
[](const ShaderLayerPtr& layer) { return layer->getTranslationExpression(1); });

_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageScaleX"),
[](const ShaderLayerPtr& layer) { return layer->getScaleExpression(0); }));
_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageScaleY"),
[](const ShaderLayerPtr& layer) { return layer->getScaleExpression(1); }));
createExpressionBinding("MaterialStageScaleX",
[](const ShaderLayerPtr& layer) { return layer->getScaleExpression(0); });
createExpressionBinding("MaterialStageScaleY",
[](const ShaderLayerPtr& layer) { return layer->getScaleExpression(1); });

_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageCenterScaleX"),
[](const ShaderLayerPtr& layer) { return layer->getCenterScaleExpression(0); }));
_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageCenterScaleY"),
[](const ShaderLayerPtr& layer) { return layer->getCenterScaleExpression(1); }));
createExpressionBinding("MaterialStageCenterScaleX",
[](const ShaderLayerPtr& layer) { return layer->getCenterScaleExpression(0); });
createExpressionBinding("MaterialStageCenterScaleY",
[](const ShaderLayerPtr& layer) { return layer->getCenterScaleExpression(1); });

_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageShearX"),
[](const ShaderLayerPtr& layer) { return layer->getShearExpression(0); }));
_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageShearY"),
[](const ShaderLayerPtr& layer) { return layer->getShearExpression(1); }));
createExpressionBinding("MaterialStageShearX",
[](const ShaderLayerPtr& layer) { return layer->getShearExpression(0); });
createExpressionBinding("MaterialStageShearY",
[](const ShaderLayerPtr& layer) { return layer->getShearExpression(1); });

_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageRotate"),
[](const ShaderLayerPtr& layer) { return layer->getRotationExpression(); }));
createExpressionBinding("MaterialStageRotate",
[](const ShaderLayerPtr& layer) { return layer->getRotationExpression(); });

_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageCondition"),
[](const ShaderLayerPtr& layer) { return layer->getConditionExpression(); }));
createExpressionBinding("MaterialStageCondition",
[](const ShaderLayerPtr& layer) { return layer->getConditionExpression(); });

_stageBindings.emplace(std::make_shared<CheckBoxBinding<ShaderLayerPtr>>(getControl<wxCheckBox>("MaterialStageColored"),
[](const ShaderLayerPtr& layer) { return (layer->getParseFlags() & ShaderLayer::PF_HasColoredKeyword) != 0; }));

_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageRed"),
[](const ShaderLayerPtr& layer) { return layer->getColourExpression(ShaderLayer::COMP_RED); }));
_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageGreen"),
[](const ShaderLayerPtr& layer) { return layer->getColourExpression(ShaderLayer::COMP_GREEN); }));
_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageBlue"),
[](const ShaderLayerPtr& layer) { return layer->getColourExpression(ShaderLayer::COMP_BLUE); }));
_stageBindings.emplace(std::make_shared<ExpressionBinding<ShaderLayerPtr>>(getControl<wxTextCtrl>("MaterialStageAlpha"),
[](const ShaderLayerPtr& layer) { return layer->getColourExpression(ShaderLayer::COMP_ALPHA); }));
createExpressionBinding("MaterialStageRed",
[](const ShaderLayerPtr& layer) { return layer->getColourExpression(ShaderLayer::COMP_RED); });
createExpressionBinding("MaterialStageGreen",
[](const ShaderLayerPtr& layer) { return layer->getColourExpression(ShaderLayer::COMP_GREEN); });
createExpressionBinding("MaterialStageBlue",
[](const ShaderLayerPtr& layer) { return layer->getColourExpression(ShaderLayer::COMP_BLUE); });
createExpressionBinding("MaterialStageAlpha",
[](const ShaderLayerPtr& layer) { return layer->getColourExpression(ShaderLayer::COMP_ALPHA); });

auto parameterPanel = getControl<wxPanel>("MaterialStageProgramParameters");
_stageProgramParameters = wxutil::TreeModel::Ptr(new wxutil::TreeModel(_stageProgramColumns, true));
Expand Down Expand Up @@ -642,6 +658,7 @@ void MaterialEditor::updateMaterialPropertiesFromMaterial()
for (const auto& binding : _materialBindings)
{
binding->setSource(_material);
binding->updateFromSource();
}

updateDeformControlsFromMaterial();
Expand Down Expand Up @@ -976,6 +993,7 @@ void MaterialEditor::updateStageControls()
for (const auto& binding : _stageBindings)
{
binding->setSource(selectedStage);
binding->updateFromSource();
}

getControl<wxPanel>("MaterialEditorStageSettingsPanel")->Enable(selectedStage != nullptr);
Expand Down
6 changes: 6 additions & 0 deletions radiant/ui/materials/MaterialEditor.h
Expand Up @@ -77,6 +77,10 @@ class MaterialEditor :
void setupMaterialFlag(const std::string& controlName, Material::Flags flag);
void setupStageFlag(const std::string& controlName, int flags);

void createExpressionBinding(const std::string& textCtrlName,
const std::function<shaders::IShaderExpressionPtr(const ShaderLayerPtr&)>& loadFunc,
const std::function<void(const ShaderLayerPtr&, const std::string&)>& saveFunc = std::function<void(const ShaderLayerPtr&, const std::string&)>());

void updateControlsFromMaterial();
void updateDeformControlsFromMaterial();
void updateStageListFromMaterial();
Expand All @@ -85,6 +89,8 @@ class MaterialEditor :
void selectStageByIndex(std::size_t index);
ShaderLayerPtr getSelectedStage();

void prepareMaterialForSave();

void updateStageControls();
void updateStageBlendControls();
void updateStageTexgenControls();
Expand Down
1 change: 1 addition & 0 deletions radiant/ui/materials/MaterialPreview.cpp
Expand Up @@ -199,6 +199,7 @@ void MaterialPreview::setupTestModel()
void MaterialPreview::onTestModelSelectionChanged(wxCommandEvent& ev)
{
setupTestModel();
queueDraw();
}

}
5 changes: 5 additions & 0 deletions radiantcore/shaders/Doom3ShaderLayer.cpp
Expand Up @@ -405,6 +405,11 @@ IMapExpression::Ptr Doom3ShaderLayer::getMapExpression()
return std::dynamic_pointer_cast<IMapExpression>(_bindableTex);
}

void Doom3ShaderLayer::setMapExpressionFromString(const std::string& expression)
{
setBindableTexture(MapExpression::createForString(expression));
}

int Doom3ShaderLayer::getParseFlags()
{
return _parseFlags;
Expand Down
1 change: 1 addition & 0 deletions radiantcore/shaders/Doom3ShaderLayer.h
Expand Up @@ -533,6 +533,7 @@ class Doom3ShaderLayer :
std::string getMapImageFilename() override;

shaders::IMapExpression::Ptr getMapExpression() override;
void setMapExpressionFromString(const std::string& expression) override;

int getParseFlags() override;
void setParseFlag(ParseFlags flag);
Expand Down

0 comments on commit bd351c7

Please sign in to comment.