PDA

View Full Version : What is generic vertex attribute of glEnableVertexArrayAttrib



meatich
09-22-2017, 03:13 AM
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?

Silence
09-22-2017, 05:16 AM
See this (https://www.khronos.org/opengl/wiki/Vertex_Shader#Inputs) for example.

And here (https://www.khronos.org/opengl/wiki/Vertex_Specification) and there (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindAttribLocation.xhtml) are additional information.

meatich
09-22-2017, 08:40 AM
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?

GClements
09-22-2017, 10:12 AM
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?

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

meatich
09-23-2017, 04:09 AM
OK, it makes sense. Thank you for the explanation, GClements!