Hello Guest

[Solved] BlockIndex-Issues with Uniform Buffer Object

  • 3 Replies
  • 3484 Views
[Solved] BlockIndex-Issues with Uniform Buffer Object
« on: April 15, 2020, 15:18:40 »
Hello people of the LWJGL-forum, I got a question.

My shader programs, consisting of the usual vertex and fragment parts, employ uniform buffer objects. Now, the pipeline I established for handling UBOs has proven very successful thus far, but now I have hit a weird conundrum that I cannot explain.
In this exact, scenario, there are two UBOs, one in the vertex-shader:

Code: [Select]
(...)
layout (std140) uniform Matrices {
mat4 viewMatrix;
mat4 projectionMatrix;
vec3 camPosition;
};
(...)

and one in the fragment-shader:
Code: [Select]
(...)
layout (std140) uniform SpecialData{
float arrA[16];
float arrB[24];
};
(...)

As usual with OpenGL-Problems, if you got a bug then you either get garbage or nothing. In my case, it was nothing. Expecting my data to be at fault, I wrote tests that verified that the data I was giving to the card was correct. Yes, I have decided to go with std140 layout and, yes, I am aware of the waste-of-space that comes with that, especially with float-arrays that I am employing here. To my knowledge, that should be irrelevant to the problem I am facing.

This is the relevant code that produces the mapping between the blocks and their binding points after the shader programm has been linked and validated.
Code: [Select]
int uniformBlockLocation = glGetUniformBlockIndex(programId, uniformBlockName);
if (uniformBlockLocation == GL_INVALID_VALUE || uniformBlockLocation == GL_INVALID_OPERATION)
   throw new ShaderError("Shader program '" + programDescription.programName + "' is in an illegal state!");
if (uniformBlockLocation != -1) {
   (...) // associate 'uniformBlockName' with 'uniformBlockLocation'
} else {
    //driver eliminated this variable, it was not needed/used
    System.err.println("Warning: Uniform Block '" + uniformBlockName + "' in Shader Program '" + programDescription.programName + "' was eliminated by the driver!");
}

For reference, I later employ this association-data to link a uniform block with a binding point like this
Code: [Select]
if(/* association exists */) {
   //associate shader's uniform block to a specific binding point (at which a buffer resides):
   var index = /*get computed 'uniformBlockLocation' earlier */
   glUniformBlockBinding(id, index, block.bindingPoint);
} else {
   System.err.println("Uniform Block '" + uniformBlockName + "' does not exist within this shader-program.");
}
if( /* association exists */ ) {
   glUniformBlockBinding(id, getAssociationFor(uniformBlockName) /* returns previously stored result from 'glGetUniformBlockIndex' */, block.bindingPoint);
} else {
   System.err.println("Uniform Block '" + uniformBlockName + "' does not exist within this shader-program.");
}

while the buffer itself was also associated with the binding point:

Code: [Select]
var bufferHandle = glGenBuffers();
glBindBuffer(GL_UNIFORM_BUFFER, bufferHandle);
glBufferData(GL_UNIFORM_BUFFER, data, GL_STATIC_DRAW); //send data
glBindBuffer(GL_UNIFORM_BUFFER, 0); //is this wrong?
(...)
glBindBufferBase(GL_UNIFORM_BUFFER, block.bindingPoint, bufferHandle );

Now, since stuff has stopped working once I started using two UBOs and the data looks good, I thought the most likely issue is how I bind them. Perhaps I simply mixed up some stuff but it worked by accident thus far (classical case of 0 is the default)?

I am on an OpenGL 4.4 by the way:

Code: [Select]
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);


Rephrasing this into questions:

1.) am I understanding the relationship between the buffer's handle, the binding point and the uniform block index correctly?
2.) must certain things be bound (e.g.) the buffer while calling any binding-point related functions?


« Last Edit: April 26, 2020, 16:13:52 by Source_of_Truth »

*

Offline KaiHH

  • ****
  • 334
Re: BlockIndex-Issues with Uniform Buffer Object
« Reply #1 on: April 15, 2020, 15:31:08 »
The uniform block index you get with glGetUniformBlockIndex() is _NOT_ the binding location you use to bind to the shader.
You must query the bind location via glUniformBlockBinding() taking the index as one of the parameters.
Read: https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object

Re: BlockIndex-Issues with Uniform Buffer Object
« Reply #2 on: April 15, 2020, 15:37:33 »
Hm, no, that is a misunderstanding. I do bind this, but somewhere else. I updated the original post, so my question remains?
« Last Edit: April 15, 2020, 15:42:10 by Source_of_Truth »

Re: BlockIndex-Issues with Uniform Buffer Object
« Reply #3 on: April 26, 2020, 16:13:25 »
Okay, as expected there is no binding issue :(. It seems the data send over is problematic, see this thread.

Thanks to all who read this and thought about what it could be...