It\'s not obvious from the documentation when glVertexAttribPointer
should be called. It looks like it\'s part of VBO initialisation, but I notice example code
The association of buffer, generic vertex attribute and shader attribute variable are quite subtle. glVertexAttribPointer
establishes this association. See OpenGL-Terminology for a detailed explanation.
Also, the link OpenGL-VBO,shader,VAO shows a working example with the necessary sequence of API calls.
The function glVertexAttribPointer
specifies the format and source buffer (ignoring the deprecated usage of client arrays) of a vertex attribute that is used when rendering something (i.e. the next glDraw...
call).
Now there are two scenarios. You either use vertex array objects (VAOs) or you don't (though not using VAOs is deprecated and discouraged/prohibited in modern OpenGL). If you're not using VAOs, then you would usually call glVertexAttribPointer
(and the corresponding glEnableVertexAttribArray
) right before rendering to setup the state properly. If using VAOs though, you actually call it (and the enable function) inside the VAO creation code (which is usually part of some initialization or object creation), since its settings are stored inside the VAO and all you need to do when rendering is bind the VAO and call a draw function.
But no matter when you call glVertexAttribPointer
, you should bind the corresponding buffer right before (no matter when that was actually created and filled), since the glVertexAttribPointer
function sets the currently bound GL_ARRAY_BUFFER
as source buffer for this attribute (and stores this setting, so afterwards you can freely bind another VBO).
So in modern OpenGL using VAOs (which is recommended), it's usually similar to this workflow:
//initialization
glGenVertexArrays
glBindVertexArray
glGenBuffers
glBindBuffer
glBufferData
glVertexAttribPointer
glEnableVertexAttribArray
glBindVertexArray(0)
glDeleteBuffers //you can already delete it after the VAO is unbound, since the
//VAO still references it, keeping it alive (see comments below).
...
//rendering
glBindVertexArray
glDrawWhatever
When not using VAOs it would be something like that:
//initialization
glGenBuffers
glBindBuffer
glBufferData
...
//rendering
glBindBuffer
glVertexAttribPointer
glEnableVertexAttribArray
glDrawWhatever
glVertexAttribPointer
has to be called (in most cases) when the appropriate (i.e. the one you want to use) VBO is bound. Then last parameter to it is offset in said buffer.
The last parameter is defined particularly nice in the reference manual:
Specifies a offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. The initial value is 0.
Appropriate Vertex Pointer Bindings with VBO sources are stored inside VAO, and you should use that if possible.
Short example (excuse my pseudocode):
// Setup
CreateVAO(); BindVAO();
CreateVBO(); BindVBO();
VertexAttribPointer(/*id*/ 0, 3, GL_FLOAT, /*starting at offset*/ 0);
// We have specified Vertex attribute bound to location 0,
// with size of 3 floats, starting at offset 0 of VBO we've just created.
//Draw
BindVAO();
Draw();
glVertexAttribPointer
is something that does not really belong to the Buffer nor to the Program it is - let's say - the glue between them. (The functionality of this is splitten in Opengl 4.3 in different functions VertexAttrib*Format
, VertexAttribBinding
and BindVertexBuffer
aviable through the ARB_vertex_attrib_binding )
But if you want to say that it is part of something i would say it is part of the VAO
that stores the state of which Buffer objects are bound, which attribs are enabled and how the Buffer data has to be passed to the Program.
So it belongs to part where you setup your VAO
s.
EDIT Simple setup that illustrates the order:
Buffer
s and creating programsVAO
define which attribs are enabled, which buffers should be bound when the VAO
is used and how that data is passed to the program (glVertexAttribPointer
)