diff --git a/src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h b/src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h index 48f3be31..72237e82 100644 --- a/src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h +++ b/src/ObjCommon/Game/T6/Techset/TechsetConstantsT6.h @@ -1,7 +1,7 @@ #pragma once -#include "Game/T6/CommonT6.h" #include "Game/T6/T6.h" +#include "Techset/CommonTechnique.h" namespace T6 { @@ -45,57 +45,158 @@ namespace T6 }; static_assert(std::extent_v == TECHNIQUE_COUNT); - static const char* materialStreamDestinationNames[]{ - "position", "normal", "color[0]", "color[1]", "depth", "texcoord[0]", "texcoord[1]", - "texcoord[2]", "texcoord[3]", "texcoord[4]", "texcoord[5]", "texcoord[6]", "texcoord[7]", "texcoord[8]", - "texcoord[9]", "texcoord[10]", "texcoord[11]", "texcoord[12]", "texcoord[13]", "blendWeight", + static techset::CommonStreamRoutingSourceInfo streamRoutingSources[]{ + { + .name = "position", + .abbreviation = "p", + .optional = false, + }, + { + .name = "color", + .abbreviation = "c", + .optional = false, + }, + { + .name = "texcoord[0]", + .abbreviation = "t0", + .optional = false, + }, + { + .name = "normal", + .abbreviation = "n", + .optional = false, + }, + { + .name = "tangent", + .abbreviation = "t", + .optional = false, + }, + { + .name = "texcoord[1]", + .abbreviation = "t1", + .optional = false, + }, + { + .name = "texcoord[2]", + .abbreviation = "t2", + .optional = true, + }, + { + .name = "texcoord[3]", + .abbreviation = "t3", + .optional = true, + }, + { + .name = "normalTransform[0]", + .abbreviation = "n0", + .optional = true, + }, + { + .name = "normalTransform[1]", + .abbreviation = "n1", + .optional = true, + }, + { + .name = "blendWeight", + .abbreviation = "b", + .optional = true, + }, }; - static_assert(std::extent_v == STREAM_DST_COUNT); + static_assert(std::extent_v == STREAM_SRC_COUNT); - static const char* materialStreamDestinationAbbreviation[]{ - "p", "n", "c0", "c1", "d", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "t13", "b", + static techset::CommonStreamRoutingDestinationInfo streamRoutingDestinations[]{ + { + .name = "position", + .abbreviation = "p", + }, + { + .name = "normal", + .abbreviation = "n", + }, + { + .name = "color[0]", + .abbreviation = "c0", + }, + { + .name = "color[1]", + .abbreviation = "c1", + }, + { + .name = "depth", + .abbreviation = "d", + }, + { + .name = "texcoord[0]", + .abbreviation = "t0", + }, + { + .name = "texcoord[1]", + .abbreviation = "t1", + }, + { + .name = "texcoord[2]", + .abbreviation = "t2", + }, + { + .name = "texcoord[3]", + .abbreviation = "t3", + }, + { + .name = "texcoord[4]", + .abbreviation = "t4", + }, + { + .name = "texcoord[5]", + .abbreviation = "t5", + }, + { + .name = "texcoord[6]", + .abbreviation = "t6", + }, + { + .name = "texcoord[7]", + .abbreviation = "t7", + }, + { + .name = "texcoord[8]", + .abbreviation = "t8", + }, + { + .name = "texcoord[9]", + .abbreviation = "t9", + }, + { + .name = "texcoord[10]", + .abbreviation = "t10", + }, + { + .name = "texcoord[11]", + .abbreviation = "t11", + }, + { + .name = "texcoord[12]", + .abbreviation = "t12", + }, + { + .name = "texcoord[13]", + .abbreviation = "t13", + }, + { + .name = "blendWeight", + .abbreviation = "b", + }, }; - static_assert(std::extent_v == STREAM_DST_COUNT); - - static const char* materialStreamSourceNames[]{ - "position", - "color", - "texcoord[0]", - "normal", - "tangent", - "texcoord[1]", - "texcoord[2]", - "texcoord[3]", - "normalTransform[0]", - "normalTransform[1]", - "blendWeight", - }; - static_assert(std::extent_v == STREAM_SRC_COUNT); - - static const char* materialStreamSourceAbbreviation[]{ - "p", - "c", - "t0", - "n", - "t", - "t1", - "t2", - "t3", - "n0", - "n1", - "b", - }; - static_assert(std::extent_v == STREAM_SRC_COUNT); + static_assert(std::extent_v == STREAM_DST_COUNT); inline MaterialTypeInfo g_materialTypeInfo[]{ - {"", "" }, - {"m/", "m_" }, - {"mc/", "mc_"}, - {"?", "?" }, - {"wc/", "wc_"}, - {"?", "?" }, - {"?", "?" }, - {"?", "?" }, - }; // TODO: Fill this + {"", "" }, + {"m/", "m_" }, + {"mc/", "mc_" }, + {"mlv/", "mlv_"}, + {"wc/", "wc_" }, + {"wpc/", "wpc_"}, + {"wq/", "wq_" }, + {"wqc/", "wqc_"}, + }; static_assert(std::extent_v == MTL_TYPE_COUNT); } // namespace T6 diff --git a/src/ObjCommon/Techset/CommonTechnique.cpp b/src/ObjCommon/Techset/CommonTechnique.cpp index e69de29b..135e7a35 100644 --- a/src/ObjCommon/Techset/CommonTechnique.cpp +++ b/src/ObjCommon/Techset/CommonTechnique.cpp @@ -0,0 +1,55 @@ +#include "CommonTechnique.h" + +namespace techset +{ + CommonStreamRoutingInfos::CommonStreamRoutingInfos(const CommonStreamRoutingSourceInfo* sourceInfos, + const size_t sourceCount, + const CommonStreamRoutingDestinationInfo* destinationNames, + const size_t destinationCount) + : m_sources(sourceCount), + m_destinations(destinationCount) + { + std::copy(sourceInfos, &sourceInfos[sourceCount], m_sources.data()); + std::copy(destinationNames, &destinationNames[destinationCount], m_destinations.data()); + } + + const char* CommonStreamRoutingInfos::GetSourceName(const CommonStreamSource source) const + { + if (source >= m_sources.size()) + return nullptr; + + return m_sources[source].name; + } + + const char* CommonStreamRoutingInfos::GetSourceAbbreviation(const CommonStreamSource source) const + { + if (source >= m_sources.size()) + return nullptr; + + return m_sources[source].abbreviation; + } + + bool CommonStreamRoutingInfos::IsSourceOptional(const CommonStreamSource source) const + { + if (source >= m_sources.size()) + return false; + + return m_sources[source].optional; + } + + const char* CommonStreamRoutingInfos::GetDestinationName(const CommonStreamDestination destination) const + { + if (destination >= m_destinations.size()) + return nullptr; + + return m_destinations[destination].name; + } + + const char* CommonStreamRoutingInfos::GetDestinationAbbreviation(const CommonStreamDestination destination) const + { + if (destination >= m_destinations.size()) + return nullptr; + + return m_destinations[destination].abbreviation; + } +} // namespace techset diff --git a/src/ObjCommon/Techset/CommonTechnique.h b/src/ObjCommon/Techset/CommonTechnique.h index 5f5a4835..928f1e24 100644 --- a/src/ObjCommon/Techset/CommonTechnique.h +++ b/src/ObjCommon/Techset/CommonTechnique.h @@ -6,6 +6,54 @@ namespace techset { + struct CommonStreamRoutingSourceInfo + { + const char* name; + const char* abbreviation; + bool optional; + }; + + struct CommonStreamRoutingDestinationInfo + { + const char* name; + const char* abbreviation; + }; + + typedef std::uint8_t CommonStreamSource; + typedef std::uint8_t CommonStreamDestination; + + class CommonStreamRoutingInfos + { + public: + CommonStreamRoutingInfos(const CommonStreamRoutingSourceInfo* sourceInfos, + size_t sourceCount, + const CommonStreamRoutingDestinationInfo* destinationNames, + size_t destinationCount); + + [[nodiscard]] const char* GetSourceName(CommonStreamSource source) const; + [[nodiscard]] const char* GetSourceAbbreviation(CommonStreamSource source) const; + [[nodiscard]] bool IsSourceOptional(CommonStreamSource source) const; + [[nodiscard]] const char* GetDestinationName(CommonStreamDestination destination) const; + [[nodiscard]] const char* GetDestinationAbbreviation(CommonStreamDestination destination) const; + + private: + std::vector m_sources; + std::vector m_destinations; + }; + + class CommonStreamRouting + { + public: + CommonStreamSource m_source; + CommonStreamDestination m_destination; + }; + + class CommonVertexDeclaration + { + public: + std::vector m_routing; + }; + class CommonTechniqueShader { public: @@ -27,6 +75,7 @@ namespace techset DxVersion m_dx_version; CommonTechniqueShader m_vertex_shader; CommonTechniqueShader m_pixel_shader; + CommonVertexDeclaration m_vertex_declaration; }; class CommonTechnique diff --git a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp index e3327ec7..e2191c59 100644 --- a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp @@ -99,6 +99,28 @@ namespace } } + techset::CommonVertexDeclaration ConvertToCommonVertexDeclaration(const MaterialVertexDeclaration* vertexDecl) + { + std::vector commonRouting; + + if (vertexDecl) + { + const auto streamCount = std::min(static_cast(vertexDecl->streamCount), std::extent_v); + for (auto streamIndex = 0u; streamIndex < streamCount; streamIndex++) + { + const auto& routing = vertexDecl->routing.data[streamIndex]; + commonRouting.emplace_back(techset::CommonStreamRouting{ + .m_source = static_cast(routing.source), + .m_destination = static_cast(routing.dest), + }); + } + } + + return techset::CommonVertexDeclaration{ + .m_routing = std::move(commonRouting), + }; + } + techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique) { std::vector passes; @@ -139,6 +161,7 @@ namespace .m_dx_version = techset::DxVersion::DX11, .m_vertex_shader = vertexShader, .m_pixel_shader = pixelShader, + .m_vertex_declaration = ConvertToCommonVertexDeclaration(pass.vertexDecl), }); } @@ -151,6 +174,9 @@ namespace void DumpTechniques(AssetDumpingContext& context, const MaterialTechniqueSet& techset) { + static techset::CommonStreamRoutingInfos routingInfos( + streamRoutingSources, std::extent_v, streamRoutingDestinations, std::extent_v); + auto* techniqueState = context.GetZoneAssetDumperState(); for (const auto* technique : techset.techniques) { @@ -158,7 +184,7 @@ namespace { const auto commonTechnique = ConvertToCommonTechnique(*technique); - techset::DumpCommonTechnique(context, commonTechnique); + techset::DumpCommonTechnique(routingInfos, context, commonTechnique); } } } diff --git a/src/ObjWriting/Techset/CommonTechniqueDumper.cpp b/src/ObjWriting/Techset/CommonTechniqueDumper.cpp index 9e497da5..a76358a1 100644 --- a/src/ObjWriting/Techset/CommonTechniqueDumper.cpp +++ b/src/ObjWriting/Techset/CommonTechniqueDumper.cpp @@ -21,8 +21,9 @@ namespace class TechniqueFileWriter : public AbstractTextDumper { public: - explicit TechniqueFileWriter(std::ostream& stream) - : AbstractTextDumper(stream) + TechniqueFileWriter(const CommonStreamRoutingInfos& routingInfos, std::ostream& stream) + : AbstractTextDumper(stream), + m_routing_infos(routingInfos) { } @@ -66,9 +67,9 @@ namespace #endif DumpStateMap(); - DumpShader(pass, pass.m_vertex_shader, TechniqueShaderType::VERTEX_SHADER); - DumpShader(pass, pass.m_pixel_shader, TechniqueShaderType::PIXEL_SHADER); - // DumpVertexDecl(pass); + DumpShader(pass.m_vertex_shader, TechniqueShaderType::VERTEX_SHADER, pass.m_dx_version); + DumpShader(pass.m_pixel_shader, TechniqueShaderType::PIXEL_SHADER, pass.m_dx_version); + DumpVertexDecl(pass.m_vertex_declaration); DecIndent(); m_stream << "}\n"; @@ -82,7 +83,7 @@ namespace m_stream << "stateMap \"passthrough\"; // TODO\n"; } - void DumpShader(const CommonPass& pass, const CommonTechniqueShader& shader, const TechniqueShaderType shaderType) const + void DumpShader(const CommonTechniqueShader& shader, const TechniqueShaderType shaderType, const DxVersion dxVersion) const { if (!shader.m_shader_bin) { @@ -93,7 +94,7 @@ namespace } unsigned versionMajor, versionMinor; - if (pass.m_dx_version == DxVersion::DX9) + if (dxVersion == DxVersion::DX9) { const auto shaderInfo = d3d9::ShaderAnalyser::GetShaderInfo(shader.m_shader_bin, shader.m_shader_bin_size); assert(shaderInfo); @@ -105,7 +106,7 @@ namespace } else { - assert(pass.m_dx_version == DxVersion::DX11); + assert(dxVersion == DxVersion::DX11); const auto shaderInfo = d3d11::ShaderAnalyser::GetShaderInfo(shader.m_shader_bin, shader.m_shader_bin_size); assert(shaderInfo); if (!shaderInfo) @@ -126,17 +127,34 @@ namespace Indent(); m_stream << "}\n"; } + + void DumpVertexDecl(const CommonVertexDeclaration& vertexDeclaration) const + { + if (vertexDeclaration.m_routing.empty()) + return; + + m_stream << "\n"; + + for (const auto& routing : vertexDeclaration.m_routing) + { + Indent(); + m_stream << std::format( + "vertex.{} = code.{};\n", m_routing_infos.GetDestinationName(routing.m_destination), m_routing_infos.GetSourceName(routing.m_source)); + } + } + + const CommonStreamRoutingInfos& m_routing_infos; }; } // namespace namespace techset { - void DumpCommonTechnique(const AssetDumpingContext& context, const CommonTechnique& technique) + void DumpCommonTechnique(const CommonStreamRoutingInfos& routingInfos, const AssetDumpingContext& context, const CommonTechnique& technique) { const auto techniqueFile = context.OpenAssetFile(GetFileNameForTechniqueName(technique.m_name)); if (techniqueFile) { - TechniqueFileWriter writer(*techniqueFile); + TechniqueFileWriter writer(routingInfos, *techniqueFile); writer.DumpTechnique(technique); } } diff --git a/src/ObjWriting/Techset/CommonTechniqueDumper.h b/src/ObjWriting/Techset/CommonTechniqueDumper.h index d541414a..3794d71d 100644 --- a/src/ObjWriting/Techset/CommonTechniqueDumper.h +++ b/src/ObjWriting/Techset/CommonTechniqueDumper.h @@ -5,5 +5,5 @@ namespace techset { - void DumpCommonTechnique(const AssetDumpingContext& context, const CommonTechnique& technique); + void DumpCommonTechnique(const CommonStreamRoutingInfos& routingInfos, const AssetDumpingContext& context, const CommonTechnique& technique); } // namespace techset