What is generic vertex attribute of glEnableVertexArrayAttrib

Hi, all! The docs say:

void glEnableVertexArrayAttrib(GLuint vaobj, GLuint index);

where index: Specifies the index of the generic vertex attribute to be enabled or disabled.

Which I do not understand. To put the question into context, I have:

#version 420 core                      
                                       
layout (location = 0) in vec4 position;
                                       
void main(void)                        
{                                      
  gl_Position = position;              
}
    const GLfloat positions[] =
      { 0.25, -0.25, 0.5, 1.0,
       -0.25, -0.25, 0.5, 1.0,
        0.25,  0.25, 0.5, 1.0 };

    const GLuint binding_index = 0, attrib_index = 22;

    const GLuint offset = 0, stride = sizeof(GLuint) * 4;

    const GLuint size = 4, relative_offset = 0;

    GLuint vao;

    glCreateVertexArrays(1, &vao);

    GLuint buffer;

    glCreateBuffers(1, &buffer);

    glNamedBufferStorage(buffer, 12 * sizeof(GLuint), &positions[0], NULL);

    glVertexArrayVertexBuffer(vao, binding_index, buffer, offset, stride);

    glVertexArrayAttribFormat(
      vao, attrib_index, size, GL_FLOAT, GL_FALSE, relative_offset);

    glVertexArrayAttribBinding(vao, attrib_index, binding_index);

    const int generic_vertex_attribute = 0;

    glEnableVertexArrayAttrib(vao, generic_vertex_attribute);

But how do I know generic_vertex_attribute to be 0? Otherwise, the triangle does not show. Also, binding_index also seems to have to be 0. Even if I change the (location = 0) part in the shader. But why? How exactly do these values relate to each other?

See this for example.

And here and there are additional information.

Thank you for the links. So, this is how understand things now:

  1. generic_vertex_attribute equals location specified in the shader for some attribute (location = #)
  2. glEnableVertexArrayAttrib(vao, generic_vertex_attribute); will enable fetching by searching for attrib_index in VAO, which was embedded there by calling glVertexArrayAttribBinding(vao, attrib_index, binding_index);
    Part of the confusion for me originated from the situation when triangle would not be drawn when I set binding_index in the code above higher than 15. So, this is a limit to how many buffers a vao can hold, which probably varies with implementation.
    Is all this right?

[QUOTE=meatich;1288626]Thank you for the links. So, this is how understand things now:

  1. generic_vertex_attribute equals location specified in the shader for some attribute (location = #)
  2. glEnableVertexArrayAttrib(vao, generic_vertex_attribute); will enable fetching by searching for attrib_index in VAO, which was embedded there by calling glVertexArrayAttribBinding(vao, attrib_index, binding_index);
    Part of the confusion for me originated from the situation when triangle would not be drawn when I set binding_index in the code above higher than 15. So, this is a limit to how many buffers a vao can hold, which probably varies with implementation.
    Is all this right?[/QUOTE]

It’s slightly more complex than that.

The VAO state consists of an array of per-attribute state, an array of per-buffer state, and an element buffer binding. Each vertex shader input variable is associated with an attribute index; this can be set using the location= qualifier, otherwise it will be chosen by the linker (and in either case can be queried with glGetAttribLocation). Each attribute is associated with a buffer via glVertexArrayAttribBinding (the initial state is a 1-to-1 correspondence, with attribute N bound to buffer N).

There is a limit on the maximum number of attributes, which can be queried using glGetIntegerv(GL_MAX_VERTEX_ATTRIBS). The limit is required to be at least 16. There is also a limit on the number of attribute buffers, which can be queried with glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS). Implicitly, the limit on the number of buffers must be at least that for attributes

glVertexArrayVertexBuffer and glVertexArrayBindingDivisor affect the per-buffer state. glVertexArrayAttribFormat, glVertexArrayAttribBinding, glEnableVertexArrayAttrib and glDisableVertexArrayAttrib affect the per-attribute state.

There are also non-DSA versions of these functions which affect the currently-bound VAO (rather than a specified VAO). And there are some functions which pre-date the distinction between attributes and buffers (glVertexAttribFormat, glVertexAttribDivisor).

OK, it makes sense. Thank you for the explanation, GClements!