I have a question about glUniformBlockBinding and shaders, particularly concerning some behaviour I’ve not found documented anywhere (of course, it could just be me). I have a compound model consisting of 6 different meshes. Each different mesh has a different material. A material is just a uniform block that I bind into the shader before rendering the mesh. So I’m effectively doing this whenever I render the model and all of its meshes:
for(auto i = mesh.begin(); i != mesh.end(); ++i)
{
phongShader->Set("Material", (*i)->Material()->ShaderVariables());
...DrawIndexedTriangles(...)
}
Where phongShader->Set(…) is a method that does a glUniformBlockBinding for the given shader variable block. Now when I do this, assuming meshes each use a different material and each material specifies a different colour for the shader (white, blue, red, green, yellow, for testing purposes), the colours displayed by each mesh are wrong.
When I issue a glFlush after drawing each mesh, then the colours are correct:
for(auto i = mesh.begin(); i != mesh.end(); ++i)
{
phongShader->Set("Material", (*i)->Material()->ShaderVariables());
...DrawIndexedTriangles(...)
glFlush();
}
So here’s what I’ve done to try to debug things:
(1) Checked that each material has the correct parameters and is bound correctly.
(2) Hard coded each material when drawing all meshes, to verify the material/shader is OK.
(3) Verified that the correct material is being referred to by the correct mesh.
(4) Rendered only the first mesh from the model (it was the correct colour).
(5) Rendered two meshes from the model (the first mesh was rendered the same colour as the second mesh [???])
I’ve checked and checked again and come to the following conclusion given that it works with a glFlush: when I bind the uniform block to the shader, its current binding is overwritten by my next call to bind the uniform block, that is until GL decides to send the batch for processing, at which time my next call to change the shader uniform block succeeds.
Note that my ordinary uniform (the modelview transform matrix) is fine. This uniform is set directly on the program and isn’t a uniform block. That is, all meshes appear at the correct location with the correct orientation.
Can anyone explain this behaviour for me please?
Here’s a screenshot demonstrating the problem : tinypic.com
Thanks.