#include "glclasses.hpp" #include #include #include #include namespace endofthejedi { VAO::VAO() { glGenVertexArrays(1, &m_name); } VAO::~VAO() { glDeleteVertexArrays(1, &m_name); } void VAO::bind() { glBindVertexArray(m_name); } void VAO::unbind() { glBindVertexArray(0); } void VAO::fill(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) { glEnableVertexAttribArray(index); glVertexAttribPointer(index, size, type, normalized, stride, pointer); } Shader::Shader() : m_program(0) { } Shader::~Shader() {} void Shader::init() { m_program = glCreateProgram(); } bool Shader::check() { GLint len = 0; GLint result = 0; glGetProgramiv(m_program, GL_LINK_STATUS, &result); glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &len); if (result == GL_FALSE) { std::cout<<"getting error log:" << std::endl; char *error = (char *)malloc(len+1); glGetProgramInfoLog(m_program, len, NULL, error); std::string str(error); std::cout << str << std::endl; } //std::cout << "checked program" << std::endl; return (bool)result; } bool Shader::checkShader(GLuint shader) { GLint len = 0; GLint result = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &result); if (result == GL_FALSE) { glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); char *error = (char *)malloc(len+1); glGetShaderInfoLog(shader, len, NULL, error); std::string str(error, error + len); std::cout << str << std::endl; } //std::cout << "checked shader" << std::endl; return result != GL_FALSE; } void Shader::bind() { if (m_program == 0) { std::cerr << "error: invalid to bind invalid program (0)! " "use unbind() if that was your purpose!" << std::endl; exit(-1); return; } glUseProgram(m_program); } GLuint Shader::program() { return m_program; } void Shader::unbind() { glUseProgram(0); } void Shader::load(const std::string &data, GLenum shadertype) { if (m_program == 0) { std::cout<<"[shader] error: shader program is invalid (0)!" << std::endl; exit(-1); return; } GLuint shader = glCreateShader(shadertype); const char *shaderdata = data.c_str(); glShaderSource(shader, 1, &shaderdata, NULL); glCompileShader(shader); checkShader(shader); glAttachShader(m_program, shader); glLinkProgram(m_program); check(); glDeleteShader(shader); } void Shader::loadFile(const std::string &path, GLenum shadertype) { std::string content; std::ifstream fileStream(path, std::ios::in); if(!fileStream.is_open()) { std::cerr << "Could not read file " << path << ". File does not exist." << std::endl; return; } std::string line = ""; while(!fileStream.eof()) { std::getline(fileStream, line); content.append(line + "\n"); } fileStream.close(); load(content, shadertype); } GLuint Shader::location(const std::string &name) { return glGetUniformLocation(m_program, name.c_str()); } } void printGlError(GLenum err) { if (err != GL_NO_ERROR) { std::cout << "opengl error is: " << stringFromGlError(err) << std::endl; } } void discardLastGlError(bool print) { GLenum err = glGetError(); if (print) { printGlError(err); } } // return false if there's an error bool checkAndPrintGlError() { GLenum err = glGetError(); printGlError(err); return true; } const char *stringFromGlError(GLenum err) { switch(err) { case GL_INVALID_ENUM: return "GL_INVALID_ENUM"; break; case GL_INVALID_VALUE: return "GL_INVALID_VALUE"; break; case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION"; break; case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY"; break; case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION"; break; default: return ""; break; } }