diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperTechniqueSet.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperTechniqueSet.cpp new file mode 100644 index 00000000..e5b0b142 --- /dev/null +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperTechniqueSet.cpp @@ -0,0 +1,106 @@ +#include "AssetDumperTechniqueSet.h" + +#include +#include + +using namespace T6; + +class ShaderZoneState final : public IZoneAssetDumperState +{ +public: + bool ShouldDumpTechnique(const MaterialTechnique* technique) + { + const auto existingTechnique = m_dumped_techniques.find(technique); + if (existingTechnique == m_dumped_techniques.end()) + { + m_dumped_techniques.emplace(technique); + return true; + } + + return false; + } + + bool ShouldDumpPixelShader(const MaterialPixelShader* pixelShader) + { + const auto existingPixelShader = m_dumped_pixel_shaders.find(pixelShader); + if (existingPixelShader == m_dumped_pixel_shaders.end()) + { + m_dumped_pixel_shaders.emplace(pixelShader); + return true; + } + + return false; + } + + bool ShouldDumpVertexShader(const MaterialVertexShader* vertexShader) + { + const auto existingVertexShader = m_dumped_vertex_shaders.find(vertexShader); + if (existingVertexShader == m_dumped_vertex_shaders.end()) + { + m_dumped_vertex_shaders.emplace(vertexShader); + return true; + } + + return false; + } + +private: + std::unordered_set m_dumped_techniques; + std::unordered_set m_dumped_pixel_shaders; + std::unordered_set m_dumped_vertex_shaders; +}; + +bool AssetDumperTechniqueSet::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +void AssetDumperTechniqueSet::DumpPixelShader(const AssetDumpingContext& context, const MaterialPixelShader* pixelShader) +{ + std::ostringstream ss; + ss << "shader_bin/ps_" << pixelShader->name << ".cso"; + + const auto shaderFile = context.OpenAssetFile(ss.str()); + + if (!shaderFile) + return; + + shaderFile->write(pixelShader->prog.loadDef.program, pixelShader->prog.loadDef.programSize); +} + +void AssetDumperTechniqueSet::DumpVertexShader(const AssetDumpingContext& context, const MaterialVertexShader* vertexShader) +{ + std::ostringstream ss; + ss << "shader_bin/vs_" << vertexShader->name << ".cso"; + + const auto shaderFile = context.OpenAssetFile(ss.str()); + + if (!shaderFile) + return; + + shaderFile->write(vertexShader->prog.loadDef.program, vertexShader->prog.loadDef.programSize); +} + +void AssetDumperTechniqueSet::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) +{ + const auto* techniqueSet = asset->Asset(); + auto* shaderState = context.GetZoneAssetDumperState(); + + for (const auto* technique : techniqueSet->techniques) + { + if (!technique || !shaderState->ShouldDumpTechnique(technique)) + continue; + + for (auto passIndex = 0u; passIndex < technique->passCount; passIndex++) + { + const auto* pixelShader = technique->passArray[passIndex].pixelShader; + + if (pixelShader && shaderState->ShouldDumpPixelShader(pixelShader)) + DumpPixelShader(context, pixelShader); + + const auto* vertexShader = technique->passArray[passIndex].vertexShader; + if (vertexShader && shaderState->ShouldDumpVertexShader(vertexShader)) + DumpVertexShader(context, vertexShader); + } + } +} diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperTechniqueSet.h b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperTechniqueSet.h new file mode 100644 index 00000000..5a34305e --- /dev/null +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperTechniqueSet.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/T6/T6.h" + +namespace T6 +{ + class AssetDumperTechniqueSet final : public AbstractAssetDumper + { + static void DumpPixelShader(const AssetDumpingContext& context, const MaterialPixelShader* pixelShader); + static void DumpVertexShader(const AssetDumpingContext& context, const MaterialVertexShader* vertexShader); + + protected: + bool ShouldDump(XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + }; +} // namespace T6 diff --git a/src/ObjWriting/Game/T6/ZoneDumperT6.cpp b/src/ObjWriting/Game/T6/ZoneDumperT6.cpp index e4ac10dd..f187a109 100644 --- a/src/ObjWriting/Game/T6/ZoneDumperT6.cpp +++ b/src/ObjWriting/Game/T6/ZoneDumperT6.cpp @@ -13,6 +13,7 @@ #include "AssetDumpers/AssetDumperSndBank.h" #include "AssetDumpers/AssetDumperSndDriverGlobals.h" #include "AssetDumpers/AssetDumperStringTable.h" +#include "AssetDumpers/AssetDumperTechniqueSet.h" #include "AssetDumpers/AssetDumperTracer.h" #include "AssetDumpers/AssetDumperVehicle.h" #include "AssetDumpers/AssetDumperWeapon.h" @@ -48,7 +49,7 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const // DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts, ASSET_TYPE_XANIMPARTS) DUMP_ASSET_POOL(AssetDumperXModel, m_xmodel, ASSET_TYPE_XMODEL) DUMP_ASSET_POOL(AssetDumperMaterial, m_material, ASSET_TYPE_MATERIAL) - // DUMP_ASSET_POOL(AssetDumperTechniqueSet, m_technique_set, ASSET_TYPE_TECHNIQUE_SET) + DUMP_ASSET_POOL(AssetDumperTechniqueSet, m_technique_set, ASSET_TYPE_TECHNIQUE_SET) DUMP_ASSET_POOL(AssetDumperGfxImage, m_image, ASSET_TYPE_IMAGE) DUMP_ASSET_POOL(AssetDumperSndBank, m_sound_bank, ASSET_TYPE_SOUND) // DUMP_ASSET_POOL(AssetDumperSndPatch, m_sound_patch, ASSET_TYPE_SOUND_PATCH)