I'm curious about the *BlockBinding
argument used in several of OpenGLs buffer object related functions.
For example the uniformBlockBinding
parameter in glUniformBlockBinding
, storageBlockBinding
in glShaderStorageBlockBinding
, and the corresponding index
parameter in glBindBufferRange
and glBindBufferBase
.
I know that calls to glUniformBlockBinding
and glShaderStorageBlockBinding
aren't necessary if binding points are set in the shaders using layout qualifiers such as:
layout (binding = 0) blockName {...}
and from testing around on my machine I've noticed three things:
1) setting binding points with glUniformBlockBinding
and glShaderStorageBlockBinding
override binding points set in the shader using layout qualifiers.
2) block indices returned from glGetUniformBlockIndex
and glGetProgramResourceIndex
are ordered 0 to n for each block of the same type. For example if the shader contains 3 uniform blocks and 2 buffer blocks the indices returned would be [0,1,2] and [0,1] respectively.
3) binding points, set either way, do not conflict across types. For example, setting a uniform block to binding = 0 and a buffer block to binding = 0 is completely safe.
With these assumptions in mind (please correct me if any aren't necessarily true and are simply coincidence), are there any reasons why I shouldn't just have my code automatically set the *BlockBinding
argument to the corresponding block index and save myself the trouble of ever specifying them manually via gl*BlockBinding
or with layout qualifiers.
I once had the same question. After some exploration, and especially reading the authoritative source of information on GL: https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object] I'm pretty sure this is why the separation between block index and binding point.
Think of a GL render context as a port, and a glsl program object as a ship. The binding points are harbors of the port and block indices are doors to ship's storage compartments. A ship needs to dock at the port with one of its door aligned with a specific harbor to load cargo onto the ship (or the other way around). Similarly, a block index needs to be associated with a binding point for the data to be transferred between the shader's blocks and the context's buffers.
Due to this design, the block indices and binding points are independent entities. Therefore it's not safe to simply equating binding point to block index, as that may unintentionally overrides binding points (that may have been docked by other ships).
Your observations can be also explained:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With