5 #include "state_manager.h"
6 #include "opengl/shader-gl.h"
8 extern ShaderProgram *current_program;
20 bool ShaderGL::create(char *buf, unsigned int bsz, const char *fname)
22 /* find shader type and create shader */
26 stype = GL_VERTEX_SHADER;
29 stype = GL_FRAGMENT_SHADER;
32 fprintf(stderr, "Unknown shader type.\n");
35 sdr = glCreateShader(stype);
38 glShaderSource(sdr, 1, (const char **)&buf, 0);
43 /* check compile status */
45 glGetShaderiv(sdr, GL_COMPILE_STATUS, &status);
47 printf("Successfully compiled shader: %s\n", fname);
49 fprintf(stderr, "Failed to compile %s shader.\n", fname);
51 /* print the info log */
53 glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &loglen);
54 if(loglen > 0 && (buf = new char[loglen + 1])) {
55 glGetShaderInfoLog(sdr, loglen, 0, buf);
70 void ShaderGL::destroy()
81 ShaderProgramGL::ShaderProgramGL()
84 memset(shaders, 0, sizeof shaders / sizeof *shaders);
90 ShaderProgramGL::~ShaderProgramGL()
95 void ShaderProgramGL::delete_shaders()
97 for(unsigned int i=0; i<(sizeof shaders) / (sizeof *shaders); ++i) {
102 bool ShaderProgramGL::create()
104 prog = glCreateProgram();
106 fprintf(stderr, "Failed to create shader program.\n");
112 bool ShaderProgramGL::link()
120 glGetProgramiv(prog, GL_LINK_STATUS, &status);
122 printf("Successfully linked shader program.\n");
126 printf("Failed to link shader program.\n");
129 glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &loglen);
132 if(loglen > 0 && (buf = new char[loglen + 1])) {
133 glGetProgramInfoLog(prog, loglen, 0, buf);
139 return status ? true : false;
142 bool ShaderProgramGL::use()
144 if(!is_linked && !link()) {
154 current_program = this;
156 static void (*const set_uniform[16])(GLint, GLsizei, const GLfloat *) = {
157 0, glUniform1fv, glUniform2fv, glUniform3fv, glUniform4fv
160 for(size_t i=0; i<uniforms.size(); i++) {
161 const State *st = state_manager.get_state(uniforms[i].state_idx);
163 set_uniform[st->num](uniforms[i].location, 1, st->data);
165 else if(st->num == 16) {
166 glUniformMatrix4fv(uniforms[i].location, 1, GL_TRUE, st->data);
169 fprintf(stderr, "Invalid number of floats in state %s: %d\n", st->name, st->num);
176 void ShaderProgramGL::destroy()
178 glDeleteProgram(prog);
185 void ShaderProgramGL::attach_shader(Shader *shader)
187 glAttachShader(prog, ((ShaderGL *)shader)->sdr);
191 int ShaderProgramGL::get_uniform_location(const char *name) const
193 if(!((ShaderProgramGL *)this)->use())
196 return glGetUniformLocation(prog, name);
199 int ShaderProgramGL::get_attribute_location(const char *name) const
201 if(!((ShaderProgramGL *)this)->use())
204 return glGetAttribLocation(prog, name);
207 static int get_floats_num(unsigned int utype)
231 void ShaderProgramGL::cache_uniforms()
236 glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &num_uniforms);
239 glGetProgramiv(prog, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_ulength);
241 char *name = new char[max_ulength + 1];
242 name[max_ulength] = 0;
244 for(int i=0; i<num_uniforms; i++) {
247 glGetActiveUniform(prog, i, max_ulength, 0, &usize, &utype, name);
249 if(strstr(name, "gl_") == name)
252 if(strstr(name, "st_") != name)
255 int num_floats = get_floats_num(utype);
259 int idx = state_manager.add_state_element(name, num_floats);
265 uniform.location = glGetUniformLocation(prog, name);
266 uniform.state_idx = idx;
268 uniforms.push_back(uniform);
274 void ShaderProgramGL::set_uniformi(int location, int value)
276 if(!use() || location == -1) {
280 glUniform1i(location, value);
283 void ShaderProgramGL::set_uniformi(int location, int x, int y)
285 if(!use() || location == -1) {
289 glUniform2i(location, x, y);
292 void ShaderProgramGL::set_uniformi(int location, int x, int y, int z)
294 if(!use() || location == -1) {
298 glUniform3i(location, x, y, z);
301 void ShaderProgramGL::set_uniformi(int location, int x, int y, int z, int w)
303 if(!use() || location == -1) {
307 glUniform4i(location, x, y, z, w);
310 void ShaderProgramGL::set_uniformf(int location, float value)
312 if(!use() || location == -1) {
316 glUniform1f(location, value);
319 void ShaderProgramGL::set_uniformf(int location, float x, float y)
321 if(!use() || location == -1) {
325 glUniform2f(location, x, y);
328 void ShaderProgramGL::set_uniformf(int location, float x, float y, float z)
330 if(!use() || location == -1) {
334 glUniform3f(location, x, y, z);
337 void ShaderProgramGL::set_uniformf(int location, float x, float y, float z, float w)
339 if(!use() || location == -1) {
343 glUniform4f(location, x, y, z, w);
346 void ShaderProgramGL::set_uniform_matrix(int location, const Mat4 &mat)
348 if(!use() || location == -1) {
349 fprintf(stderr, "FOO\n");
353 glUniformMatrix4fv(location, 1, GL_TRUE, (float *)&mat.m[0][0]);