X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fshaderprogram.cpp;h=68a4767d648f26fc3c5514ac4c3cc8ab1f4dfde2;hp=1f5e9e23a007ffe180796509bf9645ce8c50c306;hb=e35bf651e7ebfe4932e877780bb00397c41a7ec2;hpb=433bde2ed090928b264203c9f422a5b220857120 diff --git a/src/shaderprogram.cpp b/src/shaderprogram.cpp index 1f5e9e2..68a4767 100644 --- a/src/shaderprogram.cpp +++ b/src/shaderprogram.cpp @@ -3,27 +3,58 @@ using namespace IPDF; -ShaderProgram::~ShaderProgram() +/** + * Initialise a shader program using GLSL source files + * @param geometry_file GLSL source for Geometry shader (optional) + * @param vertex_file GLSL source for vertex shader + * @param fragment_file GLSL source for fragment shader + * If a filename is the empty string it will be ignored + */ +bool ShaderProgram::InitialiseShaders(const char * vertex_file, const char * fragment_file, const char * geometry_file) { - for(auto shader : m_shaders) + if (m_valid) { - glDetachShader(m_program, shader.obj); - glDeleteShader(shader.obj); + Error("Shader already valid?"); } + m_program = glCreateProgram(); + if (m_program == 0) + { + Error("glCreateProgram failed"); + m_valid = false; + return m_valid; + } + m_valid = true; + if (geometry_file != NULL && geometry_file[0] != '\0') + m_valid &= AttachShader(geometry_file, GL_GEOMETRY_SHADER); + if (vertex_file != NULL && vertex_file[0] != '\0') + m_valid &= AttachShader(vertex_file, GL_VERTEX_SHADER); + if (fragment_file != NULL && fragment_file[0] != '\0') + m_valid &= AttachShader(fragment_file, GL_FRAGMENT_SHADER); - if (m_program) - glDeleteProgram(m_program); + if (!m_valid) + { + Warn("One or more AttachShader calls failed but we will link the shader anyway"); + } + glLinkProgram(m_program); + return m_valid; } + + /** - * This is only called once, does it need a function? + * Destroy a shader program */ -void ShaderProgram::LazyCreateProgram() +ShaderProgram::~ShaderProgram() { - if (!m_program) + m_valid = false; + for(auto shader = m_shaders.begin(); shader != m_shaders.end(); ++shader) { - m_program = glCreateProgram(); + glDetachShader(m_program, shader->obj); + glDeleteShader(shader->obj); } + + if (m_program) + glDeleteProgram(m_program); } /** @@ -73,6 +104,7 @@ char * ShaderProgram::GetShaderSource(const char * src_file) const bool ShaderProgram::AttachShader(const char * src_file, GLenum type) { GLuint shader_obj = glCreateShader(type); + glObjectLabel(GL_SHADER, shader_obj, -1, src_file); char * src = GetShaderSource(src_file); if (src == NULL) { @@ -90,24 +122,16 @@ bool ShaderProgram::AttachShader(const char * src_file, GLenum type) { char info_log[2048]; - glGetShaderInfoLog(shader_obj, 2048, nullptr, info_log); + glGetShaderInfoLog(shader_obj, 2048, NULL, info_log); Error("Shader compile error (file \"%s\"): %s (type %d)", src_file, info_log, type); return false; } m_shaders.push_back(Shader{type, shader_obj}); - LazyCreateProgram(); // um... why? glAttachShader(m_program, shader_obj); return true; } - -bool ShaderProgram::Link() -{ - glLinkProgram(m_program); - return true; -} - const void ShaderProgram::Use() const { glUseProgram(m_program);