#include #include #include "client/rendering/Shader.h" #include "client/Utils.h" Shader::Shader(const GLchar* vPath, const GLchar* fPath) : valid(false), vShader(0), fShader(0), program(0) { std::vector vCode; std::vector fCode; bool vCheck = readFile(vCode, vPath); bool fCheck = readFile(fCode, fPath); if(vCheck || fCheck) { return; } vCheck = compileShader(vShader, vCode.data(), GL_VERTEX_SHADER); fCheck = compileShader(fShader, fCode.data(), GL_FRAGMENT_SHADER); if(vCheck || fCheck) { return; } program = glCreateProgram(); glAttachShader(program, vShader); glAttachShader(program, fShader); glLinkProgram(program); if(checkAndPrintError("shader linking error")) { return; } GLint linked; glGetProgramiv(program, GL_LINK_STATUS, &linked); if(linked == GL_FALSE) { GLchar buffer[512]; glGetProgramInfoLog(program, 512, nullptr, buffer); std::cout << "programm linking info log: " << buffer << "\n"; return; } valid = true; } Shader::~Shader() { glDeleteProgram(program); glDeleteShader(vShader); glDeleteShader(fShader); } bool Shader::isValid() const { return valid; } bool Shader::readFile(std::vector& buffer, const GLchar* path) const { std::ifstream in; in.open(path); if(in.fail()) { std::cout << "cannot read shader file: '" << path << "'\n"; return true; } while(true) { GLchar c = in.get(); if(in.eof()) { break; } buffer.push_back(c); } buffer.push_back('\0'); return false; } bool Shader::compileShader(GLuint& shader, const GLchar* code, GLenum shaderType) const { shader = glCreateShader(shaderType); glShaderSource(shader, 1, &code, nullptr); glCompileShader(shader); if(checkAndPrintError("shader error")) { return true; } GLint compiled; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if(compiled == GL_FALSE) { GLchar buffer[512]; glGetShaderInfoLog(shader, 512, nullptr, buffer); std::cout << "shader info log: " << buffer << "\n"; return true; } return false; } void Shader::use() const { glUseProgram(program); } void Shader::setMatrix(const GLchar* name, const float* data) const { glUniformMatrix4fv(glGetUniformLocation(program, name), 1, GL_FALSE, data); } void Shader::setInt(const GLchar* name, GLint data) const { glUniform1i(glGetUniformLocation(program, name), data); }