Untitled
unknown
c_cpp
a year ago
3.3 kB
5
Indexable
Never
// ShaderProgram.h #pragma once #include <unordered_map> class ShaderProgram { private: bool deleted = false; std::unordered_map<const char*, int> uniformLocations; public: unsigned int id = 0; using ShaderSrcs = std::initializer_list<const char*>; ShaderProgram() = default; ShaderProgram(ShaderSrcs vertexSrcs, ShaderSrcs fragmentSrcs); ~ShaderProgram(); int getUniformLocation(const char* uniformName); void use(); }; //ShaderProgram.cpp #include <iostream> #include <vector> #include <glad\glad.h> #include "ShaderProgram.h" void checkCompilation(unsigned int shader, GLenum type) { int compiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if (compiled == GL_TRUE) return; int logSize = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); std::vector<char> infoLog(logSize); glGetShaderInfoLog(shader, logSize, NULL, &infoLog[0]); switch (type) { case GL_VERTEX_SHADER: std::cout << "VERTEX_SHADER_ERROR: "; break; case GL_FRAGMENT_SHADER: std::cout << "FRAGMENT_SHADER_ERROR: "; break; default: std::cout << "UNKNOWN_SHADER_ERROR: "; break; } for (char c : infoLog) { std::cout << c; } } void checkLinkage(unsigned int program) { int linked = 0; glGetProgramiv(program, GL_LINK_STATUS, &linked); if (linked == GL_TRUE) return; int logSize = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize); std::vector<char> infoLog(logSize); glGetProgramInfoLog(program, logSize, NULL, &infoLog[0]); std::cout << "LINKAGE_ERROR: "; for (char c : infoLog) { std::cout << c; } } unsigned int createShader(ShaderProgram::ShaderSrcs srcs, GLenum type) { unsigned int shader = glCreateShader(type); glShaderSource(shader, srcs.size(), srcs.begin(), NULL); glCompileShader(shader); checkCompilation(shader, type); return shader; } ShaderProgram::ShaderProgram(ShaderProgram::ShaderSrcs vertexSrcs, ShaderProgram::ShaderSrcs fragmentSrcs) { unsigned int vertexShader = createShader(vertexSrcs, GL_VERTEX_SHADER); unsigned int fragmentShader = createShader(fragmentSrcs, GL_FRAGMENT_SHADER); unsigned int _id = glCreateProgram(); glAttachShader(_id, vertexShader); glAttachShader(_id, fragmentShader); glLinkProgram(_id); checkLinkage(_id); glDetachShader(_id, vertexShader); glDeleteShader(vertexShader); glDetachShader(_id, fragmentShader); glDeleteShader(fragmentShader); this->id = _id; } ShaderProgram::~ShaderProgram() { glDeleteProgram(this->id); this->deleted = true; } int ShaderProgram::getUniformLocation(const char* uniformName) { ShaderProgram& self = *this; if (self.uniformLocations.count(uniformName) == 0) { int loc = glGetUniformLocation(self.id, uniformName); self.uniformLocations[uniformName] = loc; return loc; } else { return self.uniformLocations[uniformName]; } } void ShaderProgram::use() { std::cout << this->deleted << std::endl; if (this->deleted) { std::cout << "ShaderProgram::use: shader is deleted" << std::endl; abort(); } glUseProgram(this->id); }