Add SDL3 GPU backend (Vulkan/Metal) with OpenGL fallback

This commit is contained in:
2026-05-04 11:45:43 +02:00
parent 0a03509323
commit f18d6143d1
42 changed files with 1273 additions and 738 deletions

View File

@@ -0,0 +1,99 @@
#include "rendering/shader_backend.hpp"
#include <algorithm>
#include <fstream>
#include <sstream>
namespace Rendering {
namespace {
auto trimString(const std::string& str) -> std::string {
const std::size_t start = str.find_first_not_of(" \t\r\n");
const std::size_t end = str.find_last_not_of(" \t\r\n");
if (start != std::string::npos && end != std::string::npos) {
return str.substr(start, end - start + 1);
}
return "";
}
} // namespace
auto loadFileToString(const std::filesystem::path& path, std::string& out) -> bool {
std::ifstream ifs(path, std::ios::in | std::ios::binary);
if (!ifs) { return false; }
std::ostringstream ss;
ss << ifs.rdbuf();
out = ss.str();
return true;
}
auto parseMetaFile(const std::filesystem::path& meta_path) -> ShaderMetadata {
ShaderMetadata metadata;
std::ifstream ifs(meta_path);
if (!ifs) { return metadata; }
std::string line;
while (std::getline(ifs, line)) {
const std::size_t colon = line.find(':');
if (colon == std::string::npos) { continue; }
std::string key = line.substr(0, colon);
std::string value = trimString(line.substr(colon + 1));
std::transform(key.begin(), key.end(), key.begin(),
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
key = trimString(key);
if (key == "name") { metadata.name = value; }
else if (key == "author") { metadata.author = value; }
else if (key == "ichannel0") { metadata.iChannel0 = value; }
else if (key == "ichannel1") { metadata.iChannel1 = value; }
else if (key == "ichannel2") { metadata.iChannel2 = value; }
else if (key == "ichannel3") { metadata.iChannel3 = value; }
}
return metadata;
}
auto extractShaderMetadata(const std::string& source) -> ShaderMetadata {
ShaderMetadata metadata;
std::istringstream stream(source);
std::string line;
int line_count = 0;
constexpr int MAX_LINES_TO_CHECK = 30;
while (std::getline(stream, line) && line_count < MAX_LINES_TO_CHECK) {
line_count++;
const std::size_t pos = line.find("//");
if (pos == std::string::npos) { continue; }
const std::string comment = line.substr(pos + 2);
std::string lower = comment;
std::transform(lower.begin(), lower.end(), lower.begin(),
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
auto valueAfterColon = [&]() {
return trimString(comment.substr(comment.find(':') + 1));
};
if (lower.find("name:") != std::string::npos) {
metadata.name = valueAfterColon();
} else if (lower.find("author:") != std::string::npos) {
metadata.author = valueAfterColon();
} else if (lower.find("ichannel0:") != std::string::npos) {
metadata.iChannel0 = valueAfterColon();
} else if (lower.find("ichannel1:") != std::string::npos) {
metadata.iChannel1 = valueAfterColon();
} else if (lower.find("ichannel2:") != std::string::npos) {
metadata.iChannel2 = valueAfterColon();
} else if (lower.find("ichannel3:") != std::string::npos) {
metadata.iChannel3 = valueAfterColon();
}
}
return metadata;
}
} // namespace Rendering