Reputation: 51
I am trying to learn how to use uniform buffer objects, reading the OpenGL Superbible 5. I have a uniform block in the my shader:
layout(std140) uniform SkeletonBlock
{
vec3 position[64];
vec4 orientation[64];
} Skeleton;
Now my code to grab the index is:
const GLchar* uniformNames[2] =
{
"SkeletonBlock.position",
"SkeletonBlock.orientation"
};
GLuint uniformIndex[2];
glGetUniformIndices(shaderProgram, 2, uniformNames, uniformIndex);
For some reason this call is giving me a really high index (4294967295, consistently) and I am not sure why. I feel like I am missing something obvious. OpenGL is reporting one active uniform block, which is correct, out a max allowed of 15. No error flags are active before or after this section of code either. Any suggestions where it could be going wrong?
Upvotes: 4
Views: 2234
Reputation: 28982
You will probably encounter this if the uniform block variable isn't referenced (i.e. used) in the shader's GLSL source code. The shader source code compiler will remove the variable from the shader altogether as an optimization. Then, when you call glGetUniformIndices
, GL_INVALID_INDEX will be returned.
Upvotes: 0
Reputation: 474136
layout(std140) uniform SkeletonBlock
{
vec3 position[64];
vec4 orientation[64];
} Skeleton;
Here is how this definition reads:
SkeletonBlock
.vec3
s called position
, followed by an array of 64 vec4
s called orientation
.Skeleton
.Note the last part. In GLSL, and only in GLSL, the position
array is identified by Skeleton.position
. In C++, the array is identified by either SkeletonBlock.position
or SkeletonBlock.position[0]
. The point here is that from C++ code you use the block name SkeletonBlock
as a prefix, not the instance name Skeleton
.
The SkeletonBlock
block has an index that can be queried with glGetUniformBlockIndex
(note the use of the word "Block" and the lack of plurality on "Index"). The individual uniform members also have indices, but they are indices into the list of uniforms. And these variables must be named correctly. If the uniform block has an instance name, then the uniform block members must be prefixed by the block name, not the instance name.
If you're passing those names to the OpenGL function and not getting valid indices, then you likely have a driver bug.
Upvotes: 2
Reputation: 192
I believe you want
const GLchar* uniformNames[2] =
{
"Skeleton.position",
"Skeleton.orientation"
};
As the semantics of a C-style language (such as GLSL) have it, you are declaring a variable of type uniform SkeletonBlock
named Skeleton
. Hence, "SkeletonBlock.position"
is of the form <typename>.<member>
, where you want <variable>.<member>
.
The OpenGL docs say that you will get a GL_INVALID_INDEX
from glGetUniformIndices()
when you give it a bad uniform name. It might be smart to check each of the returned indices against this. I would bet that GL_INVALID_INDEX == -1
.
Also, this number 4294967295 is the unsigned interpretation of a 32-bit -1 (twos complement).
Upvotes: 1