mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
Dump material tile and filter properties
This commit is contained in:
parent
0179d61451
commit
c010355d4a
@ -627,6 +627,17 @@ namespace IW4
|
|||||||
water_t* water;
|
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
|
enum SamplerStateBits_e
|
||||||
{
|
{
|
||||||
SAMPLER_FILTER_SHIFT = 0x0,
|
SAMPLER_FILTER_SHIFT = 0x0,
|
||||||
|
@ -409,6 +409,52 @@ namespace IW4
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(GdtStencilOpNames)> == static_cast<size_t>(StencilOp_e::COUNT));
|
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
|
enum GdtMaterialType
|
||||||
{
|
{
|
||||||
MATERIAL_TYPE_UNKNOWN,
|
MATERIAL_TYPE_UNKNOWN,
|
||||||
|
@ -526,61 +526,38 @@ namespace IW4
|
|||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(g_materialTypeInfo)> == MTL_TYPE_COUNT);
|
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);
|
return std::make_pair(Common::R_HashString(name, 0u), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::unordered_map knownMaterialSourceNames
|
inline std::unordered_map knownConstantNames
|
||||||
{
|
{
|
||||||
KnownMaterialSource("colorMap"),
|
MakeKnownConstantName("distortionScale"),
|
||||||
KnownMaterialSource("colorMap0"),
|
MakeKnownConstantName("eyeOffsetParms"),
|
||||||
KnownMaterialSource("colorMap1"),
|
MakeKnownConstantName("falloffBeginColor"),
|
||||||
KnownMaterialSource("colorMap2"),
|
MakeKnownConstantName("falloffEndColor"),
|
||||||
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"),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -142,9 +142,11 @@ namespace IW4
|
|||||||
SetTechniqueSet("2d");
|
SetTechniqueSet("2d");
|
||||||
|
|
||||||
const auto colorMapName = ReadStringProperty("colorMap");
|
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())
|
if (!colorMapName.empty())
|
||||||
AddMapTexture("colorMap", TS_2D, colorMapName);
|
AddMapTexture("colorMap", tileColor, filterColor, TS_2D, colorMapName);
|
||||||
else
|
else
|
||||||
throw GdtReadingException("ColorMap may not be blank in 2d materials");
|
throw GdtReadingException("ColorMap may not be blank in 2d materials");
|
||||||
}
|
}
|
||||||
@ -658,15 +660,59 @@ namespace IW4
|
|||||||
return m_base_statebits;
|
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{};
|
MaterialTextureDef textureDef{};
|
||||||
textureDef.nameHash = Common::R_HashString(typeName.c_str());
|
textureDef.nameHash = Common::R_HashString(typeName.c_str());
|
||||||
textureDef.nameStart = typeName[0];
|
textureDef.nameStart = typeName[0];
|
||||||
textureDef.nameEnd = typeName[typeName.size() - 1];
|
textureDef.nameEnd = typeName[typeName.size() - 1];
|
||||||
textureDef.samplerState = 0; // TODO
|
textureDef.samplerState = 0;
|
||||||
textureDef.semantic = static_cast<unsigned char>(semantic);
|
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));
|
auto* image = reinterpret_cast<XAssetInfo<GfxImage>*>(m_manager->LoadDependency(ASSET_TYPE_IMAGE, textureName));
|
||||||
|
|
||||||
if (image == nullptr)
|
if (image == nullptr)
|
||||||
@ -1015,7 +1061,7 @@ bool AssetLoaderMaterial::LoadFromGdt(const std::string& assetName, IGdtQueryabl
|
|||||||
if (loader.Load())
|
if (loader.Load())
|
||||||
manager->AddAsset(ASSET_TYPE_MATERIAL, assetName, loader.GetMaterial(), loader.GetDependencies(), std::vector<scr_string_t>());
|
manager->AddAsset(ASSET_TYPE_MATERIAL, assetName, loader.GetMaterial(), loader.GetDependencies(), std::vector<scr_string_t>());
|
||||||
}
|
}
|
||||||
catch(const SkipMaterialException&)
|
catch (const SkipMaterialException&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
namespace IW4
|
namespace IW4
|
||||||
{
|
{
|
||||||
@ -136,10 +137,10 @@ namespace IW4
|
|||||||
{"semantic", ArrayEntry(semanticNames, entry.semantic)}
|
{"semantic", ArrayEntry(semanticNames, entry.semantic)}
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto knownMaterialSourceName = knownMaterialSourceNames.find(entry.nameHash);
|
const auto knownMaterialSourceName = knownTextureMaps.find(entry.nameHash);
|
||||||
if (knownMaterialSourceName != knownMaterialSourceNames.end())
|
if (knownMaterialSourceName != knownTextureMaps.end())
|
||||||
{
|
{
|
||||||
jEntry["name"] = knownMaterialSourceName->second;
|
jEntry["name"] = knownMaterialSourceName->second.m_name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -191,8 +192,8 @@ namespace IW4
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto knownMaterialSourceName = knownMaterialSourceNames.find(entry.nameHash);
|
const auto knownMaterialSourceName = knownConstantNames.find(entry.nameHash);
|
||||||
if (knownMaterialSourceName != knownMaterialSourceNames.end())
|
if (knownMaterialSourceName != knownConstantNames.end())
|
||||||
{
|
{
|
||||||
jEntry["name"] = knownMaterialSourceName->second;
|
jEntry["name"] = knownMaterialSourceName->second;
|
||||||
}
|
}
|
||||||
@ -1351,8 +1352,8 @@ namespace IW4
|
|||||||
for (auto i = 0u; i < m_material->textureCount; i++)
|
for (auto i = 0u; i < m_material->textureCount; i++)
|
||||||
{
|
{
|
||||||
const auto& entry = m_material->textureTable[i];
|
const auto& entry = m_material->textureTable[i];
|
||||||
const auto knownMaterialSourceName = knownMaterialSourceNames.find(entry.nameHash);
|
const auto knownMaterialSourceName = knownTextureMaps.find(entry.nameHash);
|
||||||
if (knownMaterialSourceName == knownMaterialSourceNames.end())
|
if (knownMaterialSourceName == knownTextureMaps.end())
|
||||||
{
|
{
|
||||||
assert(false);
|
assert(false);
|
||||||
std::cout << "Unknown material texture source name hash: 0x" << std::hex << entry.nameHash << " (" << entry.nameStart << "..." << entry.nameEnd << ")\n";
|
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);
|
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)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,18 +212,27 @@ namespace IW4
|
|||||||
Indent();
|
Indent();
|
||||||
m_stream << codeDestAccessor << " = material.";
|
m_stream << codeDestAccessor << " = material.";
|
||||||
|
|
||||||
const auto knownMaterialSource = knownMaterialSourceNames.find(arg.u.nameHash);
|
const auto knownConstantName = knownConstantNames.find(arg.u.nameHash);
|
||||||
if (knownMaterialSource != knownMaterialSourceNames.end())
|
if (knownConstantName != knownConstantNames.end())
|
||||||
{
|
{
|
||||||
m_stream << knownMaterialSource->second;
|
m_stream << knownConstantName->second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto shaderArgNameHash = Common::R_HashString(targetShaderArg->m_name.c_str(), 0u);
|
const auto knownMaterialTextureName = knownTextureMaps.find(arg.u.nameHash);
|
||||||
if (shaderArgNameHash == arg.u.nameHash)
|
|
||||||
m_stream << targetShaderArg->m_name;
|
if(knownMaterialTextureName != knownTextureMaps.end())
|
||||||
|
{
|
||||||
|
m_stream << knownConstantName->second;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_stream << "#0x" << std::hex << arg.u.nameHash;
|
{
|
||||||
|
const auto shaderArgNameHash = Common::R_HashString(targetShaderArg->m_name.c_str(), 0u);
|
||||||
|
if (shaderArgNameHash == arg.u.nameHash)
|
||||||
|
m_stream << targetShaderArg->m_name;
|
||||||
|
else
|
||||||
|
m_stream << "#0x" << std::hex << arg.u.nameHash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream << ";\n";
|
m_stream << ";\n";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user