Skip to content

Commit

Permalink
#5532: Redesign fragmentMap handling in Doom3ShaderLayer, analogously…
Browse files Browse the repository at this point in the history
… to the vertexParms.
  • Loading branch information
codereader committed Feb 28, 2021
1 parent 0b1e67a commit a1fff5e
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 20 deletions.
17 changes: 15 additions & 2 deletions include/ShaderLayer.h
Expand Up @@ -341,10 +341,23 @@ class ShaderLayer
*/
virtual std::size_t getNumFragmentMaps() = 0;

struct FragmentMap
{
FragmentMap() :
index(-1)
{}

int index;
std::vector<std::string> options;
shaders::IMapExpression::Ptr map;
};

virtual const FragmentMap& getFragmentMap(int index) = 0;

/**
* Returns the fragment map with the given index.
* Returns the fragment map image with the given index.
*/
virtual TexturePtr getFragmentMap(int index) = 0;
virtual TexturePtr getFragmentMapTexture(int index) = 0;

/**
* Stage-specific polygon offset, overriding the "global" one defined on the material.
Expand Down
1 change: 1 addition & 0 deletions libs/materials/ParseLib.h
Expand Up @@ -124,5 +124,6 @@ inline std::string getStringForTexGenType(ShaderLayer::TexGenType type)
}

constexpr int NUM_MAX_VERTEX_PARMS = 4;
constexpr int NUM_MAX_FRAGMENT_MAPS = 8;

}
23 changes: 21 additions & 2 deletions radiantcore/shaders/Doom3ShaderLayer.cpp
Expand Up @@ -299,14 +299,33 @@ float Doom3ShaderLayer::getAlphaTest() const
return _registers[_alphaTest];
}

TexturePtr Doom3ShaderLayer::getFragmentMap(int index)
TexturePtr Doom3ShaderLayer::getFragmentMapTexture(int index)
{
if (index < 0 || index >= static_cast<int>(_fragmentMaps.size()))
{
return TexturePtr();
}

return GetTextureManager().getBinding(_fragmentMaps[index]);
return GetTextureManager().getBinding(std::dynamic_pointer_cast<NamedBindable>(_fragmentMaps[index].map));
}

const Doom3ShaderLayer::FragmentMap& Doom3ShaderLayer::getFragmentMap(int index)
{
assert(index >= 0 && index < static_cast<int>(_fragmentMaps.size()));

return _fragmentMaps[index];
}

void Doom3ShaderLayer::addFragmentMap(const ShaderLayer::FragmentMap& fragmentMap)
{
assert(fragmentMap.index >= 0);

if (fragmentMap.index >= _fragmentMaps.size())
{
_fragmentMaps.resize(fragmentMap.index + 1);
}

_fragmentMaps[fragmentMap.index] = fragmentMap;
}

std::string Doom3ShaderLayer::getMapImageFilename()
Expand Down
16 changes: 4 additions & 12 deletions radiantcore/shaders/Doom3ShaderLayer.h
Expand Up @@ -105,7 +105,7 @@ class Doom3ShaderLayer
std::vector<VertexParm> _vertexParmDefinitions;

// The array of fragment maps
std::vector<MapExpressionPtr> _fragmentMaps;
std::vector<FragmentMap> _fragmentMaps;

// Stage-specific polygon offset, is 0 if not used
float _privatePolygonOffset;
Expand Down Expand Up @@ -513,19 +513,11 @@ class Doom3ShaderLayer
return _fragmentMaps.size();
}

TexturePtr getFragmentMap(int index);
const FragmentMap& getFragmentMap(int index) override;

void setFragmentMap(std::size_t index, const MapExpressionPtr& map)
{
assert(index >= 0);
TexturePtr getFragmentMapTexture(int index) override;

if (index >= _fragmentMaps.size())
{
_fragmentMaps.resize(index + 1);
}

_fragmentMaps[index] = map;
}
void addFragmentMap(const FragmentMap& fragmentMap);

float getPrivatePolygonOffset()
{
Expand Down
17 changes: 13 additions & 4 deletions radiantcore/shaders/ShaderTemplate.cpp
Expand Up @@ -804,8 +804,15 @@ bool ShaderTemplate::parseStageModifiers(parser::DefTokeniser& tokeniser,
}
else if (token == "fragmentmap")
{
ShaderLayer::FragmentMap map;

// fragmentMap <index> [options] <map>
int mapNum = string::convert<int>(tokeniser.nextToken());
map.index = string::convert<int>(tokeniser.nextToken());

if (map.index < 0 || map.index >= NUM_MAX_FRAGMENT_MAPS)
{
throw parser::ParseException(fmt::format("A material stage can have {0} fragment maps at most", NUM_MAX_FRAGMENT_MAPS));
}

std::string next = tokeniser.peek();
string::to_lower(next);
Expand All @@ -816,14 +823,16 @@ bool ShaderTemplate::parseStageModifiers(parser::DefTokeniser& tokeniser,
next == "zeroclamp" || next == "alphazeroclamp" || next == "forcehighquality" ||
next == "uncompressed" || next == "highquality" || next == "nopicmip")
{
tokeniser.nextToken();
map.options.emplace_back(tokeniser.nextToken());

next = tokeniser.peek();
string::to_lower(next);
}

// Get the map expression (but don't really use it)
_currentLayer->setFragmentMap(mapNum, MapExpression::createForToken(tokeniser));
// Get the map expression and add the fragment map to the stage
map.map = MapExpression::createForToken(tokeniser);

_currentLayer->addFragmentMap(map);
}
else if (token == "alphatest")
{
Expand Down

0 comments on commit a1fff5e

Please sign in to comment.