OpenGL着色器的显式和自动属性位置绑定

为OpenGL着色器程序设置属性位置时,您面临两个选择:

链接前glBindAttribLocation()明确定义属性位置。

要么

glGetAttribLocation()链接后获得一个自动分配的属性位置。

使用其中一个的效用是什么?

如果有的话,哪一个在实践中更受欢迎?


我知道有一个很好的理由喜欢明确的位置定义。

考虑您将几何数据保存在顶点数组对象中。 对于一个给定的对象,你创建一个VAO的方式使索引符合,例如:

  • 索引0 :职位,
  • 索引1 :法线,
  • 索引2 :texcoords
  • 现在考虑你想用两种不同的着色器绘制一个对象。 一个着色器需要位置和正常数据作为输入,其他位置和纹理坐标

    如果你编译了这些着色器,你会注意到第一个着色器会预期位于属性索引0和位置为1的位置。另一个位置的位置为0,但纹理坐标位于1。

    引用https://www.opengl.org/wiki/Vertex_Shader:

    自动分配

    如果前两种方法都没有将输入分配给属性索引,则当链接程序时,索引由OpenGL自动分配。 分配的索引完全是任意的,对于链接的不同程序可能不同,即使它们使用完全相同的顶点着色器代码。

    这意味着你将无法在两个着色器中使用你的VAO。 而不是每个对象都有一个VAO,您需要 - 在最坏的情况下 - 每个着色器需要一个单独的VAO

    强制着色器通过glBindAttribLocation使用自己的属性编号约定可以轻松解决这个问题 - 您只需要在属性与其建立的ID之间保持一致的关系,并强制着色器在链接时使用该约定。

    (如果你不使用单独的VAO,这并不是一个大问题,但仍然可能使你的代码更加清晰。)


    BTW:

    为OpenGL着色器程序设置属性位置时,您面临两个选择

    OpenGL / GLSL 3.3中有第三个选项:直接在着色器代码中指定位置。 它看起来像这样:

    layout(location=0) in vec4 position;
    

    但是这在GLSL ES着色器语言中不存在。


    这里的另一个答案是glGetAttribLocation将数据返回给调用者,这意味着它隐含地需要管道刷新。 如果在编译程序之后立即调用它,则基本上迫使异步编译同步发生。


    第三个选项,即layout(location=0) in vec4 position; 在着色器代码中,现在可在OpenGL ES 3.0 / GLSL 300 es中使用。 但只适用于顶点着色器输入变量。

    链接地址: http://www.djcxy.com/p/52419.html

    上一篇: Explicit vs Automatic attribute location binding for OpenGL shaders

    下一篇: UITableView Plist Not Returning valueForKey