#include "shader.h" #include #include #include BEGIN_NAMESPACE void check_compile_error(GLuint shaderId) { GLint isCompiled = 0; glGetShaderiv(shaderId, GL_COMPILE_STATUS, &isCompiled); if (isCompiled == GL_FALSE) { GLint maxLength = 0; glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &maxLength); //The maxLength includes the NULL character char errorLog[maxLength]; glGetShaderInfoLog(shaderId, maxLength, &maxLength, &errorLog[0]); std::cout << "Shader error: " << errorLog << std::endl; //Provide the infolog in whatever manor you deem best. //Exit with failure. glDeleteShader(shaderId); //Don't leak the shader. } } shader::shader(const char *vs_content, const char *ps_content) { shader_ids[0] = glCreateShader(GL_VERTEX_SHADER); glShaderSource(shader_ids[0], 1, &vs_content, nullptr); glCompileShader(shader_ids[0]); check_compile_error(shader_ids[0]); shader_ids[1] = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(shader_ids[1], 1, &ps_content, nullptr); glCompileShader(shader_ids[1]); check_compile_error(shader_ids[1]); program_id = glCreateProgram(); glAttachShader(program_id, shader_ids[0]); glAttachShader(program_id, shader_ids[1]); // TODO Adrian: these should come from an external enumeration glBindAttribLocation(program_id, 0, "position"); glBindAttribLocation(program_id, 1, "normal"); glBindAttribLocation(program_id, 2, "texCoords"); glLinkProgram(program_id); glUseProgram(program_id); } shader::~shader() { glDetachShader(program_id, shader_ids[0]); glDetachShader(program_id, shader_ids[1]); glDeleteShader(shader_ids[0]); glDeleteShader(shader_ids[1]); glDeleteProgram(program_id); } void shader::use() const { glUseProgram(program_id); } void shader::unuse() const { glUseProgram(0); } int shader::getUniform(const char *uniformName) { if (uniformCache.count(uniformName) == 0) { uniformCache[uniformName] = glGetUniformLocation(program_id, uniformName); } return uniformCache[uniformName]; } void shader::setMatrix3Uniform(float *matrix, const char *uniformName) { GLint location = getUniform(uniformName); if (location != -1) glUniformMatrix3fv(location, 1, false, matrix); } void shader::setMatrix4Uniform(float *matrix, const char *uniformName) { GLint location = getUniform(uniformName); if (location != -1) glUniformMatrix4fv(location, 1, false, matrix); } void shader::setVec3Uniform(float *value, const char *uniformName) { GLint location = getUniform(uniformName); if (location != -1) glUniform3fv(location, 1, value); } void shader::setVec4Uniform(float *value, const char *uniformName) { GLint location = getUniform(uniformName); if (location != -1) glUniform4fv(location, 1, value); } void shader::setIntUniform(int value, const char *uniformName) { GLint location = getUniform(uniformName); if (location != -1) glUniform1i(location, value); } void shader::setFloatUniform(float value, const char *uniformName) { GLint location = getUniform(uniformName); if (location != -1) glUniform1f(location, value); } END_NAMESPACE