Opengl 如何获得自动唯一的原子计数器绑定点(无硬编码绑定=)?

Opengl 如何获得自动唯一的原子计数器绑定点(无硬编码绑定=)?,opengl,glsl,modularity,hardcoded,Opengl,Glsl,Modularity,Hardcoded,许多文章通过指定固定绑定点来描述如何使用原子计数器: //Shader: layout(binding = 0, offset = 0) uniform atomic_uint myAtomicCounter; //App code glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, myBufferHandle); int atomicCounterIndex; glGetActiveUniformsiv(programId, count, inde

许多文章通过指定固定绑定点来描述如何使用原子计数器:

//Shader:
layout(binding = 0, offset = 0) uniform atomic_uint myAtomicCounter;

//App code
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, myBufferHandle);
int atomicCounterIndex;
glGetActiveUniformsiv(programId, count, index, 
        GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX, &atomicCounterIndex);
glGetActiveAtomicCounterBufferiv(programId, atomicCounterIndex, 
        GL_ATOMIC_COUNTER_BUFFER_BINDING, &myBufferHandle)
这里,在着色器和应用程序代码中都指定了硬编码绑定点
binding=0
。我猜这些文章是这样做的,因为

原子计数器未分配位置,也可能未被分配 使用
Uniform*
命令进行修改。绑定, 属于原子计数器的偏移量和跨步 程序对象的属性无效,新属性无效 在每次成功重新链接后分配

在您需要更多模块化着色器代码之前,以上内容都是很好的。例如,我有两个shader include文件,每个文件都需要一个原子计数器,我编写的可插入代码不知道另一个。显然,我不想指定硬编码的绑定点,我希望应用程序能够自动处理它。我真的不在乎它们使用哪些绑定点,只是它们不一样

顶点着色器属性看起来类似。我可以在着色器链接之前在运行时强制绑定位置(
glBindAttribLocation
),或者让OpenGL为我选择它们,然后查询结果(
glGetAttribLocation
)。我还可以搜索所有属性(
glGetActiveAttrib

如何为原子计数器实现自动唯一绑定点,这样它们就不需要硬编码,并且可以混合着色器代码?

我可以看到一些可能的方法,但链接后不更改它们的限制:

  • 不要在着色器中指定绑定点,并让OpenGL在链接时拾取一个绑定点。我不知道OpenGL是否会这样做。如果是这样,您如何查询以找到所使用的绑定点?
  • 在链接以查找原子计数器之前查询着色器对象。然后为它们指定唯一的绑定位置,就像属性的
    glBindAttribLocation
    一样是否有分配绑定点的机制?
  • 解析所有着色器代码,查找原子计数器,并使用着色器代码本身中的唯一索引替换绑定点,可以使用
    #define
    宏。万不得已。我真的不想这样做

  • 关于第1点:原子计数器的
    绑定
    布局参数不是可选的

    关于第2点:因为
    绑定
    不是可选的,所以不能从OpenGL代码中设置它


    因此,您唯一的资源是#3。

    您可以使用
    glGetActiveUniform
    查询原子计数器。然后获取缓冲区索引,最后是绑定点:

    //Shader:
    layout(binding = 0, offset = 0) uniform atomic_uint myAtomicCounter;
    
    //App code
    glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, myBufferHandle);
    
    int atomicCounterIndex;
    glGetActiveUniformsiv(programId, count, index, 
            GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX, &atomicCounterIndex);
    glGetActiveAtomicCounterBufferiv(programId, atomicCounterIndex, 
            GL_ATOMIC_COUNTER_BUFFER_BINDING, &myBufferHandle)
    
    如前所述,它自OpenGL 4.2起就开始工作