OpenGL着色器的显式与自动属性位置绑定 [英] Explicit vs Automatic attribute location binding for OpenGL shaders

查看:9
本文介绍了OpenGL着色器的显式与自动属性位置绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When setting up attribute locations for an OpenGL shader program, you are faced with two options:

glBindAttribLocation() 在链接之前明确定义属性位置.

glBindAttribLocation() before linking to explicitly define an attribute location.

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

glGetAttribLocation() after linking to obtain an automatically assigned attribute location.

使用其中一个的实用程序是什么?

What is the utility for using one over the other?

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

And which one, if any, is preferred in practice?

推荐答案

我知道一个很好的理由更喜欢 explicit 位置定义.

I know one good reason to prefer explicit location definition.

考虑将几何数据保存在 顶点数组对象中. 对于给定的对象,您可以按照索引对应的方式创建 VAO,例如:

Consider that you hold your geometry data in Vertex Array Objects. For a given object, you create a VAO in such way that the indices correspond to, for example:

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

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

Now consider that you want to draw one object with two different shaders. One shader requires position and normal data as input, the other - positions and texture coords.

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

If you compile those shaders, you will notice that the first shader will expect the positions at attribute index 0 and normals at 1. The other would expect positions at 0 but texture coords at 1.

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

自动分配

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

If neither of the prior two methods assign an input to an attribute index, then the index is automatically assigned by OpenGL when the program is linked. The index assigned is completely arbitrary and may be different for different programs that are linked, even if they use the exact same vertex shader code.

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

This means that you wouldn't be able to use your VAO with both shaders. Instead of having one VAO per, say, object, you'd need - in the worst case - a separate VAO per object per shader.

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

Forcing the shaders to use your own attribute numbering convention via glBindAttribLocation can solve this problem easily - all you need to do is to keep a consistent relation between attributes and their estabilished IDs, and force the shaders to use that convention when linking.

(如果您不使用单独的 VAO,这并不是什么大问题,但仍可能使您的代码更清晰.)

(That's not really a big issue if you don't use separate VAOs, but still might make your code clearer.)

顺便说一句:

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

When setting up attribute locations for an OpenGL shader program, you are faced with two options

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

There's a third option in OpenGL/GLSL 3.3: Specify the location directly in shader code. It looks like this:

layout(location=0) in vec4 position;

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

But this is not present in GLSL ES shader language.

这篇关于OpenGL着色器的显式与自动属性位置绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆