Vertex Attribute

From OpenGL Wiki
Revision as of 07:17, 20 August 2012 by Alfonse (talk | contribs) (Minor fixup.)
Jump to navigation Jump to search
Vertex Attribute
Core in version 4.6
Core since version 2.0
ARB extension ARB_vertex_program

A Vertex Attribute is a per-vertex value passed from an application's Buffer Object(s) to the first stage of the rendering pipeline (typically a Vertex Shader).

Vertex attributes are transferred, typically from buffer objects via Vertex Buffer Object(s) as defined by a Vertex Array Object, during Vertex Specification. Each attribute consists of one 4-element vector value, which can be a floating-point value, signed integral, unsigned integral, or (in GL 4.1+) a double-precision float.

Attribute indices

Each attribute has an index. Up to GL_MAX_VERTEX_ATTRIBS​ can be used by a shader. Double-precision attributes take up twice the space of single-precision ones. Therefore, a 3 or 4-element double-precision attribute really takes up 2 attribute slots.

At link time, vertex shader inputs are assigned an attribute index, in one of three ways. These are ordered in priority from highest to lowest:

  1. Explicit attribute specification via a layout qualifier. The shader can directly state that an input variable is assigned a specific attribute:
  2. Direct binding before linking. Calling glBindAttribLocation before linking the program will assign the input specified to the given attribute index.
  3. Implicit assignment. OpenGL will assign any vertex shader input an attribute index if it is not assigned by one of the above methods. This value will be arbitrarily assigned.

Array or matrix vertex shader inputs take up one attribute index for each array element or each matrix column, in sequence. So if an attribute is a in vec2 array[5];, this will take up five attribute indices in sequence. This is regardless of how they are assigned. So if you explicitly give it the index 10, then the above definition will use indices 10, 11, 12, 13, and 14.

If array/matrix assignments overlap with other explicit assignment, or cannot otherwise be assigned (because doing so would assign to an index beyond GL_MAX_VERTEX_ATTRIBS​, then a linking error will results.

Attribute index assignments for vertex shaders can be queried with glGetAttribLocation.

Attribute values and shader inputs

The size of the attribute used by a vertex shader input does not have to match the attribute sizes provided by glVertexAttribPointer. If the vertex shader input is larger, having more elements in the vector than the attribute array provides, then the extra values are filled in from (0, 0, 0, 1) values. So if the input is a vec4, but only 3 values are provided, the last component will be 1.0.

There does need to be some type correlation however. Floating-point intputs must use AttribPointer; integer (signed or unsigned) inputs must use AttribIPointer. Double-precision inputs must use AttribLPointer.

Context attributes

Vertex attributes are usually specified by vertex arrays stored in buffer objects and defined by properly set up Vertex Array Objects. However, each attribute index also has a context state value. If the vertex shader accesses an attribute index that is not drawn from an array (glEnableVertexAttribArray was not called), then the context's state value is used.

The context attribute value is set with the glVertexAttrib function(s).

Attribute zero

In core contexts, attribute zero has state like regular attributes. In a compatibility context, it does not have state.

Note: NVIDIA drivers almost always get this wrong, implementing the core behavior (more or less) even in a compatibility context.