#include "graphics/shader.h" #include "utility/logger.h" #include Shader::Shader(const char* vertexPath, const char* fragmentPath) { std::string vertexSource; std::string fragmentSource; std::ifstream vertexStream; std::ifstream fragmentStream; vertexStream.exceptions(std::ifstream::badbit | std::ifstream::failbit); fragmentStream.exceptions(std::ifstream::badbit | std::ifstream::failbit); try { vertexStream.open(vertexPath); fragmentStream.open(fragmentPath); std::stringstream vStringStream, fStringStream; vStringStream << vertexStream.rdbuf(); fStringStream << fragmentStream.rdbuf(); vertexSource = vStringStream.str(); fragmentSource = fStringStream.str(); vertexStream.close(); fragmentStream.close(); } catch(std::exception e) { LOG(ERROR, "failed to open shader files '{}', '{}' error: {}", vertexPath, fragmentPath, e.what()); assert(1 == 0); // force crash } const char* vSource = vertexSource.c_str(); const char* fSource = fragmentSource.c_str(); unsigned int vertexid, fragmentid; char infoLog[512]; int success; //compile vertex shader vertexid = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexid, 1, &vSource, NULL); glCompileShader(vertexid); glGetShaderiv(vertexid, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexid, 512, NULL, infoLog); LOG(ERROR, "VERTEX SHADER '{}' COMPILE ERROR\n{}", vertexPath, infoLog); } //compile fragment shader fragmentid = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentid, 1, &fSource, NULL); glCompileShader(fragmentid); glGetShaderiv(fragmentid, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentid, 512, NULL, infoLog); LOG(ERROR, "FRAGMENT SHADER '{}' COMPILE ERROR\n{}", fragmentPath, infoLog); } //create and link program with compiled shaders ID = glCreateProgram(); glAttachShader(ID, vertexid); glAttachShader(ID, fragmentid); glLinkProgram(ID); glGetProgramiv(ID, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(ID, 512, NULL, infoLog); LOG(ERROR, "PROGRAM LINKER ERROR\n{}", infoLog); } glDeleteShader(vertexid); glDeleteShader(fragmentid); } void Shader::setFloat(const std::string& name, float value) { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } void Shader::setFloatArray(const std::string& name, size_t count, const float* value) { glUniform1fv(glGetUniformLocation(ID, name.c_str()), count, value); } void Shader::setIntArray(const std::string& name, size_t count, const int* value) { glUniform1iv(glGetUniformLocation(ID, name.c_str()), count, value); } void Shader::setInt(const std::string& name, int value) { glUniform1i(glGetUniformLocation(ID, name.c_str()), value); } void Shader::setBool(const std::string& name, bool value) { glUniform1i(glGetUniformLocation(ID, name.c_str()), value); } void Shader::setVec2(const std::string& name, const float* value) { glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, value); } void Shader::setMatrix4f(const std::string& name, const float* value) { GLuint loc = glGetUniformLocation(ID, name.c_str()); glUniformMatrix4fv(loc, 1, GL_FALSE, value); } Shader::~Shader() { glDeleteProgram(ID); }