#include "shader.hpp" #include #include #include #include #include #include "dbc.hpp" #include #include #include namespace fs = std::filesystem; inline std::string read_file(const std::string& filename) { // load the file std::ifstream in_file{filename, std::ios::binary}; // get the size of the file std::stringstream in_str; in_str << in_file.rdbuf(); return in_str.str(); } void check_error(const std::string& what, unsigned int thing, GLenum check_type) { int success = 0; char infoLog[512] = {0}; if(check_type == GL_LINK_STATUS) { glGetProgramiv(thing, check_type, &success); if(!success) { glGetProgramInfoLog(thing, 512, NULL, infoLog); dbc::sentinel(std::format("ERROR: Program {} compile failed: {}", what, infoLog)); } } else { glGetShaderiv(thing, check_type, &success); if(!success) { glGetShaderInfoLog(thing, 512, NULL, infoLog); dbc::sentinel(std::format("ERROR: Shader {} compile failed: {}", what, infoLog)); } } } unsigned int Shader::load_shader(const std::string& filename, GLenum shader_type) { dbc::check(fs::exists(filename), std::format("shader file {} does not exist", filename)); // create the shader std::string shader_code = read_file(filename); const char* shader_code_ptr = shader_code.c_str(); int shader_id = glCreateShader(shader_type); glShaderSource(shader_id, 1, &shader_code_ptr, NULL); glCompileShader(shader_id); check_error(filename, shader_id, GL_COMPILE_STATUS); // check compile error return shader_id; } Shader::Shader(const char* vertexPath, const char* fragmentPath) { unsigned int vertex = load_shader(vertexPath, GL_VERTEX_SHADER); unsigned int fragment = load_shader(fragmentPath, GL_FRAGMENT_SHADER); ID = glCreateProgram(); glAttachShader(ID, vertex); glAttachShader(ID, fragment); glLinkProgram(ID); check_error("link", ID, GL_LINK_STATUS); glDeleteShader(vertex); glDeleteShader(fragment); } void Shader::use() const { glUseProgram(ID); } void Shader::cleanup() { glDeleteProgram(ID); } void Shader::setBool(const std::string &name, bool value) const { auto uniform = glGetUniformLocation(ID, name.c_str()); glUniform1i(uniform, (int)value); } void Shader::setInt(const std::string &name, int value) const { auto uniform = glGetUniformLocation(ID, name.c_str()); glUniform1i(uniform, value); } void Shader::setFloat(const std::string &name, float value) const { auto uniform = glGetUniformLocation(ID, name.c_str()); glUniform1f(uniform, value); } void Shader::setVec4(const std::string &name, float v1, float v2, float v3, float v4) const { auto uniform = glGetUniformLocation(ID, name.c_str()); glUniform4f(uniform, v1, v2, v3, v4); } void Shader::setVec4(const std::string &name, const glm::vec4& value) const { auto uniform = glGetUniformLocation(ID, name.c_str()); glUniform4fv(uniform, 1, &value[0]); } void Shader::setVec3(const std::string &name, const glm::vec3& value) const { auto uniform = glGetUniformLocation(ID, name.c_str()); glUniform3fv(uniform, 1, &value[0]); } void Shader::setVec3(const std::string &name, float v1, float v2, float v3) const { auto uniform = glGetUniformLocation(ID, name.c_str()); glUniform3f(uniform, v1, v2, v3); } void Shader::setMat4(const std::string &name, const glm::mat4& mat) const { unsigned int loc = glGetUniformLocation(ID, name.c_str()); glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(mat)); }