opengl – 使用块索引作为UniformBufferObject,ShaderStorageBufferObjects等的绑定点是否安全?

我很好奇几个OpenGLs缓冲区对象相关函数中使用的* BlockBinding参数.

例如glUniformBlockBinding中的uniformBlockBinding参数,glShaderStorageBlockBinding中的storedBlockBinding,以及glBindBufferRange和glBindBufferBase中的相​​应索引参数.

我知道如果使用布局限定符在着色器中设置绑定点,则不需要调用glUniformBlockBinding和glShaderStorageBlockBinding,例如:

layout (binding = 0) blockName {...}

从我的机器上测试我发现了三件事:

1)使用glUniformBlockBinding和glShaderStorageBlockBinding设置绑定点,使用布局限定符覆盖着色器中设置的绑定点.

2)从glGetUniformBlockIndex返回的块索引和glGetProgramResourceIndex对于相同类型的每个块按0到n排序.例如,如果着色器包含3个统一块和2个缓冲块,则返回的索引将分别为[0,1,2]和[0,1].

3)绑定点,设置两种方式,不要跨类型冲突.例如,将一个统一块设置为binding = 0,将一个缓冲块设置为binding = 0是完全安全的.

考虑到这些假设(请纠正我,如果有任何不一定是真的并且只是巧合),是否有任何理由我不应该让我的代码自动将* BlockBinding参数设置为相应的块索引并保存自己通过gl * BlockBinding或布局限定符手动指定它们的麻烦.

最佳答案 我曾经有同样的问题.经过一番探索,特别是阅读有关GL:
https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object]的权威信息来源

我很确定这就是为什么块索引和绑定点之间的分离.

将GL渲染上下文视为端口,将glsl程序对象视为船舶.装订点是港口的港口,区块索引是船舶储藏室的门.船舶需要在港口停靠,其中一扇门与特定港口对齐,以便将货物装载到船上(或相反的方式).类似地,块索引需要与在着色器块和上下文缓冲区之间传输的数据的绑定点相关联.

由于这种设计,块索引和绑定点是独立的实体.因此,简单地将绑定点等同于块索引是不安全的,因为这可能无意中覆盖了绑定点(可能已被其他船只停靠).

您的观察也可以解释:

>块索引和绑定点从0开始连续计数(如您在(2)中观察到的那样).
>每种类型的缓冲区(因为它们驻留在上下文中)具有一组与其他类型分开的绑定点(因此您的观察3).
>关于您的观察1,是的,在应用程序端设置关联会在着色器中取代硬编码绑定.

点赞