Skip to content

Commit

Permalink
Add some logic to clear the noshadows flag that is set when the mater…
Browse files Browse the repository at this point in the history
…ial coverage is determined after parsing.

When adding or removing stages, the flag needs to react.
  • Loading branch information
codereader committed Apr 17, 2021
1 parent 1b5111e commit e129733
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 63 deletions.
10 changes: 6 additions & 4 deletions radiant/ui/materials/editor/MaterialEditor.cpp
Expand Up @@ -1628,7 +1628,9 @@ void MaterialEditor::updateStageButtonSensitivity()
{
auto item = _stageView->GetSelection();

if (_material && item.IsOk() && GlobalMaterialManager().materialCanBeModified(_material->getName()))
bool materialCanBeModified = _material && GlobalMaterialManager().materialCanBeModified(_material->getName());

if (materialCanBeModified && item.IsOk())
{
auto row = wxutil::TreeModel::Row(item, *_stageList);
auto index = row[STAGE_COLS().index].getInteger();
Expand All @@ -1649,7 +1651,7 @@ void MaterialEditor::updateStageButtonSensitivity()
getControl<wxButton>("MaterialEditorMoveUpStageButton")->Disable();
getControl<wxButton>("MaterialEditorMoveDownStageButton")->Disable();
getControl<wxButton>("MaterialEditorDuplicateStageButton")->Disable();
getControl<wxButton>("MaterialEditorAddStageButton")->Disable();
getControl<wxButton>("MaterialEditorAddStageButton")->Enable(materialCanBeModified);
}
}

Expand Down Expand Up @@ -2526,7 +2528,7 @@ void MaterialEditor::_onAddStage(wxCommandEvent& ev)
{
std::size_t index = _material->addLayer(determineStageTypeToCreate(_material));

updateStageListFromMaterial();
updateControlsFromMaterial();
selectStageByIndex(index);
}

Expand Down Expand Up @@ -2698,7 +2700,7 @@ void MaterialEditor::updateMaterialTreeItem()

void MaterialEditor::onMaterialChanged()
{
updateMaterialNameControl();
updateMaterialPropertiesFromMaterial();
updateMaterialTreeItem();
updateMaterialControlSensitivity();
updateSourceView();
Expand Down
137 changes: 79 additions & 58 deletions radiantcore/shaders/ShaderTemplate.cpp
Expand Up @@ -1255,72 +1255,88 @@ void ShaderTemplate::parseDefinition()
resetSortRequest();
}

std::size_t numAmbientStages = 0;
determineCoverage();

for (const auto& layer : _layers)
{
if (layer->getType() == IShaderLayer::BLEND)
{
numAmbientStages++;
}
}

// Determine coverage if not yet done
if (_coverage == Material::MC_UNDETERMINED)
{
// automatically set MC_TRANSLUCENT if we don't have any interaction stages and
// the first stage is blended and not an alpha test mask or a subview
if (_layers.empty())
{
// non-visible
_coverage = Material::MC_TRANSLUCENT;
}
else if (_layers.size() != numAmbientStages)
{
// we have an interaction draw
_coverage = Material::MC_OPAQUE;
}
else
{
const Doom3ShaderLayer& firstLayer = **_layers.begin();
// We might have invoked a few setters during this process, clear the flag now
_blockContentsNeedUpdate = false;
}

BlendFunc blend = firstLayer.getBlendFunc();
void ShaderTemplate::determineCoverage()
{
// Determine coverage if not yet done
if (_coverage == Material::MC_UNDETERMINED)
{
std::size_t numAmbientStages = 0;

// If the layers are blended with the destination, we consider it translucent
if (blend.dest != GL_ZERO ||
blend.src == GL_DST_COLOR ||
blend.src == GL_ONE_MINUS_DST_COLOR ||
blend.src == GL_DST_ALPHA ||
blend.src == GL_ONE_MINUS_DST_ALPHA)
{
_coverage = Material::MC_TRANSLUCENT;
}
else
{
_coverage = Material::MC_OPAQUE;
}
}
}
for (const auto& layer : _layers)
{
if (layer->getType() == IShaderLayer::BLEND)
{
numAmbientStages++;
}
}

// translucent automatically implies noshadows
if (_coverage == Material::MC_TRANSLUCENT)
{
_materialFlags |= Material::FLAG_NOSHADOWS;
}
else
{
// mark the contents as opaque
_surfaceFlags |= Material::SURF_OPAQUE;
}
// automatically set MC_TRANSLUCENT if we don't have any interaction stages and
// the first stage is blended and not an alpha test mask or a subview
if (_layers.empty())
{
// non-visible
_coverage = Material::MC_TRANSLUCENT;
}
else if (_layers.size() != numAmbientStages)
{
// we have an interaction draw
_coverage = Material::MC_OPAQUE;
}
else
{
const Doom3ShaderLayer& firstLayer = **_layers.begin();

// We might have invoked a few setters during this process, clear the flag now
_blockContentsNeedUpdate = false;
BlendFunc blend = firstLayer.getBlendFunc();

// If the layers are blended with the destination, we consider it translucent
if (blend.dest != GL_ZERO ||
blend.src == GL_DST_COLOR ||
blend.src == GL_ONE_MINUS_DST_COLOR ||
blend.src == GL_DST_ALPHA ||
blend.src == GL_ONE_MINUS_DST_ALPHA)
{
_coverage = Material::MC_TRANSLUCENT;
}
else
{
_coverage = Material::MC_OPAQUE;
}
}
}

// translucent automatically implies noshadows
if (_coverage == Material::MC_TRANSLUCENT)
{
_materialFlags |= Material::FLAG_NOSHADOWS;
}
else
{
// mark the contents as opaque
_surfaceFlags |= Material::SURF_OPAQUE;
}
}

void ShaderTemplate::addLayer(const Doom3ShaderLayer::Ptr& layer)
{
// Add the layer
_layers.emplace_back(layer);
// Add the layer
_layers.emplace_back(layer);

// If this is our first layer, clear the noshadows flag that was set before
// and redetermine the coverage
if (_layers.size() == 1)
{
_materialFlags &= ~Material::FLAG_NOSHADOWS;
_coverage = Material::MC_UNDETERMINED;
determineCoverage();
}

onTemplateChanged();
}

void ShaderTemplate::addLayer(IShaderLayer::Type type, const MapExpressionPtr& mapExpr)
Expand Down Expand Up @@ -1350,7 +1366,6 @@ std::size_t ShaderTemplate::addLayer(IShaderLayer::Type type)
}

addLayer(std::make_shared<Doom3ShaderLayer>(*this, type, map));
onTemplateChanged();

return _layers.size() - 1;
}
Expand All @@ -1359,6 +1374,12 @@ void ShaderTemplate::removeLayer(std::size_t index)
{
_layers.erase(_layers.begin() + index);

if (_layers.empty())
{
_coverage = Material::MC_UNDETERMINED;
determineCoverage();
}

onTemplateChanged();
}

Expand Down
2 changes: 1 addition & 1 deletion radiantcore/shaders/ShaderTemplate.h
Expand Up @@ -543,7 +543,7 @@ class ShaderTemplate final
IShaderExpression::Ptr parseSingleExpressionTerm(parser::DefTokeniser& tokeniser);

bool saveLayer();

void determineCoverage();
};

/* TYPEDEFS */
Expand Down

0 comments on commit e129733

Please sign in to comment.