Jin*_*ing 77 shader opengl-es opengl-es-2.0
为OpenGL着色器程序设置属性位置时,您将面临两个选项:
链接之前的glBindAttribLocation()以显式定义属性位置.
要么
链接后的glGetAttribLocation()以获取自动分配的属性位置.
使用一个而不是另一个有什么用?
在实践中哪一个(如果有的话)更受欢迎?
Kos*_*Kos 90
我知道选择明确的位置定义的一个很好的理由.
考虑在顶点数组对象中保存几何数据.对于给定对象,您可以以索引对应的方式创建VAO,例如:
现在考虑要使用两个不同的着色器绘制一个对象.一个着色器需要位置和正常数据作为输入,另一个 - 位置和纹理坐标.
如果编译这些着色器,您会注意到第一个着色器将预期属性索引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;
Run Code Online (Sandbox Code Playgroud)
但这在GLSL ES着色器语言中不存在.
第三个选项,即layout(location=0) in vec4 position;
着色器代码,现在可在OpenGL ES 3.0/GLSL 300 es中使用.仅适用于顶点着色器输入变量.