6
\$\begingroup\$

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...

\$\endgroup\$
2
  • \$\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\$ Commented Feb 7, 2013 at 18:26
  • \$\begingroup\$ Didn't actually know this existed. I'll look at it. Thanks :) \$\endgroup\$
    – Robinson
    Commented Feb 8, 2013 at 10:52

1 Answer 1

8
\$\begingroup\$

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;
nameList.reserve(numBlocks);
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.
    name.resize(nameLen);
    glGetActiveUniformBlockName​(prog, blockIx, nameLen, NULL, &name[0]);

    nameList.push_back(std::string());
    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.

\$\endgroup\$
1
  • \$\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
    Commented Feb 8, 2013 at 10:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .