#include <stdio.h>
#include <string.h>
-#include "state_manager.h"
#include "opengl/shader-gl.h"
-extern ShaderProgram *current_program;
-
ShaderGL::ShaderGL()
{
sdr = 0;
fprintf(stderr, "Unknown shader type.\n");
return false;
}
+ name = std::string(fname);
sdr = glCreateShader(stype);
/* compile */
prog = 0;
memset(shaders, 0, sizeof shaders / sizeof *shaders);
- current_program = 0;
is_linked = false;
}
destroy();
}
-void ShaderProgramGL::delete_shaders()
-{
- for(unsigned int i=0; i<(sizeof shaders) / (sizeof *shaders); ++i) {
- delete shaders[i];
- }
-}
-
bool ShaderProgramGL::create()
{
prog = glCreateProgram();
return status ? true : false;
}
-bool ShaderProgramGL::use()
+bool ShaderProgramGL::use() const
{
- if(!is_linked && !link()) {
+ if(!is_linked) {
return false;
}
if(!prog) {
- glUseProgram(0);
- current_program = 0;
+ return false;
}
glUseProgram(prog);
- current_program = this;
-
- static void (*const set_uniform[16])(GLint, GLsizei, const GLfloat *) = {
- 0, glUniform1fv, glUniform2fv, glUniform3fv, glUniform4fv
- };
-
- for(size_t i=0; i<uniforms.size(); i++) {
- const State *st = state_manager.get_state(uniforms[i].state_idx);
- if(st->num < 5) {
- set_uniform[st->num](uniforms[i].location, 1, st->data);
- }
- else if(st->num == 16) {
- glUniformMatrix4fv(uniforms[i].location, 1, GL_TRUE, st->data);
- }
- else {
- fprintf(stderr, "Invalid number of floats in state %s: %d\n", st->name, st->num);
- continue;
- }
- }
return true;
}
glDeleteProgram(prog);
prog = 0;
is_linked = false;
-
- delete_shaders();
}
void ShaderProgramGL::attach_shader(Shader *shader)
glAttachShader(prog, ((ShaderGL *)shader)->sdr);
is_linked = false;
}
-
-int ShaderProgramGL::get_uniform_location(const char *name) const
-{
- if(!((ShaderProgramGL *)this)->use())
- return -1;
-
- return glGetUniformLocation(prog, name);
-}
-
-int ShaderProgramGL::get_attribute_location(const char *name) const
-{
- if(!((ShaderProgramGL *)this)->use())
- return -1;
-
- return glGetAttribLocation(prog, name);
-}
-
-static int get_floats_num(unsigned int utype)
-{
- switch(utype) {
- case GL_FLOAT:
- return 1;
- case GL_FLOAT_VEC2:
- return 2;
- case GL_FLOAT_VEC3:
- return 3;
- case GL_FLOAT_VEC4:
- return 4;
- case GL_FLOAT_MAT2:
- return 4;
- case GL_FLOAT_MAT3:
- return 9;
- case GL_FLOAT_MAT4:
- return 16;
- default:
- break;
- }
-
- return -1;
-}
-
-void ShaderProgramGL::cache_uniforms()
-{
- uniforms.clear();
-
- int num_uniforms;
- glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &num_uniforms);
-
- int max_ulength;
- glGetProgramiv(prog, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_ulength);
-
- char *name = new char[max_ulength + 1];
- name[max_ulength] = 0;
-
- for(int i=0; i<num_uniforms; i++) {
- int usize;
- unsigned int utype;
- glGetActiveUniform(prog, i, max_ulength, 0, &usize, &utype, name);
-
- if(strstr(name, "gl_") == name)
- continue;
-
- if(strstr(name, "st_") != name)
- continue;
-
- int num_floats = get_floats_num(utype);
- if(num_floats == -1)
- continue;
-
- int idx = state_manager.add_state_element(name, num_floats);
- if(idx == -1)
- continue;
-
- Uniform uniform;
- uniform.name = name;
- uniform.location = glGetUniformLocation(prog, name);
- uniform.state_idx = idx;
-
- uniforms.push_back(uniform);
- }
-
- delete [] name;
-}
-
-void ShaderProgramGL::set_uniformi(int location, int value)
-{
- if(!use() || location == -1) {
- return;
- }
-
- glUniform1i(location, value);
-}
-
-void ShaderProgramGL::set_uniformi(int location, int x, int y)
-{
- if(!use() || location == -1) {
- return;
- }
-
- glUniform2i(location, x, y);
-}
-
-void ShaderProgramGL::set_uniformi(int location, int x, int y, int z)
-{
- if(!use() || location == -1) {
- return;
- }
-
- glUniform3i(location, x, y, z);
-}
-
-void ShaderProgramGL::set_uniformi(int location, int x, int y, int z, int w)
-{
- if(!use() || location == -1) {
- return;
- }
-
- glUniform4i(location, x, y, z, w);
-}
-
-void ShaderProgramGL::set_uniformf(int location, float value)
-{
- if(!use() || location == -1) {
- return;
- }
-
- glUniform1f(location, value);
-}
-
-void ShaderProgramGL::set_uniformf(int location, float x, float y)
-{
- if(!use() || location == -1) {
- return;
- }
-
- glUniform2f(location, x, y);
-}
-
-void ShaderProgramGL::set_uniformf(int location, float x, float y, float z)
-{
- if(!use() || location == -1) {
- return;
- }
-
- glUniform3f(location, x, y, z);
-}
-
-void ShaderProgramGL::set_uniformf(int location, float x, float y, float z, float w)
-{
- if(!use() || location == -1) {
- return;
- }
-
- glUniform4f(location, x, y, z, w);
-}
-
-void ShaderProgramGL::set_uniform_matrix(int location, const Mat4 &mat)
-{
- if(!use() || location == -1) {
- fprintf(stderr, "FOO\n");
- return;
- }
-
- glUniformMatrix4fv(location, 1, GL_TRUE, (float *)&mat.m[0][0]);
-}
\ No newline at end of file