DeerEngine/Deer/src/DeerRender/Shader/ShaderDataStore.cpp

61 lines
1.7 KiB
C++

#include "DeerRender/Shader.h"
#include "Deer/DataStore.h"
#include <unordered_map>
namespace Deer {
namespace DataStore {
std::unordered_map<std::string, std::string> preProcess(const std::string& source);
}
void DataStore::loadShader(ShaderData& shader_data, const Path& name) {
Path realName;
realName = name.string() + DEER_SHADER_EXTENSION;
uint32_t size;
uint8_t* data = DataStore::readFile(realName, &size);
DataStore::loadFileData(DEER_SHADER_PATH, realName, &data, &size);
std::string str_data((char*)data, size);
DataStore::freeFileData(data);
std::unordered_map<std::string, std::string> types = preProcess(str_data);
shader_data.freeData();
if (types.contains("vertex")) {
shader_data.vertexShader = types["vertex"];
}
if (types.contains("fragment")) {
shader_data.fragmentShader = types["fragment"];
}
}
std::unordered_map<std::string, std::string> preProcess(const std::string& source) {
std::unordered_map<std::string, std::string> shaderSource;
const std::string typeToken = "#type ";
size_t pos = 0;
while (pos < source.size()) {
size_t typePos = source.find(typeToken, pos);
if (typePos == std::string::npos) break;
size_t typeEnd = source.find_first_of("\n\r", typePos);
if (typeEnd == std::string::npos) break;
std::string shaderType = source.substr(typePos + typeToken.size(), typeEnd - typePos - typeToken.size());
size_t nextTypePos = source.find(typeToken, typeEnd);
std::string shaderSourceStr = source.substr(typeEnd + 1, nextTypePos - typeEnd - 1);
shaderSource[shaderType] = shaderSourceStr;
pos = nextTypePos;
}
return shaderSource;
}
}