Fix material loading sortkeys and cameraRegion

This commit is contained in:
Jan 2022-08-06 15:40:00 +02:00
parent 09fdb95927
commit 347c1b3d68
4 changed files with 96 additions and 16 deletions

View File

@ -784,6 +784,18 @@ namespace IW3
CAMERA_REGION_NONE = 0x3, CAMERA_REGION_NONE = 0x3,
}; };
enum MaterialStateFlags
{
STATE_FLAG_CULL_BACK = 0x1,
STATE_FLAG_CULL_FRONT = 0x2,
STATE_FLAG_DECAL = 0x4,
STATE_FLAG_WRITES_DEPTH = 0x8,
STATE_FLAG_USES_DEPTH_BUFFER = 0x10,
STATE_FLAG_USES_STENCIL_BUFFER = 0x20,
STATE_FLAG_CULL_BACK_SHADOW = 0x40,
STATE_FLAG_CULL_FRONT_SHADOW = 0x80,
};
struct Material struct Material
{ {
MaterialInfo info; MaterialInfo info;

View File

@ -864,6 +864,9 @@ namespace IW4
SORTKEY_SKYBOX = 3, SORTKEY_SKYBOX = 3,
// ? = 4, // some kind of dynamic decal? // ? = 4, // some kind of dynamic decal?
// ? = 5, // another kind of dynamic decal? // ? = 5, // another kind of dynamic decal?
SORTKEY_TRANS_START = 6,
SORTKEY_DECAL_BOTTOM_1 = 6, // prob decal - bottom 1 SORTKEY_DECAL_BOTTOM_1 = 6, // prob decal - bottom 1
SORTKEY_DECAL_BOTTOM_2 = 7, // prob decal - bottom 2 SORTKEY_DECAL_BOTTOM_2 = 7, // prob decal - bottom 2
SORTKEY_DECAL_BOTTOM_3 = 8, // prob decal - bottom 3 SORTKEY_DECAL_BOTTOM_3 = 8, // prob decal - bottom 3
@ -916,6 +919,20 @@ namespace IW4
SORTKEY_MAX SORTKEY_MAX
}; };
// Names unknown
// There's probably: MTL_GAMEFLAG_CASTS_SHADOW (part of iw3; 0x40 there)
enum MaterialGameFlags
{
MTL_GAMEFLAG_1 = 0x1,
MTL_GAMEFLAG_2 = 0x2,
MTL_GAMEFLAG_4 = 0x4,
MTL_GAMEFLAG_8 = 0x8,
MTL_GAMEFLAG_10 = 0x10,
MTL_GAMEFLAG_20 = 0x20,
MTL_GAMEFLAG_40 = 0x40,
MTL_GAMEFLAG_80 = 0x80,
};
struct MaterialInfo struct MaterialInfo
{ {
const char* name; const char* name;
@ -941,14 +958,13 @@ namespace IW4
enum MaterialStateFlags enum MaterialStateFlags
{ {
MTL_STATEFLAG_CULL_BACK = 0x1, // Only when has technique for >= TECHNIQUE_LIT_BEGIN (checks all statebits) STATE_FLAG_CULL_BACK = 0x1,
MTL_STATEFLAG_CULL_FRONT = 0x2, // ^ STATE_FLAG_AMBIENT = 0x2,
MTL_STATEFLAG_IS_DECAL = 0x4, STATE_FLAG_DECAL = 0x4,
MTL_STATEFLAG_WRITES_DEPTH = 0x8, STATE_FLAG_WRITES_DEPTH = 0x8,
MTL_STATEFLAG_USES_DEPTH_BUFFER = 0x10, STATE_FLAG_USES_DEPTH_BUFFER = 0x10,
MTL_STATEFLAG_USES_STENCIL_BUFFER = 0x20, STATE_FLAG_USES_STENCIL_BUFFER = 0x20,
MTL_STATEFLAG_CULL_SHADOW_BACK = 0x40, // Only when has technique for TECHNIQUE_BUILD_SHADOWMAP_DEPTH (checks its statebits) STATE_FLAG_CULL_BACK_SHADOW = 0x40,
MTL_STATEFLAG_CULL_SHADOW_FRONT = 0x80 // ^
}; };
struct Material struct Material

View File

@ -4,6 +4,7 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include "AssetLoaderTechniqueSet.h"
#include "ObjLoading.h" #include "ObjLoading.h"
#include "AssetLoading/AbstractGdtEntryReader.h" #include "AssetLoading/AbstractGdtEntryReader.h"
#include "Game/IW4/CommonIW4.h" #include "Game/IW4/CommonIW4.h"
@ -542,16 +543,35 @@ namespace IW4
m_dependencies.push_back(techset); m_dependencies.push_back(techset);
m_material->techniqueSet = techset->Asset(); m_material->techniqueSet = techset->Asset();
auto* loadingContext = m_manager->GetAssetLoadingContext();
auto* searchPath = loadingContext->m_raw_search_path;
auto* definitionCache = loadingContext->GetZoneAssetLoaderState<techset::TechsetDefinitionCache>();
const auto* techsetDefinition = AssetLoaderTechniqueSet::LoadTechsetDefinition(techsetName, searchPath, definitionCache);
if (techsetDefinition == nullptr)
{
std::ostringstream ss;
ss << "Could not find techset definition for: \"" << techsetName << "\"";
throw GdtReadingException(ss.str());
}
SetTechniqueSetStateBits(techsetDefinition);
SetTechniqueSetCameraRegion(techsetDefinition);
}
void SetTechniqueSetStateBits(const techset::TechsetDefinition* techsetDefinition)
{
for (auto i = 0; i < TECHNIQUE_COUNT; i++) for (auto i = 0; i < TECHNIQUE_COUNT; i++)
{ {
if (m_material->techniqueSet->techniques[i]) std::string techniqueName;
if (techsetDefinition->GetTechniqueByIndex(i, techniqueName))
{ {
const auto stateBitsForTechnique = GetStateBitsForTechnique(static_cast<MaterialTechniqueType>(i)); const auto stateBitsForTechnique = GetStateBitsForTechnique(techniqueName);
const auto foundStateBits = std::find_if(m_state_bits.begin(), m_state_bits.end(), const auto foundStateBits = std::find_if(m_state_bits.begin(), m_state_bits.end(),
[stateBitsForTechnique](const GfxStateBits& s1) [stateBitsForTechnique](const GfxStateBits& s1)
{ {
return s1.loadBits[0] == stateBitsForTechnique.loadBits[0] && s1.loadBits[1] == stateBitsForTechnique.loadBits[1]; return s1.loadBits[0] == stateBitsForTechnique.loadBits[0] && s1.loadBits[1] == stateBitsForTechnique.loadBits[1];
}); });
if (foundStateBits != m_state_bits.end()) if (foundStateBits != m_state_bits.end())
{ {
@ -570,7 +590,27 @@ namespace IW4
} }
} }
GfxStateBits GetStateBitsForTechnique(MaterialTechniqueType techniqueType) void SetTechniqueSetCameraRegion(const techset::TechsetDefinition* techsetDefinition) const
{
std::string tempName;
if (techsetDefinition->GetTechniqueByIndex(TECHNIQUE_LIT, tempName))
{
if (m_material->info.sortKey >= SORTKEY_TRANS_START)
m_material->cameraRegion = CAMERA_REGION_LIT_TRANS;
else
m_material->cameraRegion = CAMERA_REGION_LIT_OPAQUE;
}
else if (techsetDefinition->GetTechniqueByIndex(TECHNIQUE_EMISSIVE, tempName))
{
m_material->cameraRegion = CAMERA_REGION_EMISSIVE;
}
else
{
m_material->cameraRegion = CAMERA_REGION_NONE;
}
}
GfxStateBits GetStateBitsForTechnique(const std::string& techniqueName)
{ {
// TODO: Use technique statemap to evaluate actual statebits // TODO: Use technique statemap to evaluate actual statebits
return m_base_statebits; return m_base_statebits;
@ -863,6 +903,18 @@ namespace IW4
m_material->textureTable = nullptr; m_material->textureTable = nullptr;
m_material->textureCount = 0u; m_material->textureCount = 0u;
} }
if (!m_state_bits.empty())
{
m_material->stateBitsTable = static_cast<GfxStateBits*>(m_memory->Alloc(sizeof(GfxStateBits) * m_state_bits.size()));
m_material->stateBitsCount = static_cast<unsigned char>(m_state_bits.size());
memcpy(m_material->stateBitsTable, m_state_bits.data(), sizeof(GfxStateBits) * m_state_bits.size());
}
else
{
m_material->stateBitsTable = nullptr;
m_material->stateBitsCount = 0u;
}
} }
static size_t GetIndexForString(const std::string& propertyName, const std::string& value, const char** validValuesArray, const size_t validValuesArraySize) static size_t GetIndexForString(const std::string& propertyName, const std::string& value, const char** validValuesArray, const size_t validValuesArraySize)

View File

@ -1277,7 +1277,7 @@ namespace IW4
SetValue("materialType", GdtMaterialTypeNames[static_cast<size_t>(m_techset_info.m_gdt_material_type)]); SetValue("materialType", GdtMaterialTypeNames[static_cast<size_t>(m_techset_info.m_gdt_material_type)]);
SetValue("customTemplate", GdtCustomMaterialTypeNames[static_cast<size_t>(m_techset_info.m_gdt_custom_material_type)]); SetValue("customTemplate", GdtCustomMaterialTypeNames[static_cast<size_t>(m_techset_info.m_gdt_custom_material_type)]);
SetValue("customString", m_techset_info.m_gdt_custom_string); SetValue("customString", m_techset_info.m_gdt_custom_string);
SetValue("sortKey", m_techset_info.m_sort_key_name); SetValue("sort", m_techset_info.m_sort_key_name);
SetValue("noCastShadow", m_techset_info.m_no_cast_shadow); SetValue("noCastShadow", m_techset_info.m_no_cast_shadow);
SetValue("noReceiveDynamicShadow", m_techset_info.m_no_receive_dynamic_shadow); SetValue("noReceiveDynamicShadow", m_techset_info.m_no_receive_dynamic_shadow);
SetValue("noFog", m_techset_info.m_no_fog); SetValue("noFog", m_techset_info.m_no_fog);