1 #include "shaderprogram.h"
7 * Initialise a shader program using GLSL source files
8 * @param geometry_file GLSL source for Geometry shader (optional)
9 * @param vertex_file GLSL source for vertex shader
10 * @param fragment_file GLSL source for fragment shader
11 * If a filename is the empty string it will be ignored
13 bool ShaderProgram::InitialiseShaders(const char * vertex_file, const char * fragment_file, const char * geometry_file)
17 Error("Shader already valid?");
19 m_program = glCreateProgram();
22 Error("glCreateProgram failed");
27 if (geometry_file != NULL && geometry_file[0] != '\0')
28 m_valid &= AttachShader(geometry_file, GL_GEOMETRY_SHADER);
29 if (vertex_file != NULL && vertex_file[0] != '\0')
30 m_valid &= AttachShader(vertex_file, GL_VERTEX_SHADER);
31 if (fragment_file != NULL && fragment_file[0] != '\0')
32 m_valid &= AttachShader(fragment_file, GL_FRAGMENT_SHADER);
36 Warn("One or more AttachShader calls failed but we will link the shader anyway");
38 glLinkProgram(m_program);
45 * Destroy a shader program
47 ShaderProgram::~ShaderProgram()
50 for(auto shader = m_shaders.begin(); shader != m_shaders.end(); ++shader)
52 glDetachShader(m_program, shader->obj);
53 glDeleteShader(shader->obj);
57 glDeleteProgram(m_program);
61 * Get GLSL shader source from a file as a string
62 * @param src_file filename to get the shader source from
63 * @returns a char* string allocated with new[] (remember to delete[] it)
65 char * ShaderProgram::GetShaderSource(const char * src_file) const
68 FILE * file = fopen(src_file, "r");
71 Error("Could not open shader source file \"%s\": %s", src_file, strerror(errno));
74 long start = ftell(file);
76 if (fseek(file, 0, SEEK_END) != 0)
78 Error("Couldn't seek to end of file \"%s\": %s", src_file, strerror(errno));
81 long end = ftell(file);
82 if (start < 0 || end < 0 || end < start)
84 // I bet that now I've put this message here, it will occur at least once in the life of this code
85 Error("Insane results from ftell(3) on file \"%s\"", src_file);
88 size_t size = end - start;
89 src = new char[size+1]; // Warning! Allocation of memory occuring! We might all die!
91 if (fread(src, 1,size, file) != size)
93 Error("Error in fread on \"%s\": %s", src_file, strerror(errno));
104 bool ShaderProgram::AttachShader(const char * src_file, GLenum type)
106 GLuint shader_obj = glCreateShader(type);
107 char * src = GetShaderSource(src_file);
110 Error("Couldn't get shader source.");
115 glShaderSource(shader_obj, 1, &src, 0);
116 glCompileShader(shader_obj);
118 glGetShaderiv(shader_obj, GL_COMPILE_STATUS, &did_compile);
119 delete [] src; // Oh my goodness memory management is hard guys
124 glGetShaderInfoLog(shader_obj, 2048, NULL, info_log);
125 Error("Shader compile error (file \"%s\"): %s (type %d)", src_file, info_log, type);
129 m_shaders.push_back(Shader{type, shader_obj});
130 glAttachShader(m_program, shader_obj);
134 const void ShaderProgram::Use() const
136 glUseProgram(m_program);
139 const GLint ShaderProgram::GetUniformLocation(const char *name) const
141 return glGetUniformLocation(m_program, name);