2013-07-23 34 views
7

我假设这将是“未定义”的那些东西之一,但我似乎无法从Google中找到具体的答案。使用布局限定符时,未缓冲顶点属性的OpenGL默认值

让我们在我的顶点着色器说我有:

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

但并没有什么缓冲,以地点2 glEnableVertexAttribArray()或glVertexAttribPointer()。我能期望价值是什么特别的吗?

我假设一个vec4它将沿{0,0,0,0},{0,0,0,1}或{1,1,1,1}行,但在我的情况是{0,0,1,1}。

当我先前使用glBindAttribLocation()来指定的位置,它默认为{1,1,1,1},用3个不同的操作系统4台不同的机器(Ubuntu的12.04,窗口7,和Ubuntu 10.04)。

跨机器假设值为{0,0,1,1}是否安全?或者这只是一个巧合?

回答

5

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

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

假设你正确关掉属性阵列(即:与glDisableVertexAttribArray该属性索引),将得到的值来自in-context vertex attribute,如由glVertexAttrib套件的功能设定。这些是全局上下文状态,不存储在VAO中。

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

+0

所以我已经为特定的位置编号设置了glDisableVertexAttribArray(),但它仍然在着色器中被读为{0,0,1,1}。我正在使用VAO,所以我只拨打一次电话。我应该在我的glDrawElements()调用之前禁用它们吗? – kbirk

+0

@Pondwater:如果VAO禁用它,则禁用它。您不必再次禁用它。另外,我做了一个补充答案。 –

+0

啊,这是有道理的!谢谢你的澄清! – kbirk

1

他们在这里没有定义,但这可能不是问题。 GL状态由CURRENT_VERTEX_ATTRIB值组成。最初,他们是(0,0,0,1)。您可以通过glVertexAttrib()系列函数明确地设置那些没有启用数组的属性值。

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

如果未启用对应于由顶点着色器 所需的通用属性的阵列,则对应的元素是从当前通用 采取属性状态(参见2.7节)。

如果对应于由顶点着色器所需要的通用属性的阵列是 使能时,相应的电流通用属性值是 执行的DrawArraysOneInstance后未定义的。

所以你必须指定一个有用的值,然后你为该特定属性启用了一个数组。

UPDATE

此行为已实际改变开始与OpenGL 4.2

如果未启用对应于由顶点着色器所需要的通用属性阵列 ,则相应的元件被取从当前通用属性 状态(请参阅第2.7节)。否则,如果启用了阵列,则通过执行DrawArraysOneInstance,相应的当前通用属性值不受影响

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

+0

“*它们在这里没有定义,但这可能不成问题,GL状态由CURRENT_VERTEX_ATTRIB值组成。*”那么这怎么会使它们变成“未定义的”?如果spec *定义它们,则不是不确定的。 –

+1

@NicolBolas:我指的事实,你启用了ATTRIB阵列渲染后(由SPEC)的值是不确定的,这是我承担OP在做,因为否则他们会一直在默认值,如果他甚至不知道有关'glVertexAttrib'。 – derhass