GLSL: Getting active uniforms

When you load a vertex and fragment shader in OpenGL you need to pass in data such as the current viewport transform, camera transform and lighting data. You do this via Uniform variables.

Each of these Uniforms is addressed via a location which in true OpenGL style is a GLuint. It’s pretty slow to get the location of a Uniform so it’s advisable to cache the location before using the shader in anger. Here is the code to get the location of all ACTIVE uniforms in a compiled and linked shader program:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int numUni = -1;
GLCHECK(glGetProgramiv( mProgram, GL_ACTIVE_UNIFORMS, &numUni ));
for(int i = 0; i < numUni; ++i){

    int namelen =-1, num=-1;
    GLenum type = GL_ZERO;
    char name[256]; //assume no variable names longer than 256

    /* Get the name of the ith Uniform */
    glGetActiveUniform(mProgram,
                       static_cast<GLuint>(i),
                       sizeof(name)-1,
                       &namelen,
                       &num,
                       &type,
                       name));
    name[namelen] = 0;

    /* Get the location of the named uniform */
    GLuint location = glGetUniformLocation( mProgram, name );

    /* cache the location of the Uniforms in a std::map
    mUniformMap[name] = location;
}

The docs for glGetActiveUniform document the types returned in type but in general it’s not useful information during runtime.

Note this only finds active uniforms so if you have a uniform declared but you don’t use it it’s stripped by the shader compiler and will not appear.

Comments