Way to find uniforms in the 'default' uniform block?


Is there a way to iterate through the uniforms in the default uniform block, ie: the ‘global’ uniforms, ignoring all uniforms inside uniform blocks?

I’m currently doing something like this:

    int numUniforms = 0;
    glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms);

    for (int i = 0; i < numUniforms; ++i) {
        int blk = 0;
        glGetActiveUniformsiv(program, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &blk);
        if (blk != -1) continue;
        // If we get here, it's a default/global uniform...

This works, but I have a pretty big array in my uniform block and it takes ages to go through the 128K uniforms in there just to find the 3 ‘global’ ones. Well, not ages, but it just seems like a dumb way to do it.

I also tried glGetActiveUniformBlockiv to get the number and indices of uniforms attached to uniform block ‘-1’ (which,as above, is sometimes the id of the default block - pretty weird behaviour for a GLuint though!) but that doesn’t work either, I just get 0 returned for number of uniforms.

What am I missing here?

This is how you iterate over the non-block uniforms. There is no alternative.

There are better APIs, but they work the same way.

-1 is not a block index in the same way that nullptr is not a pointer to an object.

Not the answer to your question, but possibly a way to obviate it:

You might consider taking Vulkan GLSL route: don’t use naked, global-scope uniforms and just pass all of your uniforms (**) in via UBO or SSBO bindings, always explicitly specifying their binding locations in the GLSL shader source.

Then you can largely just jettison the whole concept of shader introspection.

** uniforms with non-opaque types (e.g. uint, vec4, etc.)

With GL 4.4, you don’t even have to switch to UBOs; you can specify locations directly in the shader.