Search code examples
openglshadervertex-buffervertex-attributesvertex-array-object

Confusion about binding the index of a non-existent attribute using glVertexAttribPointer


When binding an attribute index using glVertexAttribPointer, what happens when an associated program does not contain an attribute at said index?

Is the behaviour undefined, or is the attribute ignored altogether?

I have searched the docs quite extensively, and have not been able to find much info about the link between programs and dynamic attribute bindings.


Solution

  • A program is not associated to a vertex array object. The vertex attribute index is the binding point. If a binding point is not "needed" by the program this doesn't cause any issue.


    [...] What about if there is an attribute at that index but it is of a different type than of that earlier specified using glVertexAttribPointer [...]

    OpenGL 4.6 API Core Profile Specification - 10.2.1 Current Generic Attributes, page 349:

    When values for a vertex shader attribute variable are sourced from a current generic attribute value, the attribute must be specified by a command compatible with the data type of the variable.

    This means if the data type of the attribute is floating point, then you've to specify the array of vertex attribute data by glVertexAttribPointer. If the data type is integral the you've to use glVertexAttribIPointer (focus on the I).
    If you ignore that, then the data in the vertex array buffer will be misinterpreted.

    OpenGL 4.6 API Core Profile Specification - 10.3.5 Transferring Array Elements, page 361:

    When a vertex is transferred to the GL by DrawArrays, DrawElements, or the other Draw* commands described below, each generic attribute is expanded to four components. If size is one then the x component of the attribute is specified by the array; the y, z, and w components are implicitly set to 0, 0, and 1, respectively. If size is two then the x and y components of the attribute are specified by the array; the z and w components are implicitly set to 0 and 1, respectively. If size is three then x, y, and z are specified, and w is implicitly set to 1. If size is four then all components are specified.

    So the tuple size of the vertex data and the tuple size of the data type of the vertex attribute in the shader program (e.g. float, vec2, vec3, ...) are allowed to be different.
    If the tuple size of the vertex attribute in the program is greater, then the data are expanded by 0 for the 2md and 3rd respectively 1 for the 4th component.
    If the tuple size of the vertex attribute in the program is less, then the additional components in the vertex array are "not used".