I’m experiencing the exact same problem, and I have a bit more detailed info to add for anyone who might see something we’ve missed. I’ve tested this with a GTS250 on driver versions 190.38 and 190.62. I have wrappers around every GL call that throw an exception if glGetError() returns an error code, and no error code is being set anywhere in my program.
After linking any shader program, I run this code:
// Register and/or assign any uniform blocks this technique uses
int nActiveBlocks = 0;
gl.getProgramiv(this->getHandle(), GL_ACTIVE_UNIFORM_BLOCKS, &nActiveBlocks);
for(int nBlock=0; nBlock<nActiveBlocks; nBlock++) {
char szBlock[256];
int nSize;
this->getActiveUniformBlockName(nBlock, 256, NULL, szBlock);
this->getActiveUniformBlockiv(nBlock, GL_UNIFORM_BLOCK_DATA_SIZE, &nSize);
UniformBufferObject *pUniformBuffer = gl.getManager()->createUniformBlock(szBlock, nSize);
this->uniformBlockBinding(nBlock, pUniformBuffer->getBindIndex());
}
Right now 3 shader programs get linked, and each runs through this loop. The first time the GL manager sees a uniform block with a specific name, it creates a new UniformBufferObject and automatically assigns it a unique bind index. On subsequent checks, it makes sure the size hasn’t changed and returns the existing buffer object. Right now I’m only using one uniform block named “Transform”, and I am trying to add another block. In my main game loop, I update the data in the “Transform” buffer and ensure that it is bound to its assigned index:
GL::Uniform::Transform t;
...
GL::UniformBufferObject *pTransform = gl.getManager()->getUniformBlock("Transform", sizeof(GL::Uniform::Transform));
pTransform->updateBlock(t);
pTransform->bindBlock();
When my shader program only declares one uniform block, everything works and renders perfectly. If I define a second uniform block in my shader programs (without using it), I get a blank screen. In the debugger, I see my “Transform” block being assigned index 1 instead of index 0, and this seems to be causing the problem. If I force “pTransform->bindBlock()” to use index 0, it starts working again (even though uniformBlockBinding told the driver to use index 1).
It seems to me like the driver is ignoring the numbers I pass to uniformBlockBinding and is always using binding 0 for all blocks. When I call glGetActiveUniformBlockiv with GL_UNIFORM_BLOCK_BINDING it returns 1, so I know I set it properly, but the shader will only use the values in my uniform buffer if I bind it to index 0.
Can anyone see anything I’ve missed, or does it seem like a driver bug? Named uniform blocks are useless if you can only use one of them. I wish I could post an small complete program duplicating the problem, but GL 3.1 requires way too much code for that.
Thanks,
Sean