Getting a list of active uniform variables
While it is a simple process to query for the location of an individual uniform variable, there may be instances where it can be useful to generate a list of all active uniform variables. For example, one might choose to create a set of variables to store the location of each uniform and assign their values after the program is linked. This would avoid the need to query for uniform locations when setting the value of the uniform variables, creating slightly more efficient code.
Getting ready
We'll start with a basic OpenGL program that compiles and links a shader program. You could use the shaders from the recipe Sending data to a shader using per-vertex attributes and vertex buffer objects. In the following example, we'll assume that the handle to the program is in a variable named programHandle
.
How to do it...
After linking the shader program, use the following steps to print information about the active uniform variables:
Retrieve the maximum length of the names of all of the active uniforms and the number of active uniforms using
glGetProgramiv
.GLint nUniforms, maxLen; glGetProgramiv( programHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen); glGetProgramiv( programHandle, GL_ACTIVE_UNIFORMS, &nUniforms);
Allocate space to store each uniform variable's name.
GLchar * name = (GLchar *) malloc( maxLen );
Retrieve and print information about each active uniform using
glGetActiveUniform
andglGetUniformLocation
.GLint size, location; GLsizei written; GLenum type; printf(" Location | Name\n"); printf("------------------------------------------------\n"); for( int i = 0; i < nUniforms; ++i ) { glGetActiveUniform( programHandle, i, maxLen, &written, &size, &type, name ); location = glGetUniformLocation(programHandle, name); printf(" %-8d | %s\n", location, name); } free(name);
How it works...
In step one above, we call the function glGetProgramiv
to query for the maximum length of the uniform variable names (GL_ACTIVE_UNIFORM_MAX_LENGTH
), and the number of active uniforms (GL_ACTIVE_UNIFORMS
). The maximum length value includes the null terminating character, so in step 2 we allocate enough space to store a name of that length.
Next, we loop from zero to the number of uniforms minus one, and call glGetActiveUniform
to retrieve information about each variable. Similar to glGetActiveAttrib
, this function provides several pieces of information about the variable including its size, type, and name. We then query for the location of that uniform variable by calling glGetUniformLocation
. It is quite often the case that the index used in the call to glGetActiveUniform
is the same as the uniform's location, but we make the call just to be sure.
Finally, we print the name and location of the variable to standard out.
There's more...
As with vertex attributes, a uniform variable is not considered active unless it is determined by the GLSL linker that it will be used within the shader.
Note that one could also use the function glGetActiveUniformName
instead of glGetActiveUniform
. The former only provides the name, while the latter also provides the size and type.
See also
Sending data to a shader using uniform variables