#include "Shader.h" #include #include #include Shader::Shader(const char* vertexPath, const char* fragmentPath) { std::string vertexCode, fragmentCode; std::ifstream vertexFile, fragmentFile; 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 Shader::Use() const { glUseProgram(ID); }; // Setters 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::setFloat(const std::string &name, float value) const { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } // ------------------------------------------------------------------------ void Shader::setVec2(const std::string &name, const glm::vec2 &value) const { glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); } void Shader::setVec2(const std::string &name, float x, float y) const { glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y); } // ------------------------------------------------------------------------ void Shader::setVec3(const std::string &name, const glm::vec3 &value) const { glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); } void Shader::setVec3(const std::string &name, float x, float y, float z) const { glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); } // ------------------------------------------------------------------------ void Shader::setArr(const std::string &name, const GLint value[], const int &count) const { glUniform1iv(glGetUniformLocation(ID, name.c_str()), count, value); } // ------------------------------------------------------------------------ void Shader::setVec4(const std::string &name, const glm::vec4 &value) const { glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); } void Shader::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 Shader::setMat2(const std::string &name, const glm::mat2 &mat) const { glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); } // ------------------------------------------------------------------------ void Shader::setMat3(const std::string &name, const glm::mat3 &mat) const { glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); } // ------------------------------------------------------------------------ void Shader::setMat4(const std::string &name, const glm::mat4 &mat) const { glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); } void Shader::setDecal(int index, GLint tex, float opacity, const glm::vec4& uvCoords) const { std::string indexStr = std::to_string(index); GLint texLoc = glGetUniformLocation(ID, ("decals[" + indexStr + "].tex").c_str()); if (texLoc != -1) glUniform1i(texLoc, tex); GLint opLoc = glGetUniformLocation(ID, ("decals[" + indexStr + "].opacity").c_str()); if (opLoc != -1) glUniform1f(opLoc, opacity); GLint uvLoc = glGetUniformLocation(ID, ("decals[" + indexStr + "].uvCoords").c_str()); if (uvLoc != -1) { glUniform4fv(uvLoc, 1, &uvCoords[0]); } } void Shader::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; } } }