// external libs #include "glad/glad.h" #include #include #include // project headers #include "shader.hpp" // std libs #include #include #include #include namespace Ogle { Shader::Shader(const char* vertexPath, const char* fragmentPath) { // -- read shaders from file -- std::string vertexCode; std::string fragmentCode; std::ifstream vShaderFile; std::ifstream fShaderFile; // ensure ifstream objects can throw exceptions: vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); try { // open files vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); std::stringstream vShaderStream, fShaderStream; // read file's buffer contents into streams vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); // close file handlers vShaderFile.close(); fShaderFile.close(); // convert stream into string vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch(std::ifstream::failure e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl; } const char* vShaderCode = vertexCode.c_str(); const char* fShaderCode = fragmentCode.c_str(); // -- compile shaders -- unsigned int vertex, fragment; int success; char infoLog[512]; // vertex Shader vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); glCompileShader(vertex); glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); if(!success) { glGetShaderInfoLog(vertex, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; }; // fragment Shader fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); if(!success) { glGetShaderInfoLog(fragment, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; }; // linking shaders this->ID = glCreateProgram(); glAttachShader(ID, vertex); glAttachShader(ID, fragment); glLinkProgram(ID); glGetProgramiv(ID, GL_LINK_STATUS, &success); if(!success) { glGetProgramInfoLog(ID, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } // cleanup uneeded pre-linked shaders glDeleteShader(vertex); glDeleteShader(fragment); } void Shader::use() { glUseProgram(ID); } // -- various setters for shader uniforms -- void Shader::setBool(const std::string &name, bool value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); } void Shader::setInt(const std::string &name, int value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), value); } void Shader::set1f(const std::string &name, float value) const { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } void Shader::set4f(const std::string &name, float value0, float value1, float value2, float value3) const { glUniform4f(glGetUniformLocation(ID, name.c_str()), value0, value1, value2, value3); } void Shader::setMatrix4fv(const std::string &name, glm::mat4 matrix) { glUniformMatrix4fv( glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, glm::value_ptr(matrix) ); } }