在为OpenGL着色器程序设置属性位置时,您面临两个选择:
链接以明确定义属性位置之前,请使用glBindAttribLocation()。
要么
链接以获取自动分配的属性位置后的glGetAttribLocation()。
什么是实用程序?
在实践中最好选择哪一个?
Answers:
我知道有一个很好的理由喜欢显式的位置定义。
考虑将几何数据保存在“顶点数组对象”中。对于给定的对象,以如下方式创建VAO,使索引对应于:
现在考虑要使用两个不同的着色器绘制一个对象。一个着色器需要位置和法线数据作为输入,而另一个则需要位置和纹理坐标。
如果编译这些着色器,您将注意到第一个着色器将期望属性索引为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着色器语言中不存在。
glBindAttribLocation
在我的图形引擎中使用它,它在Linux上运行良好。当我移植到Windows时,它使用的是法线作为顶点-我必须通过着色器明确告诉它变量的顺序,glBindAttribLocation
以使其正常工作……