I want to auto-bind uniform blocks with certain named values to certain binding points when I compile a shader. For example, I have some basic, default fixed binding points that are always used for certain things like:

0 Camera
1 Model
2 Material
3 Lights

At the moment I'm binding manually by finding the index of a named block with glGetUniformBlockIndex, and then binding it with glUniformBlockBinding. What I'd like to do is fetch the set of all block names in my shader program. When I iterate with glGetActiveUniformsiv, I get a list of all uniforms, which excludes block names.

Is there any way to do this without testing and failing each of my above names to see if it's an active block with glGetUniformBlockIndex? There's no glGetActiveUniformBlocksiv, is there...

  • \$\begingroup\$ Is there some reason you can't use ARB_shading_language_420pack and specify them in the shader itself? It's a pretty widely available extension. \$\endgroup\$ – Nicol Bolas Feb 7 '13 at 18:26
  • \$\begingroup\$ Didn't actually know this existed. I'll look at it. Thanks :) \$\endgroup\$ – Robinson Feb 8 '13 at 10:52

This is pretty easy; just the program introspection API to fetch the indices. First, ask how many uniform blocks there are:

GLint numBlocks;
glGetProgramiv(prog, GL_ACTIVE_UNIFORM_BLOCKS, &numBlocks);​

All of your uniform block indices are on the half-open range [0, numBlocks). So iterate through them and get their names.

std::vector<std::string> nameList;
for(int blockIx = 0; blockIx < numBlocks; ++blockIx)
    GLint nameLen;
    glGetActiveUniformBlockiv​(prog, blockIx, GL_UNIFORM_BLOCK_NAME_LENGTH, &nameLen);

    std::vector<GLchar> name; //Yes, not std::string. There's a reason for that.
    glGetActiveUniformBlockName​(prog, blockIx, nameLen, NULL, &name[0]);

    nameList.back().assign(name.begin(), name.end() - 1); //Remove the null terminator.

BTW, if you're doing this because you think it's faster, stop. First, performance is irrelevant since this is one-time setup code. Second, you're doing this for maybe 4-8 blocks at most. It's not going to affect actual performance in any way. So really, there's no reason to not just get the indices by name if that's what you're ultimately doing. The introspection API is for when you don't know what is there.

| improve this answer | |
  • \$\begingroup\$ I wasn't do it so it was faster Nicol, just because I thought it was more "correct" to enumerate them, rather than trying each one and failing if it wasn't there. Anyway, thanks very much for this. \$\endgroup\$ – Robinson Feb 8 '13 at 10:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.