GLSL Shaders -> Files (instead of #define)
[ipdf/code.git] / src / shaderprogram.cpp
index eb7a82d..1f5e9e2 100644 (file)
@@ -15,6 +15,9 @@ ShaderProgram::~ShaderProgram()
                glDeleteProgram(m_program);
 }
 
+/**
+ * This is only called once, does it need a function?
+ */
 void ShaderProgram::LazyCreateProgram()
 {
        if (!m_program)
@@ -23,42 +26,81 @@ void ShaderProgram::LazyCreateProgram()
        }
 }
 
-bool ShaderProgram::AttachShader(const char *src, GLenum type)
+/**
+ * Get GLSL shader source from a file as a string
+ * @param src_file filename to get the shader source from
+ * @returns a char* string allocated with new[] (remember to delete[] it)
+ */
+char * ShaderProgram::GetShaderSource(const char * src_file) const
+{
+       char * src = NULL;
+       FILE * file = fopen(src_file, "r");
+       if (file == NULL)
+       {
+               Error("Could not open shader source file \"%s\": %s", src_file, strerror(errno));
+               return NULL;
+       }
+       long start = ftell(file);
+
+       if (fseek(file, 0, SEEK_END) != 0)
+       {
+               Error("Couldn't seek to end of file \"%s\": %s", src_file, strerror(errno));
+               return NULL;
+       }
+       long end = ftell(file);
+       if (start < 0 || end < 0 || end < start)
+       {
+               // I bet that now I've put this message here, it will occur at least once in the life of this code
+               Error("Insane results from ftell(3) on file \"%s\"", src_file);
+               return NULL;
+       }
+       size_t size = end - start;
+       src = new char[size+1]; // Warning! Allocation of memory occuring! We might all die!
+       rewind(file);
+       if (fread(src, 1,size, file) != size)
+       {
+               Error("Error in fread on \"%s\": %s", src_file, strerror(errno));
+               fclose(file);
+               delete [] src;
+               return NULL;
+       }
+       src[size] = '\0';
+       fclose(file);
+       return src;
+       
+}
+
+bool ShaderProgram::AttachShader(const char * src_file, GLenum type)
 {
        GLuint shader_obj = glCreateShader(type);
+       char * src = GetShaderSource(src_file);
+       if (src == NULL)
+       {
+               Error("Couldn't get shader source.");
+               return false;
+       }
+       
+
        glShaderSource(shader_obj, 1, &src, 0);
        glCompileShader(shader_obj);
        int did_compile = 0;
        glGetShaderiv(shader_obj, GL_COMPILE_STATUS, &did_compile);
+       delete [] src; // Oh my goodness memory management is hard guys
        if (!did_compile)
        {
                char info_log[2048];
 
                glGetShaderInfoLog(shader_obj, 2048, nullptr, info_log);
-               Error("Shader compile error: %s\n", 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();
+       LazyCreateProgram(); // um... why?
        glAttachShader(m_program, shader_obj);
        return true;
 }
 
-bool ShaderProgram::AttachVertexProgram(const char *src)
-{
-       return AttachShader(src, GL_VERTEX_SHADER);
-}
-
-bool ShaderProgram::AttachFragmentProgram(const char *src)
-{
-       return AttachShader(src, GL_FRAGMENT_SHADER);
-}
-
-bool ShaderProgram::AttachGeometryProgram(const char *src)
-{
-       return AttachShader(src, GL_GEOMETRY_SHADER);
-}
 
 bool ShaderProgram::Link()
 {

UCC git Repository :: git.ucc.asn.au