Dump material tile and filter properties

This commit is contained in:
Jan 2022-08-06 18:47:28 +02:00
parent 0179d61451
commit c010355d4a
6 changed files with 205 additions and 70 deletions

View File

@ -627,6 +627,17 @@ namespace IW4
water_t* water;
};
enum MaterialTextureFilter
{
TEXTURE_FILTER_DISABLED = 0x0,
TEXTURE_FILTER_NEAREST = 0x1,
TEXTURE_FILTER_LINEAR = 0x2,
TEXTURE_FILTER_ANISO2X = 0x3,
TEXTURE_FILTER_ANISO4X = 0x4,
TEXTURE_FILTER_COUNT
};
enum SamplerStateBits_e
{
SAMPLER_FILTER_SHIFT = 0x0,

View File

@ -409,6 +409,52 @@ namespace IW4
};
static_assert(std::extent_v<decltype(GdtStencilOpNames)> == static_cast<size_t>(StencilOp_e::COUNT));
enum class TileMode_e
{
UNKNOWN,
TILE_BOTH,
TILE_HORIZONTAL,
TILE_VERTICAL,
NO_TILE,
COUNT
};
inline const char* GdtTileModeNames[]
{
"",
"tile both*",
"tile horizontal",
"tile vertical",
"no tile"
};
static_assert(std::extent_v<decltype(GdtTileModeNames)> == static_cast<size_t>(TileMode_e::COUNT));
enum class GdtFilter_e
{
UNKNOWN,
MIP_2X_BILINEAR,
MIP_4X_BILINEAR,
MIP_2X_TRILINEAR,
MIP_4X_TRILINEAR,
NOMIP_NEAREST,
NOMIP_BILINEAR,
COUNT
};
static const char* GdtSamplerFilterNames[]
{
"",
"mip standard (2x bilinear)*",
"mip expensive (4x bilinear)",
"mip more expensive (2x trilinear)",
"mip most expensive (4x trilinear)",
"nomip nearest",
"nomip bilinear"
};
static_assert(std::extent_v<decltype(GdtSamplerFilterNames)> == static_cast<size_t>(GdtFilter_e::COUNT));
enum GdtMaterialType
{
MATERIAL_TYPE_UNKNOWN,

View File

@ -526,61 +526,38 @@ namespace IW4
};
static_assert(std::extent_v<decltype(g_materialTypeInfo)> == MTL_TYPE_COUNT);
static constexpr std::pair<uint32_t, const char*> KnownMaterialSource(const char* name)
struct KnownMaterialTextureMap
{
const char* m_name;
const char* m_additional_property_suffix;
};
static constexpr std::pair<uint32_t, KnownMaterialTextureMap> MakeKnownTextureMap(const char* name, const char* additionalPropertySuffix)
{
return std::make_pair(Common::R_HashString(name, 0u), KnownMaterialTextureMap{name, additionalPropertySuffix});
}
inline std::unordered_map knownTextureMaps
{
MakeKnownTextureMap("colorMap", "Color"),
MakeKnownTextureMap("colorMap0", "Color00"),
MakeKnownTextureMap("colorMap1", "Color01"),
MakeKnownTextureMap("colorMap2", "Color02"),
MakeKnownTextureMap("normalMap", "Normal"),
MakeKnownTextureMap("specularMap", "Specular"),
MakeKnownTextureMap("detailMap", "Detail"),
};
static constexpr std::pair<uint32_t, const char*> MakeKnownConstantName(const char* name)
{
return std::make_pair(Common::R_HashString(name, 0u), name);
}
inline std::unordered_map knownMaterialSourceNames
inline std::unordered_map knownConstantNames
{
KnownMaterialSource("colorMap"),
KnownMaterialSource("colorMap0"),
KnownMaterialSource("colorMap1"),
KnownMaterialSource("colorMap2"),
KnownMaterialSource("colorMap3"),
KnownMaterialSource("colorMap4"),
KnownMaterialSource("colorMap5"),
KnownMaterialSource("colorMap6"),
KnownMaterialSource("colorMap7"),
KnownMaterialSource("normalMap"),
KnownMaterialSource("normalMap0"),
KnownMaterialSource("normalMap1"),
KnownMaterialSource("normalMap2"),
KnownMaterialSource("normalMap3"),
KnownMaterialSource("normalMap4"),
KnownMaterialSource("normalMap5"),
KnownMaterialSource("normalMap6"),
KnownMaterialSource("normalMap7"),
KnownMaterialSource("specularMap"),
KnownMaterialSource("specularMap0"),
KnownMaterialSource("specularMap1"),
KnownMaterialSource("specularMap2"),
KnownMaterialSource("specularMap3"),
KnownMaterialSource("specularMap4"),
KnownMaterialSource("specularMap5"),
KnownMaterialSource("specularMap6"),
KnownMaterialSource("specularMap7"),
KnownMaterialSource("detailMap"),
KnownMaterialSource("detailMap0"),
KnownMaterialSource("detailMap1"),
KnownMaterialSource("detailMap2"),
KnownMaterialSource("detailMap3"),
KnownMaterialSource("detailMap4"),
KnownMaterialSource("detailMap5"),
KnownMaterialSource("detailMap6"),
KnownMaterialSource("detailMap7"),
KnownMaterialSource("attenuationMap"),
KnownMaterialSource("attenuationMap0"),
KnownMaterialSource("attenuationMap1"),
KnownMaterialSource("attenuationMap2"),
KnownMaterialSource("attenuationMap3"),
KnownMaterialSource("attenuationMap4"),
KnownMaterialSource("attenuationMap5"),
KnownMaterialSource("attenuationMap6"),
KnownMaterialSource("attenuationMap7"),
KnownMaterialSource("distortionScale"),
KnownMaterialSource("eyeOffsetParms"),
KnownMaterialSource("falloffBeginColor"),
KnownMaterialSource("falloffEndColor"),
MakeKnownConstantName("distortionScale"),
MakeKnownConstantName("eyeOffsetParms"),
MakeKnownConstantName("falloffBeginColor"),
MakeKnownConstantName("falloffEndColor"),
};
}

View File

@ -142,9 +142,11 @@ namespace IW4
SetTechniqueSet("2d");
const auto colorMapName = ReadStringProperty("colorMap");
const auto tileColor = ReadEnumProperty<TileMode_e>("tileColor", GdtTileModeNames, std::extent_v<decltype(GdtTileModeNames)>);
const auto filterColor = ReadEnumProperty<GdtFilter_e>("filterColor", GdtSamplerFilterNames, std::extent_v<decltype(GdtSamplerFilterNames)>);
if (!colorMapName.empty())
AddMapTexture("colorMap", TS_2D, colorMapName);
AddMapTexture("colorMap", tileColor, filterColor, TS_2D, colorMapName);
else
throw GdtReadingException("ColorMap may not be blank in 2d materials");
}
@ -658,15 +660,59 @@ namespace IW4
return m_base_statebits;
}
void AddMapTexture(const std::string& typeName, const TextureSemantic semantic, const std::string& textureName)
void AddMapTexture(const std::string& typeName, const TileMode_e tileMode, GdtFilter_e filterMode, const TextureSemantic semantic, const std::string& textureName)
{
MaterialTextureDef textureDef{};
textureDef.nameHash = Common::R_HashString(typeName.c_str());
textureDef.nameStart = typeName[0];
textureDef.nameEnd = typeName[typeName.size() - 1];
textureDef.samplerState = 0; // TODO
textureDef.samplerState = 0;
textureDef.semantic = static_cast<unsigned char>(semantic);
switch (tileMode)
{
case TileMode_e::TILE_BOTH:
textureDef.samplerState |= SAMPLER_CLAMP_U | SAMPLER_CLAMP_V | SAMPLER_CLAMP_W;
break;
case TileMode_e::TILE_HORIZONTAL:
textureDef.samplerState |= SAMPLER_CLAMP_V;
break;
case TileMode_e::TILE_VERTICAL:
textureDef.samplerState |= SAMPLER_CLAMP_U;
break;
case TileMode_e::UNKNOWN:
case TileMode_e::NO_TILE:
break;
default:
assert(false);
break;
}
switch (filterMode)
{
case GdtFilter_e::MIP_2X_BILINEAR:
textureDef.samplerState |= SAMPLER_FILTER_ANISO2X | SAMPLER_MIPMAP_NEAREST;
break;
case GdtFilter_e::MIP_2X_TRILINEAR:
textureDef.samplerState |= SAMPLER_FILTER_ANISO2X | SAMPLER_MIPMAP_LINEAR;
break;
case GdtFilter_e::MIP_4X_BILINEAR:
textureDef.samplerState |= SAMPLER_FILTER_ANISO4X | SAMPLER_MIPMAP_NEAREST;
break;
case GdtFilter_e::MIP_4X_TRILINEAR:
textureDef.samplerState |= SAMPLER_FILTER_ANISO4X | SAMPLER_MIPMAP_LINEAR;
break;
case GdtFilter_e::NOMIP_NEAREST:
textureDef.samplerState |= SAMPLER_FILTER_NEAREST | SAMPLER_MIPMAP_DISABLED;
break;
case GdtFilter_e::NOMIP_BILINEAR:
textureDef.samplerState |= SAMPLER_FILTER_LINEAR | SAMPLER_MIPMAP_DISABLED;
break;
default:
assert(false);
break;
}
auto* image = reinterpret_cast<XAssetInfo<GfxImage>*>(m_manager->LoadDependency(ASSET_TYPE_IMAGE, textureName));
if (image == nullptr)

View File

@ -19,6 +19,7 @@
using namespace IW4;
using json = nlohmann::json;
using namespace std::string_literals;
namespace IW4
{
@ -136,10 +137,10 @@ namespace IW4
{"semantic", ArrayEntry(semanticNames, entry.semantic)}
};
const auto knownMaterialSourceName = knownMaterialSourceNames.find(entry.nameHash);
if (knownMaterialSourceName != knownMaterialSourceNames.end())
const auto knownMaterialSourceName = knownTextureMaps.find(entry.nameHash);
if (knownMaterialSourceName != knownTextureMaps.end())
{
jEntry["name"] = knownMaterialSourceName->second;
jEntry["name"] = knownMaterialSourceName->second.m_name;
}
else
{
@ -191,8 +192,8 @@ namespace IW4
}
else
{
const auto knownMaterialSourceName = knownMaterialSourceNames.find(entry.nameHash);
if (knownMaterialSourceName != knownMaterialSourceNames.end())
const auto knownMaterialSourceName = knownConstantNames.find(entry.nameHash);
if (knownMaterialSourceName != knownConstantNames.end())
{
jEntry["name"] = knownMaterialSourceName->second;
}
@ -1351,8 +1352,8 @@ namespace IW4
for (auto i = 0u; i < m_material->textureCount; i++)
{
const auto& entry = m_material->textureTable[i];
const auto knownMaterialSourceName = knownMaterialSourceNames.find(entry.nameHash);
if (knownMaterialSourceName == knownMaterialSourceNames.end())
const auto knownMaterialSourceName = knownTextureMaps.find(entry.nameHash);
if (knownMaterialSourceName == knownTextureMaps.end())
{
assert(false);
std::cout << "Unknown material texture source name hash: 0x" << std::hex << entry.nameHash << " (" << entry.nameStart << "..." << entry.nameEnd << ")\n";
@ -1373,7 +1374,52 @@ namespace IW4
imageName = AssetName(entry.u.water->image->name);
}
SetValue(knownMaterialSourceName->second, imageName);
TileMode_e tileMode;
if (entry.samplerState & SAMPLER_CLAMP_U && entry.samplerState & SAMPLER_CLAMP_V && entry.samplerState & SAMPLER_CLAMP_W)
tileMode = TileMode_e::TILE_BOTH;
else if (entry.samplerState & SAMPLER_CLAMP_U)
tileMode = TileMode_e::TILE_VERTICAL;
else if (entry.samplerState & SAMPLER_CLAMP_V)
tileMode = TileMode_e::TILE_HORIZONTAL;
else
tileMode = TileMode_e::NO_TILE;
auto filter = GdtFilter_e::UNKNOWN;
if ((entry.samplerState & SAMPLER_FILTER_MASK) == SAMPLER_FILTER_ANISO2X)
{
if (entry.samplerState & SAMPLER_MIPMAP_NEAREST)
filter = GdtFilter_e::MIP_2X_BILINEAR;
else if (entry.samplerState & SAMPLER_MIPMAP_LINEAR)
filter = GdtFilter_e::MIP_2X_TRILINEAR;
}
else if ((entry.samplerState & SAMPLER_FILTER_MASK) == SAMPLER_FILTER_ANISO4X)
{
if (entry.samplerState & SAMPLER_MIPMAP_NEAREST)
filter = GdtFilter_e::MIP_4X_BILINEAR;
else if (entry.samplerState & SAMPLER_MIPMAP_LINEAR)
filter = GdtFilter_e::MIP_4X_TRILINEAR;
}
else if ((entry.samplerState & SAMPLER_FILTER_MASK) == SAMPLER_FILTER_NEAREST)
{
assert((entry.samplerState & SAMPLER_MIPMAP_MASK) == SAMPLER_MIPMAP_DISABLED);
filter = GdtFilter_e::NOMIP_NEAREST;
}
else if ((entry.samplerState & SAMPLER_FILTER_MASK) == SAMPLER_FILTER_LINEAR)
{
assert((entry.samplerState & SAMPLER_MIPMAP_MASK) == SAMPLER_MIPMAP_DISABLED);
filter = GdtFilter_e::NOMIP_BILINEAR;
}
assert(filter != GdtFilter_e::UNKNOWN);
if (filter == GdtFilter_e::UNKNOWN)
{
std::cout << "Unknown filter/mipmap combination: " << entry.samplerState << "\n";
continue;
}
SetValue(knownMaterialSourceName->second.m_name, imageName);
SetValue("tile"s + knownMaterialSourceName->second.m_additional_property_suffix, GdtTileModeNames[static_cast<size_t>(tileMode)]);
SetValue("filter"s + knownMaterialSourceName->second.m_additional_property_suffix, GdtSamplerFilterNames[static_cast<size_t>(filter)]);
}
}

View File

@ -212,10 +212,18 @@ namespace IW4
Indent();
m_stream << codeDestAccessor << " = material.";
const auto knownMaterialSource = knownMaterialSourceNames.find(arg.u.nameHash);
if (knownMaterialSource != knownMaterialSourceNames.end())
const auto knownConstantName = knownConstantNames.find(arg.u.nameHash);
if (knownConstantName != knownConstantNames.end())
{
m_stream << knownMaterialSource->second;
m_stream << knownConstantName->second;
}
else
{
const auto knownMaterialTextureName = knownTextureMaps.find(arg.u.nameHash);
if(knownMaterialTextureName != knownTextureMaps.end())
{
m_stream << knownConstantName->second;
}
else
{
@ -225,6 +233,7 @@ namespace IW4
else
m_stream << "#0x" << std::hex << arg.u.nameHash;
}
}
m_stream << ";\n";
}