100 lines
3.6 KiB
C++
100 lines
3.6 KiB
C++
#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
|