Reputation: 321
I understand how to create the vertex and fragments shaders and how to create vertex arrays and put them on the buffer, but how do i link the two?
Meaning - when i run my program, how does it know that the vertices array that is on the currently active buffer should be "fed" to the vertex shader?
Is that being done simply by using glVertexAttribPointer
?
Upvotes: 3
Views: 384
Reputation: 72539
how does it know that the vertices array that is on the currently active buffer should be "fed" to the vertex shader
The "currently active buffer", i.e. GL_ARRAY_BUFFER
, isn't used during the draw call. It's only purpose is to tell the glVertexAttribPointer
functions which buffer to bind to the VAO. Once this connection is established GL_ARRAY_BUFFER
can be unbound.
... but how do i link the two?
The link between your vertex arrays and the vertex shader is the currently active vertex array object (VAO). The pipeline will fetch the vertex attributes that the shader needs from the buffers that were bound to the VAO.
It may help to summarized VAO state as the following pseudo-C definitions:
struct VertexArrayObject
{
// VertexArrayElementBuffer
uint element_buffer;
struct Binding {
// VertexArrayVertexBuffers
uint buffer;
intptr offset;
sizei stride;
// VertexArrayBindingDivisor
uint divisor;
} bindings[];
struct Attrib {
// VertexArrayAttribBinding
uint binding; // This is an index into bindings[]
// EnableVertexArrayAttrib
bool enabled;
// VertexArrayAttrib*Format
int size;
enum type;
boolean normalized;
boolean integer;
boolean long;
uint relativeoffset;
} attribs[];
};
The comments mention the corresponding OpenGL 4.5 DSA function that can be used to set the respective state.
When you use glVertexAttribPointer
, it essentially does the following on the currently bound VAO:
vao.attribs[index].binding = index;
vao.attribs[index].size = size;
vao.attribs[index].type = type;
vao.attribs[index].normalized = normalized;
vao.attribs[index].relativeoffset = 0;
vao.bindings[index].buffer = current ARRAY_BUFFER;
vao.bindings[index].offset = pointer;
vao.bindings[index].stride = stride; // if stride == 0 computes based on size and type
Notice that it's the glVertexAttribPointer
call that binds the 'active' buffer to the VAO. If instead you set up your VAO using the direct state access API (DSA), you don't even need to ever 'activate' any buffer.
Upvotes: 4