12

我假设这将是“未定义”的事情之一,但我似乎无法从谷歌找到具体答案。

假设在我的顶点着色器中我有:

layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec4 vColour;

但是使用 glEnableVertexAttribArray() 或 glVertexAttribPointer() 没有缓冲到位置 2。我可以期望值是什么特别的吗?

我假设 vec4 会沿着 {0,0,0,0}、{0,0,0,1} 或 {1,1,1,1} 的行,但在我的情况下是{0,0,1,1}。

当我之前使用 glBindAttribLocation() 来指定位置时,它在使用 3 种不同操作系统(ubuntu 12.04、windows 7 和 ubuntu 10.04)的 4 台不同机器上默认为 {1,1,1,1}。

假设跨机器的值是 {0,0,1,1} 是否安全?还是这仅仅是巧合?

4

2 回答 2

14

我可以期望值是什么特别的吗?

是的,它是一个特定的值。

假设您正确关闭了属性数组(即:glDisableVertexAttribArray在该属性索引上使用),您获得的值来自上下文中的顶点属性,由一glVertexAttrib组函数设置。这些是全局上下文状态,不存储在 VAO 中。

默认情况下,它们都从 (0, 0, 0, 1) 开始。但是,如果您使用该属性索引中的数组使用特定属性进行渲染,则上下文值将被有效地破坏。所以如果你想使用它,你应该重置上下文值。

于 2013-07-23T19:25:59.903 回答
1

它们在这里有点未定义,但这可能不是问题。GL 状态由CURRENT_VERTEX_ATTRIB值组成。最初,它们是 (0,0,0,1)。您可以通过函数族为那些未启用数组的属性显式设置属性值glVertexAttrib()

唯一需要担心的是在绘制期间实际启用属性数组时当前值会发生什么。引用规范(版本 3.3),第 2.8.3 节顶点数组 - 绘图命令:

如果与顶点着色器所需的通用属性对应的数组未启用,则从当前通用属性状态中获取相应的元素(参见第 2.7 节)。

如果启用了顶点着色器所需的泛型属性对应的数组,则在执行DrawArraysOneInstance.

因此,您只需在为该特定属性启用数组进行绘制后指定一个有用的值。

更新

从OpenGL 4.2开始,这种行为实际上已经改变:

如果与顶点着色器所需的通用属性对应的数组未启用,则从当前通用属性状态中获取相应的元素(参见第 2.7 节)。否则,如果启用了数组,则相应的当前通用属性值不受DrawArraysOneInstance 执行的影响。

所以现在,glDraw*()调用永远不会修改当前设置的属性值。

于 2013-07-23T19:30:18.257 回答