GlGetUniformIndices does not return the correct index

I'm trying to learn how to use uniform buffer objects while reading OpenGL Superbible 5. I have a single block in my shader:

layout(std140) uniform SkeletonBlock { vec3 position[64]; vec4 orientation[64]; } Skeleton; 

Now my code to capture the index:

 const GLchar* uniformNames[2] = { "SkeletonBlock.position", "SkeletonBlock.orientation" }; GLuint uniformIndex[2]; glGetUniformIndices(shaderProgram, 2, uniformNames, uniformIndex); 

For some reason, this call gives me a really high index (4294967295, sequentially), and I'm not sure why. I feel like I'm missing something obvious. OpenGL reports one active single block that is valid, the maximum allowed of 15. No error flags are active before or after this section of code. Any suggestions in which this might go wrong?

+4
source share
3 answers

I believe you want

 const GLchar* uniformNames[2] = { "Skeleton.position", "Skeleton.orientation" }; 

For the semantics of the C-style language (e.g. GLSL), you declare a variable of type uniform SkeletonBlock with the name Skeleton . Therefore, "SkeletonBlock.position" has the form <typename>.<member> , where you want <variable>.<member> .

OpenGL docs say that you will get GL_INVALID_INDEX from glGetUniformIndices() when you give it a bad uniform name. It might be wise to check each of the returned indexes for this. I would argue that GL_INVALID_INDEX == -1 .

Also, this number 4294967295 represents an unsigned interpretation of 32-bit -1 (two-component add-on).

+1
source
 layout(std140) uniform SkeletonBlock { vec3 position[64]; vec4 orientation[64]; } Skeleton; 

Here's how this definition reads:

  • There is a single block called SkeletonBlock .
  • It contains an array of 64 vec3 called position , followed by an array of 64 vec4 called orientation .
  • The name for all its members is qualified in GLSL with the Skeleton identifier.

Pay attention to the last part. In GLSL and only in GLSL, the position array is identified by Skeleton.position . In C ++, an array is identified by either SkeletonBlock.position or SkeletonBlock.position[0] . The thing is, from C ++ code, you use the SkeletonBlock block name as a prefix, not the Skeleton instance name.

The SkeletonBlock block has an index that can be requested using glGetUniformBlockIndex (note the use of the word "Block" and the lack of multiplicity in the "Index"). Individual uniform members also have indexes, but they are indexes on the uniform list. And these variables must be named correctly. If a single block has an instance name, then single block members must have a block name prefix, not an instance name.

If you pass these names to the OpenGL function and don't get valid indexes, then you probably have a driver error.

+2
source

You will probably encounter this if a single block variable is not specified (i.e. used) in the source code of the GLSL shader. The shader source compiler will completely remove the variable from the shader as an optimization. Then, when you call glGetUniformIndices , glGetUniformIndices is returned.

0
source

Source: https://habr.com/ru/post/1390112/


All Articles