OpenGL统一缓冲区混淆

OpenGL统一缓冲区混淆,opengl,Opengl,有人能告诉我一些看似不必要的复杂的统一缓冲区吗?我已经阅读了OpenGL Superbible 5中的部分,我在博客上看到了一些示例,我已经阅读了官方规范,但我仍然不明白 具体来说,所有示例似乎都需要一个着色器程序来开始,以便最初使用glGetActiveUniformsiv设置统一缓冲区。我不明白。为什么界面不允许您在不引用着色器程序的情况下定义结构,在链接时根据程序验证缓冲区/s格式 其次,如果我从一个程序获得结构布局,假设所有使用制服集的程序的结构布局都相同,那么结构是否保证具有相同的偏移

有人能告诉我一些看似不必要的复杂的统一缓冲区吗?我已经阅读了OpenGL Superbible 5中的部分,我在博客上看到了一些示例,我已经阅读了官方规范,但我仍然不明白

具体来说,所有示例似乎都需要一个着色器程序来开始,以便最初使用glGetActiveUniformsiv设置统一缓冲区。我不明白。为什么界面不允许您在不引用着色器程序的情况下定义结构,在链接时根据程序验证缓冲区/s格式

其次,如果我从一个程序获得结构布局,假设所有使用制服集的程序的结构布局都相同,那么结构是否保证具有相同的偏移量、数据大小等?我想是的

第三,我不理解绑定点。我必须使用索引调用glBindBufferBase,然后使用块索引和传递到glBindBufferBase的索引调用glUniformBlockBinding。我很难想象这里到底发生了什么。《超级圣经》不够清晰,我看过的规范和样本也是如此

  • 你到底为什么要这么做?就我个人而言,除非您有严重的数据短缺问题并且需要每个字节,否则我认为没有理由使用std140以外的任何东西。它使代码更加清晰

    但是,如果你一心想避免std140,请继续阅读

  • 该规范彻底解释了这一点:这都在布局限定符中

    总共有3个布局限定符:
    packed
    shared
    std140
    <代码>打包意味着实现可以按照自己的意愿自由安排一切。这包括删除当前程序不使用的制服。因此,布局是由实现定义的,布局中的某些制服可能已被优化

    shared
    意味着实现可以像
    packed
    一样自由安排数据。但是,它必须为每件制服提供存储空间。这使得在程序之间共享统一的布局成为可能,因此得名<代码>共享还要求实现将提供一个一致的布局,以便跨程序提供一致的定义。因此,您只需要查询一个布局

    要回答您的第一个问题,如果您愿意,您可以创建一个带有
    shared
    layout的假程序。您可以使用它来查询统一块的布局。然后,只要布局在其他程序中保持一致(使用
    共享
    布局),所有布局都将是相同的。因此,不需要为其提供特殊的API

    std140
    然而,这意味着统一块的布局是由OpenGL实现逐字节明确定义的。这隐含地允许共享,因为本规范下的两个相同的统一块将具有相同的布局。而且,由于该实现无法在
    std140
    布局块中优化客场制服,因此一切都是完美的

    同样,几乎没有理由避免使用std140。除非你有非常非常严重的内存限制

  • 这与纹理的机制完全相同。唯一的区别是统一块名本身并不是统一的

    使用
    glActiveTexture(GL_TEXTURE0+i)将纹理对象绑定到纹理图像单元;glBindTexture()
    ,其中
    i
    是纹理图像单位索引。现在需要告诉着色器哪个采样器使用该图像单元。但是,OpenGL不允许您直接与名称关联;必须将采样器名称转换为索引位置。因此,您可以使用
    glGetUniformLocation
    获得特定采样器的统一位置。获得统一位置后,可以通过调用
    glUniform1i(loc,i)
    将纹理图像单元与该位置相关联,其中
    i
    是将纹理绑定到的纹理图像单元

    使用
    glBindBufferRange(GL\u Uniform\u buffer,i,…)
    将统一缓冲区对象绑定到统一缓冲区绑定点,其中
    i
    是统一缓冲区绑定点。现在需要告诉着色器哪个统一块使用该绑定点。但是,OpenGL不允许您直接与名称关联;必须将统一块转换为索引位置。因此,您可以使用
    glGetUniformBlockIndex
    获得特定统一块的索引。拥有索引后,可以通过调用
    glUniformBlockBinding(program,index,i)
    将统一缓冲区绑定点与该索引相关联,其中
    i
    是将统一缓冲区绑定到的统一缓冲区绑定点

    看到了吗?完全一样。它们使用不同的术语,但在结构上,它们是相同的。如果你需要一张照片,那么你可以找一张


  • 那很有用。谢谢我不需要避免std140,但对于是否需要使用它或共享来进行共享,我有些困惑。然后,规范似乎在尖叫“使用std140是低效的,但如果你必须使用它”,不管怎样,我刚刚找到了你链接到的网站,它确实让事情变得更清楚了。因此,为了清楚起见,对于使用给定统一块的每个程序,我称之为glUniformBlockBinding,并且该绑定在程序运行期间保持不变?@Robinson:是的,统一块绑定是程序状态。这就是为什么它需要一个程序对象;)@Nicol很好的解释,对我来说很有意义。但是什么是
    glBindTexture(GL_TEXTURE0+i)
    ?我又一次不是最新的,或者这是一个打字错误(或者可能是一个简化)?@Nicolas,在opengl红皮书第8版中,有一个例子直接使用块索引作为绑定点,对吗?请参阅