Variety of questions concerning VAO's

I am transitioning from learning to implementing opengl and am cutting out all unnecessary code from my main loop. I am currently implementing VAO’s and have some questions regarding what information needs to be buffered only once and how to modify buffered data.

When glDrawArrays() is called, is every buffer that has ever been bound to the currently bound VAO rendered?

If not, how does glDrawArrays know which buffer to render with its parameters?

If so, how do you remove/modify data from the VAO that has already been buffered ? Will deleting/modifying the original buffer do the trick? I thought once glVertexAtrribPointer() was called the buffer was copied to the currently bound VAO.

Also, do you HAVE to call enableVertexAttribArray(i) after you have called all the glVertexAttribPointer()'s for that particular index or can you enable the arrays beforehand ?

Why do I need to have data already buffered in a VBO before I call glVertexAttribPointer() ?

I am using 3 VAO’s, one for each vertex data format. I am encountering problems when trying to call glVertexAttribPointer multiple times for one VAO. Is this the proper way to use VAO’s or does each set of buffers need their own VAO? That is my suspicion.

That’s a lot of questions. That’s so many questions, it is likely that you don’t really understand VAOs very well. It seems more like you’ve maybe looked at some code that contains commands, but you don’t really understand what those commands do, how they relate to one another, or what VAOs are for.

That is, you seem to need a primer on what all this stuff is about. The OpenGL Wiki article on Vertex Specification lays everything out as far as how you prepare for rendering. I would suggest taking some time to run through that.

And when you do, I would advise you to forget your questions. Try not to read the article with any preconceived notions. Forget everything you think you know about how you set up code to render, and just read it exactly for what it says.

I will answer this question:

Why do I need to have data already buffered in a VBO before I call glVertexAttribPointer() ?

You don’t. You need to have created a valid buffer object, and it’s generally a good idea to have storage in that buffer before setting up to render. But there is nothing which requires this buffer to have storage yet.

You need data before you can render. But not for setting up the VAO.

how does glDrawArrays know which buffer to render with its parameters?

actually, glDrawArrays(…) “knows” nothing, it just invokes the vertex shader. for each vertex shader invocation, the vertex data gets pulled into the vertex shader according to what the vertex array object says. if you havent setup the currently bound VAO somehow, no data at all gets sent to the vertex shader, and its vertex attributes are by default 0. (you can change the default value using glVertexAttrib*(…))

if you want to pull data from several (or just 1) vertex buffer objects, you have to set the attrib pointers etc.

if you want to use indexed drawing, your VAO needs to “know” what element buffer you want the indices to be pulled from.
https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexArrayElementBuffer.xhtml

for each vertex attribute you have, you need to call 1 times glVertexAttrib*Pointer(…). for example:

struct Vertex_PTN {
    vec3 Position;
    vec2 TexCoord;
    vec3 Normal;
};

… need exactly 3 glVertexAttribPointer(…) calls, per VAO. you can pull the data from 1 buffer or 3 different buffers, however the 3 glVertexAttribPointer(…) calls are needed. and these calls are only needed once, then they are kept / stored in the VAO. dont modify the VAO each frame.