39 using name_t = std::string;
56 static std::unordered_map<shader::name_t, unsigned int>
shaders;
74 template <
typename... Args>
75 static bool create(
const std::string &shader_name,
76 shader::type type,
const std::string &path,
79 std::vector<unsigned int> compiled_shaders = {};
80 if (!compile_shaders(compiled_shaders, type, path, args...))
82 ERROR(
"shader: error compiling shader {}", path);
87 unsigned int ID = glCreateProgram();
88 std::for_each(compiled_shaders.begin(), compiled_shaders.end(),
89 [&ID](
auto shader) { glAttachShader(ID, shader); });
92 if (!shader::check_compile_errors(ID,
"PROGRAM"))
98 std::for_each(compiled_shaders.begin(), compiled_shaders.end(),
99 [](
auto shader) { glDeleteShader(shader); });
119 template <
typename... Args>
120 static bool create(
const GLchar **feedback_varyings,
int num_varyings,
121 const std::string &shader_name,
122 shader::type type,
const std::string &path,
125 std::vector<unsigned int> compiled_shaders = {};
126 if (!compile_shaders(compiled_shaders, type, path, args...))
128 ERROR(
"shader: error compiling shader {}", path)
133 unsigned int ID = glCreateProgram();
134 std::for_each(compiled_shaders.begin(), compiled_shaders.end(),
135 [&ID](
auto shader) { glAttachShader(ID, shader); });
137 if (feedback_varyings !=
nullptr)
139 glTransformFeedbackVaryings(ID, num_varyings, feedback_varyings,
140 GL_INTERLEAVED_ATTRIBS);
144 if (!shader::check_compile_errors(ID,
"PROGRAM"))
150 std::for_each(compiled_shaders.begin(), compiled_shaders.end(),
151 [](
auto shader) { glDeleteShader(shader); });
157 compile_shaders([[maybe_unused]] std::vector<unsigned int> &compiled)
162 template <
typename... Args>
163 static bool compile_shaders(std::vector<unsigned int> &compiled,
164 shader::type type,
const std::string &path,
169 file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
174 if (!file.is_open())
throw "Cannot open file";
175 std::stringstream stream;
176 stream << file.rdbuf();
180 catch (std::ifstream::failure &e)
182 ERROR(
"shader: error reading shader file: {}", path);
188 ERROR(
"shader: file is empty: {}", path);
192 const char *shader_code = code.c_str();
194 GLenum shader_type_gl;
197 case fragment: shader_type_gl = GL_FRAGMENT_SHADER;
break;
198 case vertex: shader_type_gl = GL_VERTEX_SHADER;
break;
199 case geometry: shader_type_gl = GL_GEOMETRY_SHADER;
break;
200 case compute: shader_type_gl = GL_COMPUTE_SHADER;
break;
201 default: shader_type_gl = 0;
break;
204 unsigned int shader = glCreateShader(shader_type_gl);
205 glShaderSource(shader, 1, &shader_code, NULL);
206 glCompileShader(shader);
207 if (!shader::check_compile_errors(shader,
"SHADER"))
212 compiled.push_back(shader);
213 return compile_shaders(compiled, args...);
222 static unsigned int get_id(shader::name_t shader_name);
234 static bool use(shader::name_t shader_name);
246 static bool set_bool(shader::name_t shader_name,
247 const GLchar *name,
bool value);
256 static bool set_int(shader::name_t shader_name,
const GLchar *name,
266 static bool set_float(shader::name_t shader_name,
267 const GLchar *name,
float value);
276 static bool set_mat4(shader::name_t shader_name,
const GLchar *name,
288 static bool set_vec3(shader::name_t shader_name,
const GLchar *name,
289 float x,
float y,
float z);
298 static bool set_vec3(shader::name_t shader_name,
const GLchar *name,
303 static bool check_compile_errors(
unsigned int shader, std::string type);
static bool set_vec3(shader::name_t shader_name, const GLchar *name, float x, float y, float z)
Set a 3D vector in the shader.
static bool create(const GLchar **feedback_varyings, int num_varyings, const std::string &shader_name, shader::type type, const std::string &path, Args... args)
Create a new shader with feedback varyings.