2b917543816cbbf32c5f07be1625f250d9249239
[demo] / src / opengl / shader-gl.cc
1 #include <GL/glew.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "state_manager.h"
6 #include "opengl/shader-gl.h"
7
8 ShaderGL::ShaderGL()
9 {
10         sdr = 0;
11 }
12
13 ShaderGL::~ShaderGL()
14 {
15         destroy();
16 }
17
18 bool ShaderGL::create(char *buf, unsigned int bsz, const char *fname)
19 {
20         /* find shader type and create shader */
21         unsigned int stype;
22         switch(type) {
23         case SDR_VERTEX:
24                 stype = GL_VERTEX_SHADER;
25                 break;
26         case SDR_FRAGMENT:
27                 stype = GL_FRAGMENT_SHADER;
28                 break;
29         default:
30                 fprintf(stderr, "Unknown shader type.\n");
31                 return false;
32         }
33         name = std::string(fname);
34         sdr = glCreateShader(stype);
35
36         /* compile */
37         glShaderSource(sdr, 1, (const char **)&buf, 0);
38         glCompileShader(sdr);
39
40         delete [] buf;
41
42         /* check compile status */
43         int status;
44         glGetShaderiv(sdr, GL_COMPILE_STATUS, &status);
45         if(status)
46                 printf("Successfully compiled shader: %s\n", fname);
47         else
48                 fprintf(stderr, "Failed to compile %s shader.\n", fname);
49
50         /* print the info log */
51         int loglen;
52         glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &loglen);
53         if(loglen > 0 && (buf = new char[loglen + 1])) {
54                 glGetShaderInfoLog(sdr, loglen, 0, buf);
55                 buf[loglen] = 0;
56                 printf("%s\n", buf);
57
58                 delete [] buf;
59         }
60
61         if(!status) {
62                 destroy();
63                 return false;
64         }
65
66         return true;
67 }
68
69 void ShaderGL::destroy()
70 {
71         if(sdr) {
72                 glDeleteShader(sdr);
73         }
74         sdr = 0;
75         type = SDR_UNKNOWN;
76 }
77
78 /* Shader Program */
79
80 ShaderProgramGL::ShaderProgramGL()
81 {
82         prog = 0;
83         memset(shaders, 0, sizeof shaders / sizeof *shaders);
84
85         is_linked = false;
86 }
87
88 ShaderProgramGL::~ShaderProgramGL()
89 {
90         destroy();
91 }
92
93 bool ShaderProgramGL::create()
94 {
95         prog = glCreateProgram();
96         if(!prog) {
97                 fprintf(stderr, "Failed to create shader program.\n");
98                 return false;
99         }
100         return true;
101 }
102
103 bool ShaderProgramGL::link()
104 {
105         if(is_linked)
106                 return true;
107
108         glLinkProgram(prog);
109
110         int status;
111         glGetProgramiv(prog, GL_LINK_STATUS, &status);
112         if(status) {
113                 printf("Successfully linked shader program.\n");
114                 is_linked = true;
115         }
116         else
117                 printf("Failed to link shader program.\n");
118
119         int loglen;
120         glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &loglen);
121
122         char *buf;
123         if(loglen > 0 && (buf = new char[loglen + 1])) {
124                 glGetProgramInfoLog(prog, loglen, 0, buf);
125                 buf[loglen] = 0;
126                 printf("%s\n", buf);
127                 delete [] buf;
128         }
129
130         return status ? true : false;
131 }
132
133 bool ShaderProgramGL::use() const
134 {
135         if(!is_linked) { //&& !link()) {
136                 return false;
137         }
138
139         if(!prog) {
140                 return false;
141         }
142
143         glUseProgram(prog);
144         return true;
145 }
146
147 void ShaderProgramGL::destroy()
148 {
149         glDeleteProgram(prog);
150         prog = 0;
151         is_linked = false;
152 }
153
154 void ShaderProgramGL::attach_shader(Shader *shader)
155 {
156         glAttachShader(prog, ((ShaderGL *)shader)->sdr);
157         is_linked = false;
158 }
159
160 int ShaderProgramGL::get_uniform_location(const char *name) const
161 {
162         if(!use())
163                 return -1;
164
165         return glGetUniformLocation(prog, name);
166 }
167
168 void ShaderProgramGL::set_uniformi(int location, int value)
169 {
170         if(!use() || location == -1) {
171                 return;
172         }
173
174         glUniform1i(location, value);
175 }
176
177 void ShaderProgramGL::set_uniformi(int location, int x, int y)
178 {
179         if(!use() || location == -1) {
180                 return;
181         }
182
183         glUniform2i(location, x, y);
184 }
185
186 void ShaderProgramGL::set_uniformi(int location, int x, int y, int z)
187 {
188         if(!use() || location == -1) {
189                 return;
190         }
191
192         glUniform3i(location, x, y, z);
193 }
194
195 void ShaderProgramGL::set_uniformi(int location, int x, int y, int z, int w)
196 {
197         if(!use() || location == -1) {
198                 return;
199         }
200
201         glUniform4i(location, x, y, z, w);
202 }
203
204 void ShaderProgramGL::set_uniformf(int location, float value)
205 {
206         if(!use() || location == -1) {
207                 return;
208         }
209
210         glUniform1f(location, value);
211 }
212
213 void ShaderProgramGL::set_uniformf(int location, float x, float y)
214 {
215         if(!use() || location == -1) {
216                 return;
217         }
218
219         glUniform2f(location, x, y);
220 }
221
222 void ShaderProgramGL::set_uniformf(int location, float x, float y, float z)
223 {
224         if(!use() || location == -1) {
225                 return;
226         }
227
228         glUniform3f(location, x, y, z);
229 }
230
231 void ShaderProgramGL::set_uniformf(int location, float x, float y, float z, float w)
232 {
233         if(!use() || location == -1) {
234                 return;
235         }
236
237         glUniform4f(location, x, y, z, w);
238 }
239
240 void ShaderProgramGL::set_uniform_matrix(int location, const Mat4 &mat)
241 {
242         if(!use() || location == -1) {
243                 fprintf(stderr, "FOO\n");
244                 return;
245         }
246
247         glUniformMatrix4fv(location, 1, GL_TRUE, (float *)&mat.m[0][0]);
248 }