#include "shader.h" #include #include #include #include #include #include #include Shader::Shader(const char* vertexPath, const char* fragmentPath) { 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) { spdlog::error("SHADER::FILE_NOT_SUCCESFULLY_READ"); return; } const char* vShaderCode = vertexCode.c_str(); const char* fShaderCode = fragmentCode.c_str(); unsigned int vertex, fragment; int success; char infoLog[512]; // vertex Shader vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); glCompileShader(vertex); // print compile errors if any glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertex, 512, NULL, infoLog); spdlog::error("SHADER::VERTEX::COMPILATION_FAILED {}", infoLog); return; }; // similiar for Fragment Shader fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); // print compile errors if any glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertex, 512, NULL, infoLog); spdlog::error("SHADER::FRAGMENT::COMPILATION_FAILED {}", infoLog); return; }; // shader Program ID = glCreateProgram(); glAttachShader(ID, vertex); glAttachShader(ID, fragment); glLinkProgram(ID); // print linking errors if any glGetProgramiv(ID, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(ID, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; return; } // delete the shaders as they're linked into our program now and no longer necessary glDeleteShader(vertex); glDeleteShader(fragment); compiled = true; } void Shader::use() { if (!compiled) { spdlog::error("Shader not compiler. Exiting"); return; } glUseProgram(ID); } void Shader::set4f(const std::string& uniform, float val1, float val2, float val3, float val4) { glUniform4f(glGetUniformLocation(ID, uniform.c_str()), val1, val2, val3, val4); } void Shader::setFloat(const char* name, float value, bool useShader) { if (useShader) this->use(); glUniform1f(glGetUniformLocation(this->ID, name), value); } void Shader::setInteger(const char* name, int value, bool useShader) { if (useShader) this->use(); glUniform1i(glGetUniformLocation(this->ID, name), value); } void Shader::setVector2f(const char* name, float x, float y, bool useShader) { if (useShader) this->use(); glUniform2f(glGetUniformLocation(this->ID, name), x, y); } void Shader::setVector2f(const char* name, const glm::vec2& value, bool useShader) { if (useShader) this->use(); glUniform2f(glGetUniformLocation(this->ID, name), value.x, value.y); } void Shader::setVector3f(const char* name, float x, float y, float z, bool useShader) { if (useShader) this->use(); glUniform3f(glGetUniformLocation(this->ID, name), x, y, z); } void Shader::setVector3f(const char* name, const glm::vec3& value, bool useShader) { if (useShader) this->use(); glUniform3f(glGetUniformLocation(this->ID, name), value.x, value.y, value.z); } void Shader::setVector4f(const char* name, float x, float y, float z, float w, bool useShader) { if (useShader) this->use(); glUniform4f(glGetUniformLocation(this->ID, name), x, y, z, w); } void Shader::setVector4f(const char* name, const glm::vec4& value, bool useShader) { if (useShader) this->use(); glUniform4f(glGetUniformLocation(this->ID, name), value.x, value.y, value.z, value.w); } void Shader::setMatrix4(const char* name, const glm::mat4& matrix, bool useShader) { if (useShader) this->use(); glUniformMatrix4fv(glGetUniformLocation(this->ID, name), 1, false, glm::value_ptr(matrix)); }