[Opengl] relationship between VAO and VBO

Posted by slyte33 on Mon, 07 Mar 2022 08:10:47 +0100

Reprint here

Note: both VAO and VBO are used to store vertex information and send it to vertex shader. As for what are vertices and vertices Shaders , I won't say much here. Readers who don't understand CSDN can do it by themselves.

B in VBO means Buffer, which is used to store vertex data; The A of VAO is Array, but I think it is better understood as attribute, which means the attribute of Buffer(VBO).

That is, we use VBO to store data, and VAO to tell the computer what properties and functions these data have respectively.

1, Role of VBO

VBO is the bridge between CPU and GPU to transfer information. We store the data in VBO (this step is executed by CPU), and then VBO will automatically send the data to GPU.

Send GPU In this step, no human operation is required. The user is only responsible for storing data into VBO. As follows:

However, for GPU, VBO is just a pile of numbers. How to explain them? This requires VAO.

2, Role of VAO

VBO is to transfer vertex data to GPU, and VAO is to interpret vertex data to GPU. Some readers will wonder that the vertex data is nothing more than three-dimensional coordinates. Three are a group, and they are transmitted. Why do you need to explain? Let's look at the data in VBO:

float buffer = {
   	//Vertex coordinates (in groups of 3) / / vertex colors (in groups of 3) / / texture coordinates (in groups of 2)
    0.5f,  0.5f, 0.0f,                1.0f, 0.0f, 0.0f,               1.0f, 1.0f,
    0.5f, -0.5f, 0.0f,                0.0f, 1.0f, 0.0f,               1.0f, 0.0f,
   -0.5f, -0.5f, 0.0f,                0.0f, 0.0f, 1.0f,               0.0f, 0.0f,
   -0.5f,  0.5f, 0.0f,                1.0f, 1.0f, 0.0f,               0.0f, 1.0f
};
//The above data is only fabricated by this blog post and has no practical significance

   

It can be seen from the above data that the vertex data is not just three-dimensional coordinates in a group!

If we pass the above information into VBO buffer And VBO sends them to the GPU.

However, vertex shaders don't know how to interpret these numbers, whether to group them in three, first three, then two, or three, two, three?

GPU doesn't know.

This requires the participation of VAO, which is responsible for telling GPU how many information in VBO should be grouped. The following program is to save the description of the data in VBO into a VAO:

	//vertex coord
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // color attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    // texture coord attribute
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

   

The above program seems to have three sections (glVertexAttribPointer() + glEnableVertexAttribArray()) as one section), but they all exist in the same VAO. (the functions of glVertexAttribPointer() and glEnableVertexAttribArray() will not be introduced here. Readers who don't understand can check online.)

In some complex OpenGL programs, there may be multiple vbos, but there is only one VAO. So, how to use a VAO to explain multiple vbos?

3, One VAO and multiple vbos

In OpenGL programs, there may be multiple vbos, but there is only one VAO. So, how to use a VAO to explain multiple vbos?

This involves OpenGL Context knowledge: a complete OpenGL program is equivalent to a container. When we use VAO and VBO, we need to Bind (Bind operation) first and then use it. VAO/VBO without binding does not work.

The relationship between one VAO and multiple vbos is roughly as follows:

Then, according to the relationship between one VAO and multiple vbos and the knowledge of OpenGL context (binding), the operation process of using one VAO to explain multiple vbos is as follows:

First, bind VAO,To inform OpenGL The program should use this VAO Right VBO Explain.

Then, bind the first VBO, write data to the VBO, and tell the VAO how to interpret the VBO information;
Then, unbind the VBO.

Then, bind the second VBO, write data to the VBO, and save the information about how to interpret the VBO in the VAO;
Then, unbind the VBO.
......

The procedure is as follows:

	unsigned int VBO[2], VAO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(2, VBO);

//=Bind VAO=======
glBindVertexArray(VAO);
//===============================================================

//=Bind first VBO======
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
//===============================================================

<span class="token function">glBufferData</span><span class="token punctuation">(</span>GL_ARRAY_BUFFER<span class="token punctuation">,</span> sphereVertices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">float</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>sphereVertices<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> GL_STATIC_DRAW<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Write data to the first VBO</span>

//How to explain the first message of VAO=
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 sizeof(float), (void)0);
glEnableVertexAttribArray(0);
//===============================================================

//=Unbind the first VBO=====
glBindBuffer(GL_ARRAY_BUFFER, 0);
//===============================================================

//=Bind second VBO======
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
//===============================================================

<span class="token function">glBufferData</span><span class="token punctuation">(</span>GL_ARRAY_BUFFER<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>texVertrices<span class="token punctuation">)</span><span class="token punctuation">,</span> texVertrices<span class="token punctuation">,</span> GL_STATIC_DRAW<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//Write data to the second VBO</span>

//Information that tells the VAO how to interpret the second VBO=
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 sizeof(float), (void)0);
glEnableVertexAttribArray(1);
//=============================================================

Topics: OpenGL