#include "ShaderProgram.h" GLuint Shader::CompileShader(GLenum shaderType, std::string fileName) { LOG_INFO("Compiling shader \"%s\"", fileName.c_str()); std::string shaderFile; std::ifstream in(fileName, std::ios::in); if (!in) { LOG_ERROR("Error: Failed to open shader file \"%s\"", fileName.c_str()); return 0; } in.seekg(0, std::ios::end); shaderFile.resize((int)in.tellg()); in.seekg(0, std::ios::beg); in.read(&shaderFile[0], shaderFile.size()); in.close(); GLuint shader = glCreateShader(shaderType); if(GLERROR("glCreateShader")) return 0; const GLchar* shaderFiles = shaderFile.c_str(); const GLint length = shaderFile.length(); glShaderSource(shader, 1, &shaderFiles, &length); if(GLERROR("glShaderSource")) return 0; glCompileShader(shader); GLint compileStatus; glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); if(compileStatus != GL_TRUE) { LOG_ERROR("Shader compilation failed"); GLsizei infoLogLength; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); GLchar* infolog = new GLchar[infoLogLength]; glGetShaderInfoLog(shader, infoLogLength, &infoLogLength, infolog); LOG_ERROR(infolog); delete[] infolog; } if(GLERROR("glCompileShader")) return 0; return shader; } Shader::Shader(GLenum shaderType, std::string fileName) : m_ShaderType(shaderType), m_FileName(fileName) { m_ShaderHandle = 0; } Shader::~Shader() { if (m_ShaderHandle != 0) { glDeleteShader(m_ShaderHandle); } } GLuint Shader::Compile() { m_ShaderHandle = CompileShader(m_ShaderType, m_FileName); return m_ShaderHandle; } GLenum Shader::GetType() const { return m_ShaderType; } std::string Shader::GetFileName() const { return m_FileName; } GLuint Shader::GetHandle() const { return m_ShaderHandle; } bool Shader::IsCompiled() const { return m_ShaderHandle != 0; } ShaderProgram::~ShaderProgram() { if (m_ShaderProgramHandle != 0) { glDeleteProgram(m_ShaderProgramHandle); } } void ShaderProgram::AddShader(std::shared_ptr shader) { m_Shaders.push_back(shader); } void ShaderProgram::Compile() { for (auto &shader : m_Shaders) { if (!shader->IsCompiled()) { shader->Compile(); } } } GLuint ShaderProgram::Link() { if (m_Shaders.size() == 0) { LOG_ERROR("Failed to link shader program: No shaders bound"); return 0; } LOG_INFO("Linking shader program"); m_ShaderProgramHandle = glCreateProgram(); for (auto &shader : m_Shaders) { glAttachShader(m_ShaderProgramHandle, shader->GetHandle()); } glLinkProgram(m_ShaderProgramHandle); if (GLERROR("glLinkProgram")) return 0; m_Shaders.clear(); return m_ShaderProgramHandle; } GLuint ShaderProgram::GetHandle() { return m_ShaderProgramHandle; } void ShaderProgram::Bind() { if (m_ShaderProgramHandle == 0) return; glUseProgram(m_ShaderProgramHandle); } void ShaderProgram::Unbind() { glActiveShaderProgram(0, 0); }