mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-24 13:44:58 +00:00
feat(materialx): Add vertex data block handling in shader generation
This commit is contained in:
@@ -10,11 +10,73 @@
|
||||
#include <MaterialXGenShader/Util.h>
|
||||
#include <MaterialXRender/Util.h>
|
||||
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
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<std::string> 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<ILogger> 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user