VertexArrayObject,如何设置 "default" 属性值?

VertexArrayObject, how can i set "default" attribute value?

我正在开发一个 OpenGL 应用程序,我正在尝试使 ShaderPrograms 和 VAO 相互独立。说独立是指 ShaderProgram 和 VAO 都可以有不同的属性集。

在创建新的 ShaderProgram 时,我明确地将已知属性列表绑定到预定义位置,即使着色器不使用它们也是如此。

  BindAttributeLocation(program, StandardAttribute.Position, PositionAttributeName);
  BindAttributeLocation(program, StandardAttribute.Color, ColorAttributeName);
  BindAttributeLocation(program, StandardAttribute.Normal, NormalAttributeName);
  BindAttributeLocation(program, StandardAttribute.TexCoord, TexCoordAttributeName);
  BindAttributeLocation(program, StandardAttribute.Tangent, TangentAttributeName);

我正在尝试用 VAO 做同样的事情,但是如果网格不包含我想设置默认值的属性数据:

vao.Bind();
if(mesh.Color == null) {
    DisableVertexAttribArray(attribute);
    VertexAttrib4f(attribute, 1, 1, 1, 1);
}
else {
    EnableVertexAttribArray(attribute);
    buffer.Bind();
    BufferData(mesh.Color);
    VertexAttribPointer(attribute, ...);
}

此代码似乎有效(到目前为止),但我不确定这是否是正确的方法。 VertexAttrib4f 在哪里存储数据:在 VAO 中,还是上下文全局状态,我需要在每次绘制调用后重置它?

当前属性值不是 VAO 状态的一部分。确认这一点的规范中最清晰的声明在 glGetVertexAttrib() 的描述中(强调已添加):

Note that all the queries except CURRENT_VERTEX_ATTRIB return values stored in the currently bound vertex array object

其中 CURRENT_VERTEX_ATTRIB 是您使用 glVertexAttrib4f() 设置的值。

这意味着这些值是全局上下文状态。

好的,我找到了关于此的好文章:opengl.org

A vertex shader can read an attribute that is not currently enabled (via glEnableVertexAttribArray​). The value that it gets is defined by special context state, which is not part of the VAO.

Because the attribute is defined by context state, it is constant over the course of a single draw call. Each attribute index has a separate value. Warning: Every time you issue a drawing command with an array enabled, the corresponding context attribute values become undefined. So if you want to, for example, use the non-array attribute index 3 after previously using an array in index 3, you need to repeatedly reset it to a known value.

The initial value for these is a floating-point (0.0, 0.0, 0.0, 1.0)​.