#include "GLSLShader.h" #include GLSLShader::GLSLShader() { Reset(); } GLSLShader::~GLSLShader() { UnloadShaders(); } GLSLShader::GLSLShader(GLSLShader&& other) noexcept { *this = std::move(other); } GLSLShader& GLSLShader::operator=(GLSLShader&& other) noexcept { if (this != &other) { m_program = other.m_program; m_vShader = other.m_vShader; m_fShader = other.m_fShader; uniformLocMap = other.uniformLocMap; attribLocMap = other.attribLocMap; std::copy(std::begin(other.uniformLoc), std::end(other.uniformLoc), std::begin(uniformLoc)); std::copy(std::begin(other.attribLoc), std::end(other.attribLoc), std::begin(attribLoc)); other.Reset(); } return *this; } bool GLSLShader::LoadShaders(const char* vertexShader, const char* fragmentShader) { m_program = glCreateProgram(); m_vShader = glCreateShader(GL_VERTEX_SHADER); m_fShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(m_vShader, 1, &vertexShader, NULL); glShaderSource(m_fShader, 1, &fragmentShader, NULL); glCompileShader(m_vShader); glCompileShader(m_fShader); glAttachShader(m_program, m_vShader); glAttachShader(m_program, m_fShader); glLinkProgram(m_program); PrintShaderInfoLog(m_vShader); PrintShaderInfoLog(m_fShader); PrintProgramInfoLog(m_program); return true; } void GLSLShader::UnloadShaders() { if (m_program) { glDeleteShader(m_vShader); glDeleteShader(m_fShader); glDeleteProgram(m_program); } m_vShader = 0; m_fShader = 0; m_program = 0; } void GLSLShader::EnableShader() { glUseProgram(m_program); } void GLSLShader::DisableShader() { glUseProgram(0); } void GLSLShader::Reset() { m_vShader = 0; m_fShader = 0; m_program = 0; for (auto& i : uniformLoc) { i = -1; } for (auto& i : attribLoc) { i = -1; } uniformLocMap.clear(); attribLocMap.clear(); } void GLSLShader::PrintShaderInfoLog(GLuint obj) { int infologLength = 0; int charsWritten = 0; glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infologLength); if (infologLength > 0) { char* infoLog = new char[infologLength]; glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog); printf("%s\n", infoLog); delete[] infoLog; } } void GLSLShader::PrintProgramInfoLog(GLuint obj) { int infologLength = 0; int charsWritten = 0; glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infologLength); if (infologLength > 0) { char* infoLog = new char[infologLength]; glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog); printf("%s\n", infoLog); delete[] infoLog; } } int GLSLShader::GetUniformLocation(const char* str) { return glGetUniformLocation(m_program, str); } void GLSLShader::GetUniformLocationMap(const char* str) { uniformLocMap[str] = GetUniformLocation(str); } int GLSLShader::GetAttributeLocation(const char* str) { return glGetAttribLocation(m_program, str); } void GLSLShader::GetAttributeLocationMap(const char* str) { attribLocMap[str] = GetAttributeLocation(str); }