#pragma once #include "OpenGL.h" #include enum GLParamFlag { PARAM_IN, PARAM_OUT, PARAM_UNIFORM, PARAM_CONST, PARAM_NONE, }; struct GLParamItem { std::string name; std::string location; std::string value; GLParamItem(const std::string& _name, int _location, const std::string& _value = "") : name(_name) , value(_value) { if (_location > -1) location = "layout (location = " + std::to_string(_location) + ") "; else location = ""; } }; struct GLParamType { const GLParamFlag flag; std::string type; std::vector items; GLParamType(const GLParamFlag _flag, const std::string& _type) : flag(_flag) , type(_type) { } bool SearchName(const std::string& name) { for (u32 i = 0; i params; GLParamType* SearchParam(const std::string& type) { for (u32 i = 0; iSearchName(name); } std::string AddParam(const GLParamFlag flag, std::string type, const std::string& name, const std::string& value) { type = GetParamFlag(flag) + type; GLParamType* t = SearchParam(type); if (t) { if (!t->SearchName(name)) t->items.emplace_back(name, -1, value); } else { const u32 num = params.size(); params.emplace_back(flag, type); params[num].items.emplace_back(name, -1, value); } return name; } std::string AddParam(const GLParamFlag flag, std::string type, const std::string& name, int location = -1) { type = GetParamFlag(flag) + type; GLParamType* t = SearchParam(type); if (t) { if (!t->SearchName(name)) t->items.emplace_back(name, location); } else { const u32 num = params.size(); params.emplace_back(flag, type); params[num].items.emplace_back(name, location); } return name; } }; class ShaderVar { public: std::string name; std::vector swizzles; ShaderVar() = default; ShaderVar(const std::string& var) { auto var_blocks = fmt::split(var, { "." }); if (var_blocks.size() == 0) { assert(0); } name = var_blocks[0]; if (var_blocks.size() == 1) { swizzles.push_back("xyzw"); } else { swizzles = std::vector(var_blocks.begin() + 1, var_blocks.end()); } } int get_vector_size() const { return swizzles[swizzles.size() - 1].length(); } ShaderVar& symplify() { std::unordered_map swizzle; static std::unordered_map pos_to_swizzle = { { 0, 'x' }, { 1, 'y' }, { 2, 'z' }, { 3, 'w' } }; for (auto &i : pos_to_swizzle) { swizzle[i.second] = swizzles[0].length() > i.first ? swizzles[0][i.first] : 0; } for (int i = 1; i < swizzles.size(); ++i) { std::unordered_map new_swizzle; for (auto &sw : pos_to_swizzle) { new_swizzle[sw.second] = swizzle[swizzles[i].length() <= sw.first ? '\0' : swizzles[i][sw.first]]; } swizzle = new_swizzle; } swizzles.clear(); std::string new_swizzle; for (auto &i : pos_to_swizzle) { if (swizzle[i.second] != '\0') new_swizzle += swizzle[i.second]; } swizzles.push_back(new_swizzle); return *this; } std::string get() const { if (swizzles.size() == 1 && swizzles[0] == "xyzw") { return name; } return name + "." + fmt::merge({ swizzles }, "."); } };