diff --git a/src/Common/Game/T6/T6_Assets.h b/src/Common/Game/T6/T6_Assets.h index 1a7b9b0e..366c93f7 100644 --- a/src/Common/Game/T6/T6_Assets.h +++ b/src/Common/Game/T6/T6_Assets.h @@ -3038,17 +3038,45 @@ namespace T6 void /*ID3D11RasterizerState*/* rasterizerState; }; + enum VertexShaderPrecompiledIndex : unsigned char + { + VERTEX_SHADER_NONE = 0x0, + VERTEX_SHADER_MODEL_LIT, + VERTEX_SHADER_MODEL_LIT_LIGHTMAP_VC, + VERTEX_SHADER_MODEL_UNLIT, + }; + + enum MaterialType : unsigned char + { + MTL_TYPE_DEFAULT = 0x0, + MTL_TYPE_MODEL, // m_ + MTL_TYPE_MODEL_VERTCOL, // mc_ + MTL_TYPE_MODEL_LIGHTMAP_VC, // mlv_ + MTL_TYPE_WORLD_VERTCOL, // wc_ + MTL_TYPE_PACKED_WORLD_VERTCOL, // wpc_ + MTL_TYPE_QUANT_WORLD, // wq_ + MTL_TYPE_QUANT_WORLD_VERTCOL, // wqc_ + + MTL_TYPE_COUNT, + }; + + struct MaterialTypeInfo + { + const char* materialPrefix; + const char* techniqueSetPrefix; + }; + struct MaterialPass { MaterialVertexDeclaration* vertexDecl; MaterialVertexShader* vertexShader; MaterialPixelShader* pixelShader; - char perPrimArgCount; - char perObjArgCount; - char stableArgCount; - char customSamplerFlags; - char precompiledIndex; - char materialType; + unsigned char perPrimArgCount; + unsigned char perObjArgCount; + unsigned char stableArgCount; + unsigned char customSamplerFlags; + VertexShaderPrecompiledIndex precompiledIndex; + MaterialType materialType; MaterialShaderArgument* args; }; @@ -5839,26 +5867,6 @@ namespace T6 }; }; - enum MaterialType - { - MTL_TYPE_DEFAULT = 0x0, - MTL_TYPE_MODEL = 0x1, // m_ - MTL_TYPE_MODEL_VERTCOL = 0x2, // mc_ - MTL_TYPE_MODEL_LIGHTMAP_VC = 0x3, // ? - MTL_TYPE_WORLD_VERTCOL = 0x4, // wc_ - MTL_TYPE_PACKED_WORLD_VERTCOL = 0x5, // ? - MTL_TYPE_QUANT_WORLD = 0x6, // ? - MTL_TYPE_QUANT_WORLD_VERTCOL = 0x7, // ? - - MTL_TYPE_COUNT, - }; - - struct MaterialTypeInfo - { - const char* materialPrefix; - const char* techniqueSetPrefix; - }; - enum MaterialConstantSource { CONST_SRC_CODE_MAYBE_DIRTY_PS_BEGIN = 0x0, diff --git a/src/ObjCommon/Game/IW4/TechsetConstantsIW4.h b/src/ObjCommon/Game/IW4/Techset/TechsetConstantsIW4.h similarity index 100% rename from src/ObjCommon/Game/IW4/TechsetConstantsIW4.h rename to src/ObjCommon/Game/IW4/Techset/TechsetConstantsIW4.h diff --git a/src/ObjCommon/Game/T6/TechsetConstantsT6.h b/src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h similarity index 100% rename from src/ObjCommon/Game/T6/TechsetConstantsT6.h rename to src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h diff --git a/src/ObjCommon/Techset/CommonShader.cpp b/src/ObjCommon/Techset/CommonShader.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/ObjCommon/Techset/CommonShader.h b/src/ObjCommon/Techset/CommonShader.h new file mode 100644 index 00000000..e69de29b diff --git a/src/ObjCommon/Techset/CommonTechnique.cpp b/src/ObjCommon/Techset/CommonTechnique.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/ObjCommon/Techset/CommonTechnique.h b/src/ObjCommon/Techset/CommonTechnique.h new file mode 100644 index 00000000..22259f79 --- /dev/null +++ b/src/ObjCommon/Techset/CommonTechnique.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include + +namespace techset +{ + class CommonTechniqueShader + { + public: + std::string m_name; + uint32_t m_version_major; + uint32_t m_version_minor; + }; + + class CommonPass + { + public: + uint64_t m_flags; + uint32_t m_sampler_flags; + CommonTechniqueShader m_vertex_shader; + CommonTechniqueShader m_pixel_shader; + }; + + class CommonTechnique + { + public: + uint64_t m_flags; + std::vector m_passes; + }; +} // namespace techset diff --git a/src/ObjCommon/Techset/CommonTechset.cpp b/src/ObjCommon/Techset/CommonTechset.cpp new file mode 100644 index 00000000..96bc0d3b --- /dev/null +++ b/src/ObjCommon/Techset/CommonTechset.cpp @@ -0,0 +1,22 @@ +#include "CommonTechset.h" + +#include + +techset::CommonTechniqueTypeNames::CommonTechniqueTypeNames(const char** names, const size_t nameCount) + : m_names(nameCount) +{ + std::copy(names, &names[nameCount], m_names.data()); +} + +const char* techset::CommonTechniqueTypeNames::GetTechniqueTypeName(const size_t techniqueTypeIndex) const +{ + if (techniqueTypeIndex >= m_names.size()) + return nullptr; + + return m_names[techniqueTypeIndex]; +} + +size_t techset::CommonTechniqueTypeNames::GetTechniqueTypeCount() const +{ + return m_names.size(); +} diff --git a/src/ObjCommon/Techset/CommonTechset.h b/src/ObjCommon/Techset/CommonTechset.h new file mode 100644 index 00000000..5dd2c02e --- /dev/null +++ b/src/ObjCommon/Techset/CommonTechset.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +namespace techset +{ + class CommonTechniqueTypeNames + { + public: + CommonTechniqueTypeNames(const char** names, size_t nameCount); + + [[nodiscard]] const char* GetTechniqueTypeName(size_t techniqueTypeIndex) const; + [[nodiscard]] size_t GetTechniqueTypeCount() const; + + private: + std::vector m_names; + }; + + class CommonTechset + { + public: + std::string m_name; + std::vector m_technique_names; + }; +} // namespace techset diff --git a/src/ObjCompiling/Game/IW4/Material/CompilerMaterialIW4.cpp b/src/ObjCompiling/Game/IW4/Material/CompilerMaterialIW4.cpp index 76897870..1b2aad5f 100644 --- a/src/ObjCompiling/Game/IW4/Material/CompilerMaterialIW4.cpp +++ b/src/ObjCompiling/Game/IW4/Material/CompilerMaterialIW4.cpp @@ -5,7 +5,7 @@ #include "Game/IW4/MaterialConstantsIW4.h" #include "Game/IW4/ObjConstantsIW4.h" #include "Game/IW4/Techset/CompilerTechsetIW4.h" -#include "Game/IW4/TechsetConstantsIW4.h" +#include "Game/IW4/Techset/TechsetConstantsIW4.h" #include "Gdt/AbstractGdtEntryReader.h" #include "Gdt/IGdtQueryable.h" #include "ObjLoading.h" diff --git a/src/ObjCompiling/Game/IW4/Techset/CompilerTechsetIW4.cpp b/src/ObjCompiling/Game/IW4/Techset/CompilerTechsetIW4.cpp index 7627004b..ac775a8f 100644 --- a/src/ObjCompiling/Game/IW4/Techset/CompilerTechsetIW4.cpp +++ b/src/ObjCompiling/Game/IW4/Techset/CompilerTechsetIW4.cpp @@ -3,7 +3,7 @@ #include "Game/IW4/IW4.h" #include "Game/IW4/Shader/LoaderPixelShaderIW4.h" #include "Game/IW4/Shader/LoaderVertexShaderIW4.h" -#include "Game/IW4/TechsetConstantsIW4.h" +#include "Game/IW4/Techset/TechsetConstantsIW4.h" #include "Shader/D3D9ShaderAnalyser.h" #include "Shader/ShaderCommon.h" #include "StateMap/StateMapReader.h" diff --git a/src/ObjCompiling/Game/IW4/Techset/CompilerVertexDeclIW4.cpp b/src/ObjCompiling/Game/IW4/Techset/CompilerVertexDeclIW4.cpp index 5c4144b8..9bfdaedc 100644 --- a/src/ObjCompiling/Game/IW4/Techset/CompilerVertexDeclIW4.cpp +++ b/src/ObjCompiling/Game/IW4/Techset/CompilerVertexDeclIW4.cpp @@ -1,7 +1,7 @@ #include "CompilerVertexDeclIW4.h" #include "Game/IW4/IW4.h" -#include "Game/IW4/TechsetConstantsIW4.h" +#include "Game/IW4/Techset/TechsetConstantsIW4.h" #include "Utils/Logging/Log.h" #include diff --git a/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.cpp b/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.cpp index 749c8d52..2a2a8e37 100644 --- a/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.cpp @@ -2,8 +2,7 @@ #include "Game/IW4/MaterialConstantsIW4.h" #include "Game/IW4/ObjConstantsIW4.h" -#include "Game/IW4/TechsetConstantsIW4.h" -#include "Utils/ClassUtils.h" +#include "Game/IW4/Techset/TechsetConstantsIW4.h" #include "Utils/Logging/Log.h" #pragma warning(push, 0) diff --git a/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.cpp b/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.cpp index 8714cd74..9885247e 100644 --- a/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.cpp @@ -1,9 +1,12 @@ #include "TechsetDumperIW4.h" #include "Dumping/AbstractTextDumper.h" -#include "Game/IW4/TechsetConstantsIW4.h" +#include "Game/IW4/Techset/TechsetConstantsIW4.h" #include "Pool/GlobalAssetPool.h" #include "Shader/D3D9ShaderAnalyser.h" +#include "Techset/CommonTechset.h" +#include "Techset/CommonTechsetDumper.h" +#include "Techset/TechniqueDumpingZoneState.h" #include "Techset/TechsetCommon.h" #include "Utils/Logging/Log.h" @@ -16,23 +19,8 @@ using namespace IW4; -namespace IW4 +namespace { - class TechniqueDumpingZoneState final : public IZoneAssetDumperState - { - std::set m_dumped_techniques; - - public: - bool ShouldDumpTechnique(const MaterialTechnique* technique) - { - if (m_dumped_techniques.find(technique) != m_dumped_techniques.end()) - return false; - - m_dumped_techniques.emplace(technique); - return true; - } - }; - class TechniqueFileWriter : public AbstractTextDumper { void DumpStateMap() const @@ -472,67 +460,31 @@ namespace IW4 } }; - class TechsetFileWriter : public AbstractTextDumper + techset::CommonTechset ConvertToCommonTechset(const MaterialTechniqueSet& techset) { - bool m_last_write_was_value; + std::vector techniqueNames(std::extent_v); - public: - explicit TechsetFileWriter(std::ostream& stream) - : AbstractTextDumper(stream), - m_last_write_was_value(false) + for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v; techniqueIndex++) { + const auto* technique = techset.techniques[techniqueIndex]; + if (technique && technique->name) + techniqueNames[techniqueIndex] = technique->name; } - void WriteTechniqueType(const size_t techniqueIndex) - { - assert(techniqueIndex < std::extent_v); + return techset::CommonTechset{ + .m_name = techset.name, + .m_technique_names = std::move(techniqueNames), + }; + } - if (m_last_write_was_value) - { - m_stream << "\n"; - m_last_write_was_value = false; - } - m_stream << '"' << techniqueTypeNames[techniqueIndex] << "\":\n"; - } + void DumpTechset(const AssetDumpingContext& context, const MaterialTechniqueSet& techset) + { + static techset::CommonTechniqueTypeNames commonNames(techniqueTypeNames, std::extent_v); + const auto commonTechset = ConvertToCommonTechset(techset); - void WriteTechniqueValue(const char* value) - { - m_last_write_was_value = true; - - IncIndent(); - Indent(); - m_stream << value << ";\n"; - DecIndent(); - } - - void DumpTechset(const MaterialTechniqueSet* techset) - { - std::vector dumpedTechniques(std::extent_v); - - for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v; techniqueIndex++) - { - const auto* technique = techset->techniques[techniqueIndex]; - if (technique == nullptr || dumpedTechniques[techniqueIndex]) - continue; - - dumpedTechniques[techniqueIndex] = true; - WriteTechniqueType(techniqueIndex); - - for (auto nextTechniqueIndex = techniqueIndex + 1; nextTechniqueIndex < std::extent_v; - nextTechniqueIndex++) - { - if (techset->techniques[nextTechniqueIndex] != technique) - continue; - - dumpedTechniques[nextTechniqueIndex] = true; - WriteTechniqueType(nextTechniqueIndex); - } - - WriteTechniqueValue(technique->name); - } - } - }; -} // namespace IW4 + techset::DumpCommonTechset(commonNames, context, commonTechset); + } +} // namespace namespace techset { @@ -543,18 +495,11 @@ namespace techset void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* techset = asset.Asset(); - - const auto techsetFile = context.OpenAssetFile(GetFileNameForTechsetName(techset->name)); - - if (techsetFile) - { - TechsetFileWriter writer(*techsetFile); - writer.DumpTechset(techset); - } + const auto* techniqueSet = asset.Asset(); + DumpTechset(context, *techniqueSet); auto* techniqueState = context.GetZoneAssetDumperState(); - for (const auto* technique : techset->techniques) + for (const auto* technique : techniqueSet->techniques) { if (technique && techniqueState->ShouldDumpTechnique(technique)) { diff --git a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp index 157b17ea..b49c6b74 100644 --- a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp @@ -1,6 +1,10 @@ #include "TechsetDumperT6.h" +#include "Game/T6/Techset/TechsetConstantsT6.h" #include "Shader/ShaderCommon.h" +#include "Techset/CommonTechniqueDumper.h" +#include "Techset/CommonTechsetDumper.h" +#include "Techset/TechniqueDumpingZoneState.h" #include #include @@ -73,21 +77,12 @@ namespace shaderFile->write(vertexShader.prog.loadDef.program, vertexShader.prog.loadDef.programSize); } -} // namespace -namespace techset -{ - DumperT6::DumperT6(const AssetPool& pool) - : AbstractAssetDumper(pool) + void DumpShaders(AssetDumpingContext& context, const MaterialTechniqueSet& techset) { - } - - void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) - { - const auto* techniqueSet = asset.Asset(); auto* shaderState = context.GetZoneAssetDumperState(); - for (const auto* technique : techniqueSet->techniques) + for (const auto* technique : techset.techniques) { if (!technique || !shaderState->ShouldDumpTechnique(technique)) continue; @@ -104,4 +99,76 @@ namespace techset } } } + + techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique) + { + std::vector techniqueNames(std::extent_v); + + for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v; techniqueIndex++) + { + const auto* technique = techset.techniques[techniqueIndex]; + if (technique && technique->name) + techniqueNames[techniqueIndex] = technique->name; + } + + return techset::CommonTechset{ + .m_name = techset.name, + .m_technique_names = std::move(techniqueNames), + }; + } + + void DumpTechniques(AssetDumpingContext& context, const MaterialTechniqueSet& techset) + { + auto* techniqueState = context.GetZoneAssetDumperState(); + for (const auto* technique : techset.techniques) + { + if (technique && techniqueState->ShouldDumpTechnique(technique)) + { + const auto commonTechnique = ConvertToCommonTechnique(*technique); + + techset::DumpCommonTechnique(context, commonTechnique); + } + } + } + + techset::CommonTechset ConvertToCommonTechset(const MaterialTechniqueSet& techset) + { + std::vector techniqueNames(std::extent_v); + + for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v; techniqueIndex++) + { + const auto* technique = techset.techniques[techniqueIndex]; + if (technique && technique->name) + techniqueNames[techniqueIndex] = technique->name; + } + + return techset::CommonTechset{ + .m_name = techset.name, + .m_technique_names = std::move(techniqueNames), + }; + } + + void DumpTechset(const AssetDumpingContext& context, const MaterialTechniqueSet& techset) + { + static techset::CommonTechniqueTypeNames commonNames(techniqueTypeNames, std::extent_v); + const auto commonTechset = ConvertToCommonTechset(techset); + + techset::DumpCommonTechset(commonNames, context, commonTechset); + } +} // namespace + +namespace techset +{ + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) + { + } + + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) + { + const auto* techniqueSet = asset.Asset(); + DumpTechset(context, *techniqueSet); + DumpTechniques(context, *techniqueSet); + DumpShaders(context, *techniqueSet); + } } // namespace techset diff --git a/src/ObjWriting/Techset/CommonTechniqueDumper.cpp b/src/ObjWriting/Techset/CommonTechniqueDumper.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/ObjWriting/Techset/CommonTechniqueDumper.h b/src/ObjWriting/Techset/CommonTechniqueDumper.h new file mode 100644 index 00000000..168c27b7 --- /dev/null +++ b/src/ObjWriting/Techset/CommonTechniqueDumper.h @@ -0,0 +1,9 @@ +#pragma once + +#include "Dumping/AssetDumpingContext.h" +#include "Techset/CommonTechset.h" + +namespace techset +{ + void DumpCommonTechnique(const AssetDumpingContext& context, const CommonTechset& techset); +} // namespace techset diff --git a/src/ObjWriting/Techset/CommonTechsetDumper.cpp b/src/ObjWriting/Techset/CommonTechsetDumper.cpp new file mode 100644 index 00000000..d2c9b9db --- /dev/null +++ b/src/ObjWriting/Techset/CommonTechsetDumper.cpp @@ -0,0 +1,92 @@ +#include "CommonTechsetDumper.h" + +#include "Dumping/AbstractTextDumper.h" +#include "Game/IW3/Material/MaterialConstantZoneStateIW3.h" +#include "Techset/TechsetCommon.h" + +#include + +using namespace techset; + +namespace +{ + class TechsetFileWriter : public AbstractTextDumper + { + public: + TechsetFileWriter(const CommonTechniqueTypeNames& techniqueTypeNames, std::ostream& stream) + : AbstractTextDumper(stream), + m_last_write_was_value(false), + m_technique_type_names(techniqueTypeNames) + { + } + + void DumpTechset(const CommonTechset& techset) + { + const auto techniqueCount = m_technique_type_names.GetTechniqueTypeCount(); + assert(techset.m_technique_names.size() == techniqueCount); + + std::vector dumpedTechniques(techniqueCount); + + for (auto techniqueIndex = 0u; techniqueIndex < techniqueCount; techniqueIndex++) + { + const auto& technique = techset.m_technique_names[techniqueIndex]; + if (technique.empty() || dumpedTechniques[techniqueIndex]) + continue; + + dumpedTechniques[techniqueIndex] = true; + WriteTechniqueType(techniqueIndex); + + for (auto nextTechniqueIndex = techniqueIndex + 1; nextTechniqueIndex < std::extent_v; + nextTechniqueIndex++) + { + if (techset.m_technique_names[nextTechniqueIndex] != technique) + continue; + + dumpedTechniques[nextTechniqueIndex] = true; + WriteTechniqueType(nextTechniqueIndex); + } + + WriteTechniqueValue(technique); + } + } + + private: + void WriteTechniqueType(const size_t techniqueIndex) + { + if (m_last_write_was_value) + { + m_stream << "\n"; + m_last_write_was_value = false; + } + + m_stream << '"' << m_technique_type_names.GetTechniqueTypeName(techniqueIndex) << "\":\n"; + } + + void WriteTechniqueValue(const std::string& value) + { + m_last_write_was_value = true; + + IncIndent(); + Indent(); + m_stream << value << ";\n"; + DecIndent(); + } + + bool m_last_write_was_value; + const CommonTechniqueTypeNames& m_technique_type_names; + }; +} // namespace + +namespace techset +{ + void DumpCommonTechset(const CommonTechniqueTypeNames& techniqueTypeNames, const AssetDumpingContext& context, const CommonTechset& techset) + { + const auto techsetFile = context.OpenAssetFile(GetFileNameForTechsetName(techset.m_name)); + + if (techsetFile) + { + TechsetFileWriter writer(techniqueTypeNames, *techsetFile); + writer.DumpTechset(techset); + } + } +} // namespace techset diff --git a/src/ObjWriting/Techset/CommonTechsetDumper.h b/src/ObjWriting/Techset/CommonTechsetDumper.h new file mode 100644 index 00000000..08d886f4 --- /dev/null +++ b/src/ObjWriting/Techset/CommonTechsetDumper.h @@ -0,0 +1,9 @@ +#pragma once + +#include "Dumping/AssetDumpingContext.h" +#include "Techset/CommonTechset.h" + +namespace techset +{ + void DumpCommonTechset(const CommonTechniqueTypeNames& techniqueTypeNames, const AssetDumpingContext& context, const CommonTechset& techset); +} // namespace techset diff --git a/src/ObjWriting/Techset/TechniqueDumpingZoneState.cpp b/src/ObjWriting/Techset/TechniqueDumpingZoneState.cpp new file mode 100644 index 00000000..7ca2e43d --- /dev/null +++ b/src/ObjWriting/Techset/TechniqueDumpingZoneState.cpp @@ -0,0 +1,13 @@ +#include "TechniqueDumpingZoneState.h" + +namespace techset +{ + bool TechniqueDumpingZoneState::ShouldDumpTechnique(const void* technique) + { + if (m_dumped_techniques.find(technique) != m_dumped_techniques.end()) + return false; + + m_dumped_techniques.emplace(technique); + return true; + } +} // namespace techset diff --git a/src/ObjWriting/Techset/TechniqueDumpingZoneState.h b/src/ObjWriting/Techset/TechniqueDumpingZoneState.h new file mode 100644 index 00000000..06e3aad1 --- /dev/null +++ b/src/ObjWriting/Techset/TechniqueDumpingZoneState.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Dumping/IZoneAssetDumperState.h" + +#include + +namespace techset +{ + class TechniqueDumpingZoneState final : public IZoneAssetDumperState + { + public: + bool ShouldDumpTechnique(const void* technique); + + private: + std::unordered_set m_dumped_techniques; + }; +} // namespace techset