GLSL Shaders -> Files (instead of #define)
[ipdf/code.git] / src / shaderprogram.cpp
1 #include "shaderprogram.h"
2 #include "log.h"
3
4 using namespace IPDF;
5
6 ShaderProgram::~ShaderProgram()
7 {
8         for(auto shader : m_shaders)
9         {
10                 glDetachShader(m_program, shader.obj);
11                 glDeleteShader(shader.obj);
12         }
13
14         if (m_program)
15                 glDeleteProgram(m_program);
16 }
17
18 /**
19  * This is only called once, does it need a function?
20  */
21 void ShaderProgram::LazyCreateProgram()
22 {
23         if (!m_program)
24         {
25                 m_program = glCreateProgram();
26         }
27 }
28
29 /**
30  * Get GLSL shader source from a file as a string
31  * @param src_file filename to get the shader source from
32  * @returns a char* string allocated with new[] (remember to delete[] it)
33  */
34 char * ShaderProgram::GetShaderSource(const char * src_file) const
35 {
36         char * src = NULL;
37         FILE * file = fopen(src_file, "r");
38         if (file == NULL)
39         {
40                 Error("Could not open shader source file \"%s\": %s", src_file, strerror(errno));
41                 return NULL;
42         }
43         long start = ftell(file);
44
45         if (fseek(file, 0, SEEK_END) != 0)
46         {
47                 Error("Couldn't seek to end of file \"%s\": %s", src_file, strerror(errno));
48                 return NULL;
49         }
50         long end = ftell(file);
51         if (start < 0 || end < 0 || end < start)
52         {
53                 // I bet that now I've put this message here, it will occur at least once in the life of this code
54                 Error("Insane results from ftell(3) on file \"%s\"", src_file);
55                 return NULL;
56         }
57         size_t size = end - start;
58         src = new char[size+1]; // Warning! Allocation of memory occuring! We might all die!
59         rewind(file);
60         if (fread(src, 1,size, file) != size)
61         {
62                 Error("Error in fread on \"%s\": %s", src_file, strerror(errno));
63                 fclose(file);
64                 delete [] src;
65                 return NULL;
66         }
67         src[size] = '\0';
68         fclose(file);
69         return src;
70         
71 }
72
73 bool ShaderProgram::AttachShader(const char * src_file, GLenum type)
74 {
75         GLuint shader_obj = glCreateShader(type);
76         char * src = GetShaderSource(src_file);
77         if (src == NULL)
78         {
79                 Error("Couldn't get shader source.");
80                 return false;
81         }
82         
83
84         glShaderSource(shader_obj, 1, &src, 0);
85         glCompileShader(shader_obj);
86         int did_compile = 0;
87         glGetShaderiv(shader_obj, GL_COMPILE_STATUS, &did_compile);
88         delete [] src; // Oh my goodness memory management is hard guys
89         if (!did_compile)
90         {
91                 char info_log[2048];
92
93                 glGetShaderInfoLog(shader_obj, 2048, nullptr, info_log);
94                 Error("Shader compile error (file \"%s\"): %s (type %d)", src_file, info_log, type);
95                 return false;
96         }
97
98         m_shaders.push_back(Shader{type, shader_obj});
99         LazyCreateProgram(); // um... why?
100         glAttachShader(m_program, shader_obj);
101         return true;
102 }
103
104
105 bool ShaderProgram::Link()
106 {
107         glLinkProgram(m_program);
108         return true;
109 }
110
111 const void ShaderProgram::Use() const
112 {
113         glUseProgram(m_program);
114 }
115
116 const GLint ShaderProgram::GetUniformLocation(const char *name) const
117 {
118         return glGetUniformLocation(m_program, name);
119 }

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