PDA

View Full Version : Binding orders to update information in multiple VAO/VBO.



Amani77
09-10-2016, 04:00 AM
I am using several VAO with several VBO bindings to represent unique sets of data in my scene. I am having some trouble understanding the correct order in which I must bind each VAO/VBO when doing updates to data.

Lets say I have VAO1 and VAO2 each with a VBO, I(index)BO, C(command)BO, and two more VBOs for matrix information.

I setup by:
Enable AttribPointers 0..n;
Gen all VAO/ect Buffers.

Bind VAO;
Bind VBO;
Bind IBO;
Bind CBO;
Set divisor;
Bind mat VBO1;
Set divisor;
Bind mat VBO2;
Set divisor;
Unbind VAO;

I update information to VBO/IBO/CBO by:
Bind VBO/IBO/CBO;
Buffer;

I render by:
Bind VAO;
Draw;
Unbind VAO;

This method works for a single VAO fine. When I try to render/update the information for multiple VAOs I get a GL_INVALID_OPERATION error on the second VAOs draw call and I am uncertain where I am going wrong.

Do I need to re-link the VAO every time I want to update information in a specific VBO/IBO/CBO?

john_connor
09-10-2016, 04:51 AM
there is NO order in which you have to setup your vertex array object
you dont have to "re-link" anything after updating a buffer content

you setup your vertex array just once, when done, you just draw like you've described:

useProgram(program);
bind(VAO);
drawArrays(...);
unbind(VAO); // bind(0)
unbind(program); // useProgram(0)

post your code to get more precise infos ..
GL_INVALID_ENUM means you are giving wrong argument(s) to a gl-call

for you setup procedure:
--> the state of vertex attributes (enabled/disabled) is also stored in the VAO, so you have to do that for each VAO, not once (before binding any VAO)
--> the same is true for te vertex attrib pointers:

example:


glBindVertexarray(VAO1);

// use buffer VBO1 for vertex position
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glVertexAttribPointer(index1, 3, GL_FLOAT, false, ...);

// use buffer VBO2 for vertex texture coordinates
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glVertexAttribPointer(index2, 2, GL_FLOAT, false, ...);

// use buffer VBO3 for vertex normals
glBindBuffer(GL_ARRAY_BUFFER, VBO3);
glVertexAttribPointer(index3, 3, GL_FLOAT, false, ...);

// use buffer VBO4 for vertex color (if needed)
glBindBuffer(GL_ARRAY_BUFFER, VBO4);
glVertexAttribPointer(index4, 4, GL_FLOAT, false, ...);

// use buffer VBO5 for model instances (if needed)
glBindBuffer(GL_ARRAY_BUFFER, VBO5);
glVertexAttribPointer(index5, ...);

// finished, unbind buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);

// now enable attributes:
glEnableVertexAttribArray(index1);
glEnableVertexAttribArray(index2);
glEnableVertexAttribArray(index3);
glEnableVertexAttribArray(index4);
glEnableVertexAttribArray(index5);

// then set some divisors (if needed)
glVertexAttribDivisor(index5, 1);// if you call glDrawArraysInstanced(...) and want this attribute once per instance

glBindVertexarray(0);

// do the same for VAO2
// you can allocate buffer memory and set the content independent from this setup
// you have to set 4 attributes for each 4x4 matrix buffer

GClements
09-10-2016, 07:09 AM
Lets say I have VAO1 and VAO2 each with a VBO, I(index)BO, C(command)BO, and two more VBOs for matrix information.

What do you mean by "command" buffer object? GL_DRAW_INDIRECT_BUFFER? That binding isn't stored in a VAO, so changing the VAO won't affect it.

A VAO stores the current GL_ELEMENT_ARRAY_BUFFER buffer binding as well the buffers for each vertex attribute (but not the current GL_ARRAY_BUFFER binding).

Amani77
09-10-2016, 09:14 PM
What do you mean by "command" buffer object? GL_DRAW_INDIRECT_BUFFER? That binding isn't stored in a VAO, so changing the VAO won't affect it.

A VAO stores the current GL_ELEMENT_ARRAY_BUFFER buffer binding as well the buffers for each vertex attribute (but not the current GL_ARRAY_BUFFER binding).

This was exactly the problem. I very erroneously assumed that because there was a attrib pointer set up for it, it would be okay. Thanks.