diff --git a/src/Common/Game/IW3/IW3_Assets.h b/src/Common/Game/IW3/IW3_Assets.h index af8782ef..a7723000 100644 --- a/src/Common/Game/IW3/IW3_Assets.h +++ b/src/Common/Game/IW3/IW3_Assets.h @@ -784,6 +784,18 @@ namespace IW3 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 { MaterialInfo info; diff --git a/src/Common/Game/IW4/IW4_Assets.h b/src/Common/Game/IW4/IW4_Assets.h index 2802a86b..392b13f5 100644 --- a/src/Common/Game/IW4/IW4_Assets.h +++ b/src/Common/Game/IW4/IW4_Assets.h @@ -864,6 +864,9 @@ namespace IW4 SORTKEY_SKYBOX = 3, // ? = 4, // some 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_2 = 7, // prob decal - bottom 2 SORTKEY_DECAL_BOTTOM_3 = 8, // prob decal - bottom 3 @@ -916,6 +919,20 @@ namespace IW4 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 { const char* name; @@ -941,14 +958,13 @@ namespace IW4 enum MaterialStateFlags { - MTL_STATEFLAG_CULL_BACK = 0x1, // Only when has technique for >= TECHNIQUE_LIT_BEGIN (checks all statebits) - MTL_STATEFLAG_CULL_FRONT = 0x2, // ^ - MTL_STATEFLAG_IS_DECAL = 0x4, - MTL_STATEFLAG_WRITES_DEPTH = 0x8, - MTL_STATEFLAG_USES_DEPTH_BUFFER = 0x10, - MTL_STATEFLAG_USES_STENCIL_BUFFER = 0x20, - MTL_STATEFLAG_CULL_SHADOW_BACK = 0x40, // Only when has technique for TECHNIQUE_BUILD_SHADOWMAP_DEPTH (checks its statebits) - MTL_STATEFLAG_CULL_SHADOW_FRONT = 0x80 // ^ + STATE_FLAG_CULL_BACK = 0x1, + STATE_FLAG_AMBIENT = 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, }; struct Material diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMaterial.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMaterial.cpp index aa52187b..dd018ee5 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMaterial.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMaterial.cpp @@ -4,6 +4,7 @@ #include #include +#include "AssetLoaderTechniqueSet.h" #include "ObjLoading.h" #include "AssetLoading/AbstractGdtEntryReader.h" #include "Game/IW4/CommonIW4.h" @@ -542,16 +543,35 @@ namespace IW4 m_dependencies.push_back(techset); m_material->techniqueSet = techset->Asset(); + auto* loadingContext = m_manager->GetAssetLoadingContext(); + auto* searchPath = loadingContext->m_raw_search_path; + auto* definitionCache = loadingContext->GetZoneAssetLoaderState(); + + 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++) { - if (m_material->techniqueSet->techniques[i]) + std::string techniqueName; + if (techsetDefinition->GetTechniqueByIndex(i, techniqueName)) { - const auto stateBitsForTechnique = GetStateBitsForTechnique(static_cast(i)); + const auto stateBitsForTechnique = GetStateBitsForTechnique(techniqueName); const auto foundStateBits = std::find_if(m_state_bits.begin(), m_state_bits.end(), - [stateBitsForTechnique](const GfxStateBits& s1) - { - return s1.loadBits[0] == stateBitsForTechnique.loadBits[0] && s1.loadBits[1] == stateBitsForTechnique.loadBits[1]; - }); + [stateBitsForTechnique](const GfxStateBits& s1) + { + return s1.loadBits[0] == stateBitsForTechnique.loadBits[0] && s1.loadBits[1] == stateBitsForTechnique.loadBits[1]; + }); 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 return m_base_statebits; @@ -863,6 +903,18 @@ namespace IW4 m_material->textureTable = nullptr; m_material->textureCount = 0u; } + + if (!m_state_bits.empty()) + { + m_material->stateBitsTable = static_cast(m_memory->Alloc(sizeof(GfxStateBits) * m_state_bits.size())); + m_material->stateBitsCount = static_cast(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) diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp index d954aa40..5036be3d 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp @@ -1277,7 +1277,7 @@ namespace IW4 SetValue("materialType", GdtMaterialTypeNames[static_cast(m_techset_info.m_gdt_material_type)]); SetValue("customTemplate", GdtCustomMaterialTypeNames[static_cast(m_techset_info.m_gdt_custom_material_type)]); 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("noReceiveDynamicShadow", m_techset_info.m_no_receive_dynamic_shadow); SetValue("noFog", m_techset_info.m_no_fog);