许多文章通过指定固定绑定点来描述使用原子计数器:
//Shader:
layout(binding = 0, offset = 0) uniform atomic_uint myAtomicCounter;
//App code
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, myBufferHandle);
在这里,硬编码绑定点binding = 0
在着色器和应用程序代码中都指定。我猜这些文章是这样做的,因为,
原子计数器没有分配位置,并且不能使用
Uniform*
命令进行修改。属于程序对象的原子计数器的绑定、偏移量和步幅在每次成功重新链接后都将失效并分配新的。[shader_atomic_counters]
在您想要一些更模块化的着色器代码之前,上述内容很好。例如,我有两个着色器包含文件,每个都需要一个原子计数器,我将其编写为不知道另一个的可插入代码。显然我不想指定硬编码绑定点,我希望应用程序自动处理它。我真的不在乎他们使用哪个绑定点,只是他们不一样。
顶点着色器属性看起来相似。我可以在着色器链接之前在运行时()强制绑定位置,glBindAttribLocation
或者让 OpenGL 为我选择它们,然后查询结果(glGetAttribLocation
)。我还可以搜索所有属性 ( glGetActiveAttrib
)。
如何为原子计数器实现自动唯一绑定点,这样它们就不会被硬编码,我可以混合着色器代码?
我可以看到几种可能的方法,但仍然存在链接后不更改它们的限制:
- 不要在着色器中指定绑定点,让 OpenGL 在链接时选择一个。我不知道OpenGL是否会这样做。如果是这样,您如何查询以找到使用的绑定点?
- 在链接之前查询着色器对象以查找原子计数器。然后给他们唯一的绑定位置,就像
glBindAttribLocation
属性一样。是否有分配绑定点的机制? - 解析所有着色器代码,寻找原子计数器并用着色器代码本身中的唯一索引替换绑定点,可能使用
#define
宏。最后的手段。我真的不想这样做。