#ifndef SHADER_H #define SHADER_H #include #include #include #include #include class Shader { public: // Compiled Shader Program ID unsigned int ID; Shader(const char* vertexPath, const char* fragmentPath) { std::string vertexCode, fragmentCode; std::ifstream vertexFile, fragmentFile; std::cout << vertexPath << std::endl; vertexFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); fragmentFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); try { // Open the files vertexFile.open(vertexPath); fragmentFile.open(fragmentPath); std::stringstream vertexStream, fragmentStream; // Save the contents to our streams vertexStream << vertexFile.rdbuf(); fragmentStream << fragmentFile.rdbuf(); // Close files vertexFile.close(); fragmentFile.close(); // Save the contents to our strings vertexCode = vertexStream.str(); fragmentCode = fragmentStream.str(); // Fix encoding issues, specifically for Linux vertexCode.erase(std::remove(vertexCode.begin(), vertexCode.end(), '\r'), vertexCode.end()); fragmentCode.erase(std::remove(fragmentCode.begin(), fragmentCode.end(), '\r'), fragmentCode.end()); } catch (std::ifstream::failure& e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl; } const char* vertexShaderSource = vertexCode.c_str(); const char* fragmentShaderSource = fragmentCode.c_str(); unsigned int vertexShader; vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); checkCompileErrors(vertexShader, "VERTEX"); unsigned int fragmentShader; fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); checkCompileErrors(fragmentShader, "FRAGMENT"); ID = glCreateProgram(); glAttachShader(ID, vertexShader); glAttachShader(ID, fragmentShader); glLinkProgram(ID); checkCompileErrors(ID, "PROGRAM"); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); } void Use() { glUseProgram(ID); }; // Setters void setBool(const std::string &name, bool value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); } // ------------------------------------------------------------------------ void setInt(const std::string &name, int value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), value); } // ------------------------------------------------------------------------ void setFloat(const std::string &name, float value) const { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } // ------------------------------------------------------------------------ void setVec2(const std::string &name, const glm::vec2 &value) const { glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); } void setVec2(const std::string &name, float x, float y) const { glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y); } // ------------------------------------------------------------------------ void setVec3(const std::string &name, const glm::vec3 &value) const { glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); } void setVec3(const std::string &name, float x, float y, float z) const { glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); } // ------------------------------------------------------------------------ void setVec4(const std::string &name, const glm::vec4 &value) const { glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); } void setVec4(const std::string &name, float x, float y, float z, float w) const { glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w); } // ------------------------------------------------------------------------ void setMat2(const std::string &name, const glm::mat2 &mat) const { glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); } // ------------------------------------------------------------------------ void setMat3(const std::string &name, const glm::mat3 &mat) const { glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); } // ------------------------------------------------------------------------ void setMat4(const std::string &name, const glm::mat4 &mat) const { glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); } private: void checkCompileErrors(unsigned int shader, std::string type) { int success; char infoLog[1024]; if (type != "PROGRAM") { glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(shader, 1024, NULL, infoLog); std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; } } else { glGetProgramiv(shader, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shader, 1024, NULL, infoLog); std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; } } } }; #endif