#include #include #include "rendering/wrapper/Shader.h" #include "gaming-core/wrapper/GL.h" Shader::Shader(const GLchar* vPath, const GLchar* fPath) : vShader(0), fShader(0), program(0) { if(readFileAndCompile(vPath, vShader, GL_VERTEX_SHADER) || readFileAndCompile(fPath, fShader, GL_FRAGMENT_SHADER)) { return; } program = glCreateProgram(); glAttachShader(program, vShader); glAttachShader(program, fShader); glLinkProgram(program); if(GL::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; } } Shader::~Shader() { glDeleteProgram(program); glDeleteShader(vShader); glDeleteShader(fShader); } bool Shader::hasError() const { return vShader == 0 || fShader == 0 || program == 0; } bool Shader::readFileAndCompile(const GLchar* path, GLuint& shader, GLenum shaderType) { GLchar buffer[8192]; if(readFile(buffer, 8192, path)) { return true; } return compile(shader, buffer, shaderType); } bool Shader::readFile(GLchar* buffer, size_t bufferSize, const GLchar* path) const { std::ifstream in; in.open(path); if(in.fail()) { std::cout << "cannot read shader file: '" << path << "'\n"; return true; } in.get(buffer, bufferSize, EOF); return false; } bool Shader::compile(GLuint& shader, const GLchar* code, GLenum shaderType) { shader = glCreateShader(shaderType); glShaderSource(shader, 1, &code, nullptr); glCompileShader(shader); if(GL::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 GLfloat* data) const { glUniformMatrix4fv(glGetUniformLocation(program, name), 1, GL_TRUE, data); } void Shader::setInt(const GLchar* name, GLint data) const { glUniform1i(glGetUniformLocation(program, name), data); }