Can I set VAO before VBO in OpenGL? - opengl

I have a Sphere class that generate the VBO for creating given input radius and some more parameters.
Each Sphere VBO share the same memory layout (let's say vertex indice 0 = vertices, 1 = colors).
I may getting wrong, but if a understand correctly, state is what VAO store. But I don't know if VAO reminds which VBO was bound or use the currently bound VBO. But I think it use the VBO bound when modifying it (so it imply that reconfiguring the VAO for each Sphere render)
Question #1
Is it possible to store on VAO for all of the spheres? Sharing one VAO for multiple VBO.
Question #2
Can we set up the VAO independently from the VBO ? I wanna say, before even creating the VBO and without VBO bound, for example in a static function before even creating Spheres.
Question #3
This question may have non sens and be case-specific, but should I use one VAO and one VBO for each Sphere or share one VAO for all the Spheres (if it's possible) ?

Using the separate attribute format API, it is easy to set up a VAO independently from any particular set of source buffer objects. The vertex format information (component type, count, etc) can all be established via glVertexAttribFormat without a buffer object. You can even set up the relationship between attribute indices and buffer binding points, so that you can read interleaved attributes from a single buffer binding. All without ever binding a buffer object.
Now at the end of the data, you will have to attach buffer objects to the VAO when it comes time to render (via glBindVertexBuffer(s)). And the VAO will store the buffers it was last set with. But you should essentially ignore this. Treat a VAO as if it were just the vertex format state, with buffer binding being something that you do right before you render with it.
And yes, having one VAO and multiple potential buffers that get read with that vertex format (or better yet, just one buffer with multiple mesh data in it that all share the same vertex format, with mesh selection being done via the baseVertex parameter of glDrawElementsBaseVertex) is the right way to go.
All that being said, you also should remember that all spheres are the same mesh. They may appear in different locations with different sizes, but that's just a matter of providing a different transform of a unit sphere. The only reason to use more than one sphere mesh is if you need different resolutions of spheres (more polygons vs. fewer).

Related

Do I need a VAO for each different object rendered?

I believe I misunderstood the limits of VAO's.
I have 3 VAO's, one for each vertex spec. format.
Focusing on the VAO intended for menus/quads rendering in homogeneous screen coordinates, how many buffers can I have connected to the same array index of a single VAO ?
Due to results in my program I am inclined to believe every separate instance rendered should have it's own VAO. However, I am still able to draw two instances using one VAO, although with incorrect results. (Cursor takes up fullscreen and position doesn't change, rendered overtop fullscreen TitleMenu).
I'm fairly certain I already know the answer is have a VAO for each instance with differing array buffer data, would just like confirmation I have rationalized this correctly.
Also, are the buffers bound to the VAO copied to the VAO and can be deleted?
Does a glVertexAttribPointer() need to be called again to update the information in a VAO ? Or is buffering data to the original buffer sufficient ?

Process of setting up a VAO in OpenGL

Can I get a more overall/general description of this?
I've been trying to research these things all week, but I only come into super technical explanations or examples.
Could somebody explain the overall process or goal of these VAO's? Maybe outline a bit of a "step-by-step" flowchart for setting up a VAO in OpenGL?
I've never been someone who learns by examples... so all the things I've found online have been really unhelpful so far.
Your Vertex Buffer Objects (VBOs) contain the vertex data. You set up attribute pointers which specify how that data should be accessed and interpreted in order to draw a vertex - how many components are there to each vertex, how are they stored (GL_FLOAT for example) etc.
The Vertex Array Object (VAO) saves all these attributes. Their purpose is to allow you to set up these attributes once and then restore them with one state change whenever you need to use them.
The advantage of this is you can easily set up multiple states and restore them - if I want to draw a cube and a triangle these are two different states - I create a VAO for each and the VAO saves the state for each of them. When I want to draw the cube, I restore the state for the cube only.
Setup
Setup has four steps:
Create the VAO
Bind the VAO
Set up the state
Unbind the VAO
Creating a VAO is very simple:
GLuint vao_name;
glGenVertexArrays(1, &vao_name);
This will generate one vertex array, and store it's name in vao_name.
Once your VAO is created you need to bind it:
glBindVertexArray(vao_name);
Now, any changes you make to the attribute pointers or bindings to the element array buffer will be saved. This is a call to any of the following:
glVertexAttribPointer(...)
glEnableVertexAttribArray(...)
glDisableVertexAttribArray(...)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)
Whenever you make one of these calls, the corresponding state is saved in the currently bound VAO. And when you later bind the VAO again, the state is restored.
Once you have set up the state you can unbind the VAO. Do this by binding VAO 0:
glBindVertexArrays(0);
You could also bind a different VAO and set up a different state for that. When this happens it is safe to make changes to the attribute pointers without disrupting your previous state.
Drawing
When you want to draw something all you have to do is restore the VAO:
glBindVertexArray(cube_vao)
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(triangle_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0); //Unbind the VAO
Edit:
These are some answers that helped me when I was trying to understand VAOs:
glVertexAttribPointer overwrite, glVertexAttribPointer clarification, When should glVertexAttribPointer be called?
Also, the OpenGL specification explains it well once you've got your head around the basics: https://www.opengl.org/registry/
The VAO holds all information about how to read the attributes from the VBOs.
This includes for each attribute, which VBO it is in; the offset, the stride, how it is encoded (int, float, normalized or not), how many values per attribute. In other words the parameters of glVertexAttribPointer (and the bound GL_ARRAY_BUFFER at the time of the call.
It also holds the element array buffer that holds the indexes.
For what VAO's are, see #ratchet-freak's answer.
As for the goal of VAO's, it's a matter of improving performance by allowing one single state change to setup all vertex attributes bindings, which not only means fewer function calls but also more opportunity for the OpenGL implementation to optimize for this state as a whole.
For VAO, an understanding of VBOs and Shader is a pre-requisite. VAOs provide a way to “pre-define” vertex data and its attributes.
One way to understand is to draw with VBOs and then draw the same with VAOs. You will notice that it is similar to drawing with VBOs, except that it is first "saved" in a VAO for later use. Subsequently, the VAO is made active to actually draw the saved state.
See VBO, Shader, VAO for a fairly good example.

OpenGL - Is it possible to use texture buffers with interleaved VBOs?

Is there a method for binding only a single attribute of a VBO to a texture buffer object?
Problem is, I use an interleaved VBO for drawing spheres with the attributes position, radius and another one. Now, I want to use another shader which draws other stuff using instanced geometry at the positions in my sphere VBO.
What I could do is just texelFetch() the data I need which is really ugly concerning the needed alignment (VBO attributes have different size) and the unused space, which is bad because of the limited size of a texture buffer. Another way could be copying only the data I need from one VBO to a separate VBO, but that's not really satisfying either.
So... is there another possibility?
Buffer textures do not have attributes. So what you're talking about doesn't make sense.
Also, VBOs are not a thing; there is no such thing as a "VBO". There are simply buffer objects and different uses for them. glVertexAttribPointer does not modify the buffer object. It just tells OpenGL's vertex reading system how to fetch data from it. Other systems that fetch data from buffer objects use their own mechanisms for doing so, which are entirely separate.
Like buffer textures.
If you want to "draws other stuff using instanced geometry", why don't you just use instancing? Apply a divisor (presumably of 1) to those attributes, so that they will only get different values for different instances.

Do I need to rebuild my VAO if I need to change a VBO?

I'm rendering my scene by constructing or modifying a buffer that I give to glBufferData. My understanding of Vertex Array Objects is that they allow me to skip the manual binding of all of the VBOs I am using. Is this still the case when I update my buffer all the time?
Can I bind my VAO, call glBufferData to update the vertices and indices (the only two VBOs I have at the moment), and then render?
Can I use memory mapping with the VBO's? Then I could bind VAO, modify buffer, then render?
What exactly does the VAO do? Is its function simply that of a shortcut which stores and automates the binding of vertex attributes to my VBO's? Does it take ownership of either the data or the bindings?
You would probably have to test this, but from my understanding VBOs are given IDs when generated and a VAO only references each vertex attrib along with the VBO ID it's using. You should be able to call glBufferData or glBufferSubData. I'm not sure if memory mapping just before the draw call would work, but you could certainly do things between binding the VAO and drawing. A VAO doesn't lock the VBOs or restrict access to them.
In general, a VAO just stores attributes and all their settings (bound VBO, stride, offset, etc.) and automatically binds the attributes when bound. Until you call glBindVertexArray(0);, all vertex attributes are tied to the bound VAO.

VBO per shader attribute without VAO, or different approach?

I'm using various 'nested' contexts in my application (for shader and geometry sharing), so I cannot use VAOs as they cannot be shared across contexts.
My mesh data is stored in one VBO as a 'pool' of unique vertices, and in another VBO I store the indices that make up the faces. I'm currently using this successfully for wireframe rendering in my CAD app, but I would like to add a flat shaded mode - and for that I need face normals.
If I needed vertex normals, I would just append the data to the vertex position data, but I can't do that here because a vertex would have a different face normal depending on which face it belonged to is being rendered. Ideally I would like to create another VBO pair holding my face normals and indices, however I can't bind two VBOs to the same target without a VAO - even though they're used in different attributes.
I appreciate that the normal route is to use a VAO which does let you assign multiple VBOs to the same target, but I can't use them because my geometry context is shared and VAOs are not. Are there any alternative solutions to this issue?
If I needed vertex normals, I would just append the data to the vertex position data, but I can't do that here because a vertex would have a different face normal depending on which face it belonged to is being rendered. Ideally I would like to create another VBO pair holding my face normals and indices, however I can't bind two VBOs to the same target without a VAO - even though they're used in different attributes.
Your problem has nothing to do with VAOs or buffer objects. VAOs do not allow you to have multiple index lists. They do not allow you to have "face normals".
A vertex array objects is nothing more than a container that stores vertex attribute bindings. They do not enable you to do anything you couldn't do without them; there's simply a convenient way to change all attribute bindings.
You need to break your vertex positions up into different faces. So you need to duplicate position values, so that each unique position/normal pair is properly unique. VAOs don't get around this limitation.
FYI: the reason VAOs aren't shared is because they're too simple to bother sharing. You can set the same VAO up in two different contexts easily enough. Just create a VAO in the context you want to use it in, and do what you would normally do to set it up. It's just a simple state object; it doesn't really contain anything.