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


82

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

链接以明确定义属性位置之前,请使用glBindAttribLocation()

要么

链接以获取自动分配的属性位置后的glGetAttribLocation()

什么是实用程序?

在实践中最好选择哪一个?


6
我没有glBindAttribLocation在我的图形引擎中使用它,它在Linux上运行良好。当我移植到Windows时,它使用的是法线作为顶点-我必须通过着色器明确告诉它变量的顺序,glBindAttribLocation以使其正常工作……
Jarrett

Answers:


93

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

考虑将几何数据保存在“顶点数组对象”中。对于给定的对象,以如下方式创建VAO,使索引对应于:

  • 索引0:位置,
  • 索引1:法线,
  • 索引2:texcoords

现在考虑要使用两个不同的着色器绘制一个对象。一个着色器需要位置和法线数据作为输入,而另一个则需要位置和纹理坐标

如果编译这些着色器,您将注意到第一个着色器将期望属性索引为0的位置且法线为1。另一个着色器将期望位置为0但纹理坐标为1。

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

自动分配

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

这意味着您将不能同时使用两个着色器的VAO。而不是每个对象一个VAO,在最坏的情况下,您需要每个着色器每个对象一个VAO

通过强制着色器使用您自己的属性编号约定glBindAttribLocation可以轻松解决此问题-您要做的就是在属性及其已确定的ID之间保持一致的关系,并在链接时强制着色器使用该约定。

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


顺便说一句:

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

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

layout(location=0) in vec4 position;

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


1
我不明白这一点。VAO确实很轻巧,通常您会为每个帧重新创建它们。在您的情况下,您只需在调用每个着色器之前创建不同的VAO,对吗?
PierreBdR 2012年

1
是的,您当然可以做到。它将同样有效,我们在这里仅讨论约定。:)
Kos 2012年

4
第三个选项实际上在GLES2.0中可用,但格式略有不同:layout(location = 0)属性vec4位置;请注意,您还需要在GLSL文件的顶部添加此代码:#extension GL_EXT_separate_shader_objects:enable
Gavin Maclean

35
“ VAO确实是轻量级的,您通常会为每个帧重新创建它们。对于您而言,您将在调用每个着色器之前创建不同的VAO,不是吗?” -不,您通常不会这样做,因为这最终会使VAO的全部目的完全失效。为什么要使用VAO?
Christian Rau

2
请注意。您不会将几何数据保存在VAO中。那将在VBO中。VAO没有数据存储。
平均joe 2015年

20

这里的另一个答案是glGetAttribLocation将数据返回给调用者,这意味着它隐式需要管道刷新。如果在编译程序后立即调用它,则实际上是在强制异步编译同步进行。



谢谢,这是一个非常重要的考虑因素。
2013年

1
据我了解,在大多数情况下,您glGetUniformLocation无论如何都要打电话;这个特殊的考虑仍然有意义吗?
Mike Weir

@MikeWeir自GL 4.3起,您可以设置明确的统一位置
罗斯兰

1
@Ruslan他们正在使用OpenGL ES。
迈克·威尔

9

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


7
正如他们所暗示的那样,英特尔卡可能不支持此功能(否则我会完全接受3.0+
兼容
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.