I use the folowing code to query all active uniforms in a program:
int activeUniforms;
char uniformName[256];
// get number of active uniforms
glGetProgramiv( program->id, GL_ACTIVE_UNIFORMS, &activeUniforms );
// save names, sizes and locations of all uniforms
for( uint index = 0; index < activeUniforms; index++ )
{
int type, location;
// get uniform's name and data type at given index
glGetActiveUniformName( program->id, index, 256, 0, uniformName );
glGetActiveUniformsiv( program->id, 1, &index, GL_UNIFORM_TYPE, &type );
// get uniform's location
location = glGetUniformLocation( program->id, uniformName );
// store type size and location of uniform
program->uniforms[uniformName].first = datatypeSizes[type];
program->uniforms[uniformName].second = location;
}
This enumerates all active uniforms including those which a part of a uniform block. For those, however, a location of -1 is returned. Why? If a uniform is active, it has a location, even if it’s part of a uniform block, doesn’t it?
For example, for this program:
vs:
#version 150 core
layout(location=0) in vec4 in_vertexPos;
layout(std140) uniform Projection
{
mat4 perspective;
mat4 orthographic;
} projection;
void main()
{
gl_Position = projection.orthographic*vec4(in_vertexPos.xyz, 1.0);
}
fs:
#version 150 core
out vec4 out_Color;
uniform vec4 color;
uniform vec4 color2;
void main()
{
out_Color = color*color2;
}
these uniforms are listed:
Active uniforms
---------------
Uniform: 'projection.orthographic' (size: 64, location: -1)
Uniform: 'color' (size: 16, location: 0)
Uniform: 'color2' (size: 16, location: 1)
Uniform: 'projection.perspective' (size: 64, location: -1)
Does that make sense?
EDIT: Is glGetActiveUniformsiv even part of the core yet? Can’t find it in either the 3.3 nor the 4.1 specs…?!