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);
}
/**
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)
{
{
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);