我为什么要使用glBindAttribLocation?

edA*_*a-y 12 opengl

可能重复:
OpenGL着色器的显式与自动属性位置绑定

在我的另一个问题中,其中一个答案表明我应该使用glBindAttribLocation并且不允许着色器编译器分配自己的索引.我想知道为什么这是一个推荐的做法,它有什么优点(或者说它没有使用它有什么缺点)?

我明白如果我有多个共享属性的程序,这是有道理的,因为我可以在程序之间切换而不必重置这些属性.但是,对于未共享的属性,或者如果我的程序不使用此类共享,我不认为有必要显式绑定索引.

Kil*_*nDS 21

首先,我不认为使用显式绑定glBindAttribLocation?而不是使用显式绑定是一般性建议glGetAttribLocation.话虽这么说,这些是我停止使用的主要原因glGetAttribLocation:

首先,这可能会导致不必要的开销.这一切似乎都很好,您可以使用可读的名称而不是数字.'什么是属性7'对'哦'对,属性texture_coordinate':我先解释一下可能的开销是什么,然后为什么最后一部分甚至没有意义.

如果您经常需要属性位置,则调用的开销glGetAttribLocation可能会变得不可忽略,具体取决于驱动程序.因此,要处理一般情况,您必须构建一个缓存系统.好的,我的简单易读的方法是使用名称而不是数字,我只需编写很多非平凡的包装代码.更糟糕的是,当程序变得无效时,你应该注意破坏缓存,你很可能会犯这个错误并最终导致错误.所以我们从'好看的可读名字'变成'可怕的马车乱七八糟'.

更有甚者,"好看的名字"这个论点是有缺陷的.对于着色器本身中定义的位置,您可以完美地执行以下操作:

const GLint vertex_loc_att = 0;
const GLint texture_coord_att = 1;
...
Run Code Online (Sandbox Code Playgroud)

或者您也可以使用这样的关联容器:

attribute_locations["vertex_location"] = 0;
attribute_locations["texture_coordinate"] = 1;
...
Run Code Online (Sandbox Code Playgroud)

这个你也可以结合glBindAttribLocation,只需在链接之前这样做:

foreach name, location in attribute_locations
{
    glBindAttribLocation(program_id, location, name);
}
Run Code Online (Sandbox Code Playgroud)

仍然非常易读,不需要动态缓存,只是一些静态变量甚至可能被优化掉.

然后,你自己说:显然它在使用多个程序时具有优势,我在此不再重复,因为Kos 已经详细解释了一个.我只想回答你的一个论点:

不需要共享的属性:这意味着还有一些属性需要共享,因此使用固定位置是一个很大的优势.为什么要在一个应用程序中混合两种位置管理方法?让自己远离维护问题并坚持使用,这显然是预定义的位置,因为您需要它们来共享属性.

  • 有人会想要一个`glBindUniformLocation`是否有意义?我问,因为你的论证也适用于它,但这个功能不在标准中. (4认同)
  • glBindUniformLocation 功能是在 4.3 中通过着色器中的布局语句添加的:http://www.opengl.org/wiki/Uniform_(GLSL)#Explicit_uniform_location (2认同)