From 7ec101cbf656484a7e9f927016107ac646c617f8 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Tue, 6 Jan 2026 16:43:34 +0000 Subject: [PATCH] feat(materialx): Add vertex data block handling in shader generation --- .../impl/materialx_shader_generator.cpp | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/services/impl/materialx_shader_generator.cpp b/src/services/impl/materialx_shader_generator.cpp index 3436be3..6485693 100644 --- a/src/services/impl/materialx_shader_generator.cpp +++ b/src/services/impl/materialx_shader_generator.cpp @@ -10,11 +10,73 @@ #include #include +#include #include +#include namespace sdl3cpp::services::impl { namespace mx = MaterialX; +namespace { + +bool HasVertexDataBlock(const std::string& source) { + return source.find("VertexData") != std::string::npos + && source.find("vd;") != std::string::npos; +} + +std::optional ExtractVertexDataBlock(const std::string& source) { + const std::string marker = "VertexData"; + const std::string instance = "vd;"; + size_t blockPos = source.find(marker); + if (blockPos == std::string::npos) { + return std::nullopt; + } + size_t instancePos = source.find(instance, blockPos); + if (instancePos == std::string::npos) { + return std::nullopt; + } + size_t lineStart = source.rfind('\n', blockPos); + if (lineStart == std::string::npos) { + lineStart = 0; + } else { + ++lineStart; + } + size_t lineEnd = source.find('\n', instancePos); + if (lineEnd == std::string::npos) { + lineEnd = source.size(); + } + return source.substr(lineStart, lineEnd - lineStart); +} + +std::string ToVertexOutputBlock(std::string block) { + const std::string inToken = " in VertexData"; + const std::string outToken = " out VertexData"; + size_t tokenPos = block.find(inToken); + if (tokenPos != std::string::npos) { + block.replace(tokenPos, inToken.size(), outToken); + return block; + } + tokenPos = block.find("in VertexData"); + if (tokenPos != std::string::npos) { + block.replace(tokenPos, std::string("in VertexData").size(), "out VertexData"); + } + return block; +} + +void InsertAfterVersion(std::string& source, const std::string& block) { + size_t lineEnd = source.find('\n'); + if (lineEnd == std::string::npos) { + source.append("\n"); + source.append(block); + source.append("\n"); + return; + } + ++lineEnd; + source.insert(lineEnd, block + "\n"); +} + +} // namespace + MaterialXShaderGenerator::MaterialXShaderGenerator(std::shared_ptr logger) : logger_(std::move(logger)) {} @@ -159,6 +221,27 @@ ShaderPaths MaterialXShaderGenerator::Generate(const MaterialXConfig& config, ShaderPaths paths; paths.vertexSource = shader->getSourceCode(mx::Stage::VERTEX); paths.fragmentSource = shader->getSourceCode(mx::Stage::PIXEL); + + const bool vertexHasBlock = HasVertexDataBlock(paths.vertexSource); + const bool fragmentHasBlock = HasVertexDataBlock(paths.fragmentSource); + if (!vertexHasBlock && fragmentHasBlock) { + auto fragmentBlock = ExtractVertexDataBlock(paths.fragmentSource); + if (fragmentBlock) { + std::string vertexBlock = ToVertexOutputBlock(*fragmentBlock); + InsertAfterVersion(paths.vertexSource, vertexBlock); + if (logger_) { + logger_->Trace("MaterialXShaderGenerator", "Generate", + "vertexDataBlock=inserted"); + } + } else if (logger_) { + logger_->Trace("MaterialXShaderGenerator", "Generate", + "vertexDataBlock=missing"); + } + } else if (logger_) { + logger_->Trace("MaterialXShaderGenerator", "Generate", + "vertexDataBlock=" + std::string(vertexHasBlock ? "present" : "absent") + + ", fragmentVertexDataBlock=" + std::string(fragmentHasBlock ? "present" : "absent")); + } return paths; }