#include #include #include "Shader.hpp" Shader::Shader(const char* vertexShaderFileName, const char* fragmentShaderFileName) { shaderId = createShader(vertexShaderFileName, fragmentShaderFileName); } Shader::~Shader() { glDeleteProgram(shaderId); } void Shader::bind() { glUseProgram(shaderId); } void Shader::unbind() { glUseProgram(0); } GLuint Shader::compile(std::string shaderSource, GLenum shaderType) { GLuint id = glCreateShader(shaderType); const char* src = shaderSource.c_str(); glShaderSource(id, 1, &src, nullptr); glCompileShader(id); int result; glGetShaderiv(id, GL_COMPILE_STATUS, &result); if (result == GL_FALSE) { int length = 0; glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); char* message = new char[length]; glGetShaderInfoLog(id, length, &length, message); std::cout << "Shader Compilation Error" << message << std::endl; delete[] message; return 0; } return id; } std::string Shader::parse(const char* filename) { FILE* file; file = fopen(filename, "rb"); if (file == nullptr) { std::cout << "File " << filename << " not found" << std::endl; } std::string contents; fseek(file, 0, SEEK_END); size_t filesize = ftell(file); rewind(file); contents.resize(filesize); fread(&contents[0], 1, filesize, file); fclose(file); return contents; } GLuint Shader::createShader(const char* vertexShaderFileName, const char* fragmentShaderFileName) { std::string vertexShaderSource = parse(vertexShaderFileName); std::string fragmentShaderSource = parse(fragmentShaderFileName); GLuint program = glCreateProgram(); GLuint vert = compile(vertexShaderSource, GL_VERTEX_SHADER); GLuint frag = compile(fragmentShaderSource, GL_FRAGMENT_SHADER); glAttachShader(program, vert); glAttachShader(program, frag); glLinkProgram(program); // ATTENTION: use only for release // NOTE: if you do not detach and delete the program from the gpu, it's easier to debug if errors happen with the shaders // glDetachShader(program, vert); // glDetachShader(program, frag); // glDeleteShader(vert); // glDeleteShader(frag); return program; }