glUniform invalid operation mystery

Alec Jacobson

October 02, 2011

weblog/

I burned way too many hours tracking down a foolish bug I had in my GLSL/OpenGL code. The bug had to do with setting uniform variables in my GLSL vertex shader. My shader code looked something like:

uniform mat4 my_matrices[100];
uniform int my_int;
void main()
{
  // ... something using my_int and my_matrices
}
 I would then try to set them in my C++ OpenGL code with: 


glUniformMatrix4fv(my_matrices_location,100,false,my_matrices_data);
glUniform1i(my_int_location,my_int_value);

This should work as long as my_matrices_location and my_int_location are set properly. Here's I was setting them

INCORRECTLY:

// get number of active uniforms
GLint n = 200;
glGetProgramiv(my_prog_id,GL_ACTIVE_UNIFORMS,&n);
// get max uniform name length
GLint max_name_length;
glGetProgramiv(my_prog_id,GL_ACTIVE_UNIFORM_MAX_LENGTH,&max_name_length);
// buffer for name
GLchar * name = new GLchar[max_name_length];
// buffer for length
GLsizei length = 100;
// Type of variable
GLenum type;
// Count of variables
GLint size;
// loop over active uniforms getting each's name
for(GLuint u = 0;u < n;u++)
{
  glGetActiveUniform(my_prog_id,u,max_name_length,&length,&size,&type,name);
  if(string(name) == "my_matrices[0]")
  {
    my_matrices_location = u;
  }else if(string(name) == "my_int")
  {
    my_int_location = u;
  }
}

The mistake is that I'm confusing the variable's index which I pass to glGetActiveUniform with it's location which cannot be retrieved by glGetActiveUniform. Instead I need to retrieve the variable's location with glGetUniformLocation. Here's how I'm now setting my uniform variable locations CORRECTLY:

my_matrices_location = glGetUniformLocation(my_prog_id,"my_matrices[0]");
my_int_location = glGetUniformLocation(my_prog_id,"my_int");