Skip to content

Commit

Permalink
#5565: Colour expression selector by component is now considering equ…
Browse files Browse the repository at this point in the history
…ivalent expressions, by their string representation.

More unit test cases.
  • Loading branch information
codereader committed Mar 26, 2021
1 parent 0e0877b commit aee7ac8
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 6 deletions.
13 changes: 7 additions & 6 deletions radiantcore/shaders/Doom3ShaderLayer.cpp
Expand Up @@ -224,17 +224,18 @@ const IShaderExpression::Ptr& Doom3ShaderLayer::getColourExpression(ColourCompon
case COMP_ALPHA:
return _expressionSlots[Expression::ColourAlpha].expression;
case COMP_RGB:
// Select if all RGB are using the same expression
if (_expressionSlots[Expression::ColourRed].expression == _expressionSlots[Expression::ColourGreen].expression &&
_expressionSlots[Expression::ColourGreen].expression == _expressionSlots[Expression::ColourBlue].expression)
// Select if all RGB components are using equivalent expressions
if (_expressionSlots.expressionsAreEquivalent(Expression::ColourRed, Expression::ColourGreen) &&
_expressionSlots.expressionsAreEquivalent(Expression::ColourGreen, Expression::ColourBlue))
{
return _expressionSlots[Expression::ColourRed].expression;
}
break;
case COMP_RGBA:
if (_expressionSlots[Expression::ColourRed].expression == _expressionSlots[Expression::ColourGreen].expression &&
_expressionSlots[Expression::ColourGreen].expression == _expressionSlots[Expression::ColourBlue].expression &&
_expressionSlots[Expression::ColourBlue].expression == _expressionSlots[Expression::ColourAlpha].expression)
// Select if all RGBA components are using equivalent expressions
if (_expressionSlots.expressionsAreEquivalent(Expression::ColourRed, Expression::ColourGreen) &&
_expressionSlots.expressionsAreEquivalent(Expression::ColourGreen, Expression::ColourBlue) &&
_expressionSlots.expressionsAreEquivalent(Expression::ColourBlue, Expression::ColourAlpha))
{
return _expressionSlots[Expression::ColourRed].expression;
}
Expand Down
18 changes: 18 additions & 0 deletions radiantcore/shaders/ExpressionSlots.cpp
Expand Up @@ -79,6 +79,24 @@ void ExpressionSlots::assignFromString(IShaderLayer::Expression::Slot slot, cons
assign(slot, expression, defaultRegisterIndex);
}

bool ExpressionSlots::expressionsAreEquivalent(IShaderLayer::Expression::Slot slotA, IShaderLayer::Expression::Slot slotB) const
{
auto a = at(slotA);
auto b = at(slotB);

if (a.expression == b.expression)
{
return true;
}

if (a.expression && b.expression)
{
return a.expression->getExpressionString() == b.expression->getExpressionString();
}

return false;
}

bool ExpressionSlots::registerIsShared(std::size_t index) const
{
std::size_t useCount = 0;
Expand Down
5 changes: 5 additions & 0 deletions radiantcore/shaders/ExpressionSlots.h
Expand Up @@ -41,6 +41,11 @@ class ExpressionSlots :
// Parsing failures of non-empty strings will not change the slot
void assignFromString(IShaderLayer::Expression::Slot slot, const std::string& expression, std::size_t defaultRegisterIndex);

// Returns true if the two given slots are equipped with equivalent expressions
// (i.e. are reference-equal or using the same string representation)
// This also returns true if both slots are empty
bool expressionsAreEquivalent(IShaderLayer::Expression::Slot slotA, IShaderLayer::Expression::Slot slotB) const;

private:
// Returns true if the given register index is in use by more than one expression
bool registerIsShared(std::size_t index) const;
Expand Down
78 changes: 78 additions & 0 deletions test/Materials.cpp
Expand Up @@ -1082,4 +1082,82 @@ TEST_F(MaterialsTest, MaterialParserStageFlags)
}
}

TEST_F(MaterialsTest, MaterialParserStageVertexColours)
{
auto material = GlobalMaterialManager().getMaterial("textures/parsertest/vertexcolours/none");
EXPECT_EQ(material->getAllLayers().at(0)->getVertexColourMode(), IShaderLayer::VERTEX_COLOUR_NONE);

material = GlobalMaterialManager().getMaterial("textures/parsertest/vertexcolours/vertexcolour");
EXPECT_EQ(material->getAllLayers().at(1)->getVertexColourMode(), IShaderLayer::VERTEX_COLOUR_INVERSE_MULTIPLY);
EXPECT_EQ(material->getAllLayers().at(0)->getVertexColourMode(), IShaderLayer::VERTEX_COLOUR_MULTIPLY);

material = GlobalMaterialManager().getMaterial("textures/parsertest/vertexcolours/colourcomponents");

// Stage 1: Red
EXPECT_EQ(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_RED)->getExpressionString(), "0.5");
EXPECT_FALSE(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_GREEN));
EXPECT_FALSE(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_BLUE));
EXPECT_FALSE(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_ALPHA));
EXPECT_FALSE(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_RGB));
EXPECT_FALSE(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_RGBA));

// Stage 2: Green
EXPECT_EQ(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_GREEN)->getExpressionString(), "0.4");
EXPECT_FALSE(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_RED));
EXPECT_FALSE(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_BLUE));
EXPECT_FALSE(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_ALPHA));
EXPECT_FALSE(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_RGB));
EXPECT_FALSE(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_RGBA));

// Stage 3: Blue
EXPECT_EQ(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_BLUE)->getExpressionString(), "0.3");
EXPECT_FALSE(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_RED));
EXPECT_FALSE(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_GREEN));
EXPECT_FALSE(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_ALPHA));
EXPECT_FALSE(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_RGB));
EXPECT_FALSE(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_RGBA));

// Stage 4: Alpha
EXPECT_EQ(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_ALPHA)->getExpressionString(), "0.2");
EXPECT_FALSE(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_RED));
EXPECT_FALSE(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_GREEN));
EXPECT_FALSE(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_BLUE));
EXPECT_FALSE(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_RGB));
EXPECT_FALSE(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_RGBA));

material = GlobalMaterialManager().getMaterial("textures/parsertest/vertexcolours/combinations");

// Stage 1: RGB the same, alpha is different
EXPECT_EQ(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_RED)->getExpressionString(), "0.5");
EXPECT_EQ(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_GREEN)->getExpressionString(), "0.5");
EXPECT_EQ(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_BLUE)->getExpressionString(), "0.5");
EXPECT_EQ(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_ALPHA)->getExpressionString(), "time");
EXPECT_EQ(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_RGB)->getExpressionString(), "0.5");
EXPECT_FALSE(material->getAllLayers().at(0)->getColourExpression(IShaderLayer::COMP_RGBA));

// Stage 2: RGBA all the same
EXPECT_EQ(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_RED)->getExpressionString(), "0.5");
EXPECT_EQ(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_GREEN)->getExpressionString(), "0.5");
EXPECT_EQ(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_BLUE)->getExpressionString(), "0.5");
EXPECT_EQ(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_ALPHA)->getExpressionString(), "0.5");
EXPECT_EQ(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_RGB)->getExpressionString(), "0.5");
EXPECT_EQ(material->getAllLayers().at(1)->getColourExpression(IShaderLayer::COMP_RGBA)->getExpressionString(), "0.5");

// Stage 3: RGB overridden by red
EXPECT_EQ(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_RED)->getExpressionString(), "0.4");
EXPECT_EQ(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_GREEN)->getExpressionString(), "0.3");
EXPECT_EQ(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_BLUE)->getExpressionString(), "0.3");
EXPECT_FALSE(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_ALPHA));
EXPECT_FALSE(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_RGB));
EXPECT_FALSE(material->getAllLayers().at(2)->getColourExpression(IShaderLayer::COMP_RGBA));

// Stage 4: RGBA overridden by alpha
EXPECT_EQ(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_RED)->getExpressionString(), "0.2");
EXPECT_EQ(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_GREEN)->getExpressionString(), "0.2");
EXPECT_EQ(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_BLUE)->getExpressionString(), "0.2");
EXPECT_EQ(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_ALPHA)->getExpressionString(), "time");
EXPECT_EQ(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_RGB)->getExpressionString(), "0.2");
EXPECT_FALSE(material->getAllLayers().at(3)->getColourExpression(IShaderLayer::COMP_RGBA));
}

}
75 changes: 75 additions & 0 deletions test/resources/tdm/materials/parsertest.mtr
Expand Up @@ -765,3 +765,78 @@ textures/parsertest/stageflags/maskEverything
maskDepth
}
}

textures/parsertest/vertexcolours/none
{
diffusemap _white
}

textures/parsertest/vertexcolours/vertexcolour
{
{
blend diffusemap
map _white
vertexColor
}
{
blend diffusemap
map _white
inverseVertexColor
}
}

textures/parsertest/vertexcolours/colourcomponents
{
{
blend diffusemap
map _white
red 0.5
}
{
blend diffusemap
map _white
green 0.4
}
{
blend diffusemap
map _white
blue 0.3
}
{
blend diffusemap
map _white
alpha 0.2
}
}

textures/parsertest/vertexcolours/combinations
{
{
blend diffusemap
map _white
red 0.5
green 0.5
blue 0.5
alpha time // alpha is different
}
{
blend diffusemap
map _white
red 0.5
green 0.5
blue 0.5
alpha 0.5
}
{
blend diffusemap
map _white
rgb 0.3
red 0.4
}
{
blend diffusemap
map _white
rgba 0.2
alpha time
}
}

0 comments on commit aee7ac8

Please sign in to comment.