2

I'm developing an OpenGL application and I'm trying to make ShaderPrograms and VAO's independent of each other. Saying independent I mean that both ShaderProgram and VAO can have different set of attributes.

While creating new ShaderProgram I explicitly bind list of known attributes to predefined locations even if shader does not use them.

  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);

Pretty same thing I'm trying to do with VAO, but if mesh does not contain data for attribute I want to set default value:

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

This code seems to be working (so far), but I'm not sure if this is a correct approach. Where do VertexAttrib4f stores data: in VAO, or is it context global state and I need to reset it after each draw call?

xorza
  • 1,574
  • 1
  • 11
  • 15

2 Answers2

4

The current attribute value is not part of the VAO state. The clearest statement in the spec that confirms this is in the description of glGetVertexAttrib() (emphasis added):

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

where CURRENT_VERTEX_ATTRIB is the value you set with glVertexAttrib4f().

This means that the values are global context state.

Reto Koradi
  • 49,246
  • 7
  • 76
  • 116
3

Okay, I found good article about this: 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)​.

xorza
  • 1,574
  • 1
  • 11
  • 15