VBO is used to store vertex data, including vertex colors, coordinates, normals, and indices of vertices.
Vao is used to store information about how the graphics processor will use the data inside the VBO, and what coordinates are in the vertex data, which are the colors, and which are the normals.
I've never been too clear about these before, so I guess there's a part of me that I don't understand, so I'm going to use Cocos2d-x's renderer code to illustrate the difference between Vao and no vao, to deepen the understanding of Vao.
Let's start by looking at the initialization code:
void Renderer::setupbuffer () { if (configuration::getinstance ()->supportsshareablevao ()) { Setupvboandvao (); } else { setupvbo (); }}
From the above code we know that there are vao and no VAO when the initialization code is not the same. Then let's take a look at the difference between Setupvboandvao and Setupvbo.
First look at the situation with Vao:
void Renderer::setupvboandvao () {//generate Vbo and Vao for Trianglescommand glgenvertexarrays (1, &_buffersvao); Gl::bindvao (_buffersvao); Glgenbuffers (2, &_buffersvbo[0]); Glbindbuffer (Gl_array_buffer, _buffersvbo[0]); Glbufferdata (Gl_array_buffer, sizeof (_verts[0]) * vbo_size, _verts, Gl_dynamic_draw); Vertices Glenablevertexattribarray (glprogram::vertex_attrib_position); Glvertexattribpointer (Glprogram::vertex_attrib_position, 3, gl_float, Gl_false, sizeof (V3F_C4B_T2F), (GLvoid*) Offsetof (v3f_c4b_t2f, vertices)); Colors Glenablevertexattribarray (glprogram::vertex_attrib_color); Glvertexattribpointer (Glprogram::vertex_attrib_color, 4, Gl_unsigned_byte, gl_true, sizeof (V3F_C4B_T2F), (GLvoid*) Offsetof (v3f_c4b_t2f, colors)); Tex coords Glenablevertexattribarray (Glprogram::vertex_attrib_tex_coord); Glvertexattribpointer (Glprogram::vertex_attrib_tex_coord, 2, gl_float, Gl_false, sizeof (V3F_C4B_T2F), (GLvoid*) Offsetof (V3f_c4B_T2F, texcoords)); Glbindbuffer (Gl_element_array_buffer, _buffersvbo[1]); Glbufferdata (Gl_element_array_buffer, sizeof (_indices[0]) * index_vbo_size, _indices, Gl_static_draw); Must unbind the VAO before changing the element buffer. Gl::bindvao (0); Glbindbuffer (gl_element_array_buffer, 0); Glbindbuffer (gl_array_buffer, 0); Generate Vbo and Vao for Quadcommand glgenvertexarrays (1, &_quadvao); Gl::bindvao (_quadvao); Glgenbuffers (2, &_quadbuffersvbo[0]); Glbindbuffer (Gl_array_buffer, _quadbuffersvbo[0]); Glbufferdata (Gl_array_buffer, sizeof (_quadverts[0]) * vbo_size, _quadverts, Gl_dynamic_draw); Vertices Glenablevertexattribarray (glprogram::vertex_attrib_position); Glvertexattribpointer (Glprogram::vertex_attrib_position, 3, gl_float, Gl_false, sizeof (V3F_C4B_T2F), (GLvoid*) Offsetof (v3f_c4b_t2f, vertices)); Colors Glenablevertexattribarray (glprogram::vertex_attrib_color); Glvertexattribpointer (GLPRogram::vertex_attrib_color, 4, Gl_unsigned_byte, gl_true, sizeof (V3F_C4B_T2F), (glvoid*) offsetof (V3F_C4B_T2F, colors)); Tex coords Glenablevertexattribarray (Glprogram::vertex_attrib_tex_coord); Glvertexattribpointer (Glprogram::vertex_attrib_tex_coord, 2, gl_float, Gl_false, sizeof (V3F_C4B_T2F), (GLvoid*) Offsetof (V3F_C4B_T2F, texcoords)); Glbindbuffer (Gl_element_array_buffer, _quadbuffersvbo[1]); Glbufferdata (Gl_element_array_buffer, sizeof (_quadindices[0]) * index_vbo_size, _quadindices, GL_STATIC_DRAW); Must unbind the VAO before changing the element buffer. Gl::bindvao (0); Glbindbuffer (gl_element_array_buffer, 0); Glbindbuffer (gl_array_buffer, 0); Check_gl_error_debug ();}
In the above code, the first half is the initialization triangle VAO, the latter part is the initialization of the four-sided Vao, the pattern is basically the same, so only a half part,
Here we first create a vao and bind to it, the next is to use the entire VAO, and then generate 2 Vbo to hold the vertex data and the fixed-point indicis data.
Then bind the data to the vertex data, which tells the opengles where the vertex data is, and then sets the color, normals, and coordinate information for the point.
Then continue to bind the indices data. Close the Vao,vbo.
Look at the situation without VBO:
void Renderer::setupvbo () {glgenbuffers (2, &_buffersvbo[0]); Glgenbuffers (2, &_quadbuffersvbo[0]); Mapbuffers ();} void Renderer::mapbuffers () {//Avoid changing the element buffer for whatever VAO might is bound. Gl::bindvao (0); Glbindbuffer (Gl_array_buffer, _buffersvbo[0]); Glbufferdata (Gl_array_buffer, sizeof (_verts[0]) * vbo_size, _verts, Gl_dynamic_draw); Glbindbuffer (Gl_array_buffer, _quadbuffersvbo[0]); Glbufferdata (Gl_array_buffer, sizeof (_quadverts[0]) * vbo_size, _quadverts, Gl_dynamic_draw); Glbindbuffer (gl_array_buffer, 0); Glbindbuffer (Gl_element_array_buffer, _buffersvbo[1]); Glbufferdata (Gl_element_array_buffer, sizeof (_indices[0]) * index_vbo_size, _indices, Gl_static_draw); Glbindbuffer (Gl_element_array_buffer, _quadbuffersvbo[1]); Glbufferdata (Gl_element_array_buffer, sizeof (_quadindices[0]) * index_vbo_size, _quadindices, GL_STATIC_DRAW); Glbindbuffer (gl_element_array_buffer, 0); Check_gl_error_debug ();}
From the code can be seen, in the absence of Vao, in addition to not set the point of color, coordinates and normal information to think that the other and have Vao when the basic is the same.
From the initialization can be seen a part of the difference, because Vao can store vertex usage information, so we can set this information to Vao when there is Vao, but what is the benefit after setting to Vao, let us continue to look at the code used below.
void Renderer::d rawbatchedquads () {//todo:we can improve the draw performance by Insert material switching command BEF Ore hand. int indextodraw = 0; int startIndex = 0; Upload Buffer to VBO if (_numberquads <= 0 | | _batchquadcommands.empty ()) {return; } if (Configuration::getinstance ()->supportsshareablevao ()) {//bind VAO Gl::bindvao (_quadvao); Set VBO Data Glbindbuffer (Gl_array_buffer, _quadbuffersvbo[0]); Option 1:subdata//Glbuffersubdata (Gl_array_buffer, sizeof (_quads[0]) *start, sizeof (_quads[0]) * N, &A Mp;_quads[start]); Option 2:data//Glbufferdata (Gl_array_buffer, sizeof (quads_[0]) * (N-start), &quads_[start], Gl_dyn Amic_draw); Option 3:orphaning + Glmapbuffer glbufferdata (gl_array_buffer, sizeof (_quadverts[0]) * _numberquads * 4, Nullpt R, Gl_dynamic_draw); void *buf = Glmapbuffer (gl_array_buffer, gl_write_only); memcpy (buf, _quadverts, sizeof (_quadverts[0]) * _numberquads * 4); Glunmapbuffer (Gl_array_buffer); Glbindbuffer (gl_array_buffer, 0); Glbindbuffer (Gl_element_array_buffer, _quadbuffersvbo[1]); } else {#define Kquadsize sizeof (_verts[0]) glbindbuffer (Gl_array_buffer, _quadbuffersvbo[0]); Glbufferdata (Gl_array_buffer, sizeof (_quadverts[0)) * _numberquads * 4, _quadverts, Gl_dynamic_draw); Gl::enablevertexattribs (Gl::vertex_attrib_flag_pos_color_tex); Vertices Glvertexattribpointer (glprogram::vertex_attrib_position, 3, Gl_float, Gl_false, Kquadsize, (GLvoid*) of Fsetof (v3f_c4b_t2f, vertices)); Colors Glvertexattribpointer (Glprogram::vertex_attrib_color, 4, Gl_unsigned_byte, Gl_true, Kquadsize, (GLvoid*) Offsetof (v3f_c4b_t2f, colors)); Tex coords Glvertexattribpointer (Glprogram::vertex_attrib_tex_coord, 2, Gl_float, Gl_false, Kquadsize, (glvoid*) offsetof (v3f_c4b_t2f, texcoords)); Glbindbuffer (Gl_element_array_buffer, _quadbuffersvbo[1]); } ......}
The ellipsis is followed by a purge code as follows:
if (Configuration::getinstance ()->supportsshareablevao ()) { //unbind VAO gl::bindvao (0); } else { glbindbuffer (gl_array_buffer, 0); Glbindbuffer (gl_element_array_buffer, 0); }
This function is used to draw quads, and the triangles are basically similar to this function.
When there is a Vao:
1. Enable Vao
2. Update the vertex buff data (because vertices may have been updated)
3, enable gl_element_array_buffer for the use of the back gldrawelements .
This is because the vertex usage information (color, package, normal position) has been saved to Vao, so you do not need to set this information again to Opengles.
In the absence of Vao:
1, update the vertex data, with the second step above.
2, set the use of vertex information, there is additional opengles data interaction.
3, with the Vao of the time of the third step.
Thus, because VAO preserves the usage information of vertices, it reduces the interaction of the graphics processor and CPU resulting from the use of vertex information for each drawing, saving rendering time.
This is also the role of Vao.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
OpenGL VAO and VBO