<p>VAO can share VBO's because they do not store vertex data itself but references to Vertex Buffer Objects. </p>

<p>So you can first generate your buffers and upload your buffer data (vertex data and index data) to currently bound buffers.</p>

<pre><code>glGenBuffers(1, &amp;VBO_xzCoord_IDs[i]);
glGenBuffers(1, &amp;VBO_yCoord_IDs[i]);
glGenBuffers(1, &amp;VBO_indices_IDs[i]);
glGenBuffers(1, &amp;VBO_normals_IDs[i]);
glGenBuffers(1, &amp;VBO_colors_IDs[i]);

//xz coords
glBindBuffer(GL_ARRAY_BUFFER, VBO_xzCoord_IDs[i]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*xzCoords.size(), &amp;xzCoords[0], GL_STATIC_DRAW);

...

//indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_indices_IDs[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*indices.size(), &amp;indices[0], GL_STATIC_DRAW);
</code></pre>

<p>And then generate your VAO's and connect vertex array object data index you provide in <code>glVertexAttribPointer</code> call with currently bound <code>GL_ARRAY_BUFFER</code>.</p>

<p>The <code>GL_ELEMENT_ARRAY_BUFFER</code> can be a little confusing because it doesn't require <code>glVertexAttribPointer</code> call. So how it is connected with VAO? It seems that binding the buffer ties it to the currently bound VAO.</p>

<pre><code>//VAO
glGenVertexArrays(1, &amp;VAO_IDs[i]);
glBindVertexArray(VAO_IDs[i]);

//xz coords
glBindBuffer(GL_ARRAY_BUFFER, VBO_xzCoord_IDs[i]);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

...

//indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_indices_IDs[i]);

glBindVertexArray(0);
</code></pre>

<p>And in your rendering call you don't need to bind <code>GL_ELEMENT_ARRAY_BUFFER</code> because it was already connected with VAO.</p>

CC BY-SA 3.0
2017-01-29T16:06:53.177Z
Thank you. I made it so that the "shared VBOs" are only calling glBufferData once, then they are rebounded and set to a vertex attribute for each VAO. So I don't need to call glBufferData for 10 time with the same data:)
remi000
CC BY-SA 3.0
2017-01-29T15:52:14.177Z
2017-01-29T15:52:14.177Z
mdkdy
<p>Let's say I have a have 10 different terrains. Each terrain have the same x and z coordinates, but they have different y coordinate, normals and colors. The indices used for element rendering is also the same.</p>

<p>The data looks like this:</p>

<pre><code>std::vector&lt;GLfloat&gt; xzCoords;
std::vector&lt;GLuint&gt; indices;

std::vector&lt;GLfloat&gt; yCoords[10];
std::vector&lt;GLfloat&gt; normals[10];
std::vector&lt;GLfloat&gt; colors[10];
</code></pre>

<p>And the VBO and VAO IDs:</p>

<pre><code>GLuint VAO_IDs[10];
GLuint VBO_xzCoord_IDs[10];
GLuint VBO_yCoord_IDs[10];
GLuint VBO_indices_IDs[10];
GLuint VBO_normals_IDs[10];
GLuint VBO_colors_IDs[10];
</code></pre>

<p>If I want one VAO for each of the terrain deffinitions, how would that look if the VBO for xz coordinates and indices are the same for each?</p>

<p>What I am doing now looks like this:</p>

<p>Setting up the buffers:</p>

<pre><code>for (size_t i = 0; i &lt; 10; i++){
        //VAO
        glGenVertexArrays(1, &amp;VAO_IDs[i]);
        glBindVertexArray(VAO_IDs[i]);

        //VBO
        glGenBuffers(1, &amp;VBO_xzCoord_IDs[i]);
        glGenBuffers(1, &amp;VBO_yCoord_IDs[i]);
        glGenBuffers(1, &amp;VBO_indices_IDs[i]);
        glGenBuffers(1, &amp;VBO_normals_IDs[i]);
        glGenBuffers(1, &amp;VBO_colors_IDs[i]);

        //xz coords
        glBindBuffer(GL_ARRAY_BUFFER, VBO_xzCoord_IDs[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*xzCoords.size(), &amp;xzCoords[0], GL_STATIC_DRAW);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
        glEnableVertexAttribArray(0);
        //y coords
        glBindBuffer(GL_ARRAY_BUFFER, VBO_yCoord_IDs[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*yCoords[i].size(), &amp;yCoords[i][0], GL_STREAM_DRAW);
        glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, (void*)0);
        glEnableVertexAttribArray(1);
        //normals
        glBindBuffer(GL_ARRAY_BUFFER, VBO_normals_IDs[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VBO_normals_IDs[i].size(), &amp;VBO_normals_IDs[i][0], GL_STREAM_DRAW);
        glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, (void*)0);
        glEnableVertexAttribArray(2);
        //colors
        glBindBuffer(GL_ARRAY_BUFFER, VBO_colors_IDs[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VBO_colors_IDs[i].size(), &amp;VBO_colors_IDs[i][0], GL_STREAM_DRAW);
        glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, (void*)0);
        glEnableVertexAttribArray(3);

//indices
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_indices_IDs[i]);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*indices.size(), &amp;indices[0], GL_STATIC_DRAW);
    }
</code></pre>

<p>Rendering function:</p>

<pre><code>for (size_t i = 0; i &lt; 10; i++)
    {
        glBindVertexArray(VAO_IDs[i]);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_indices_IDs[i]);
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void*)0);

    }
</code></pre>

<p>So as you can see, I create a new xz-coordinates and indices buffer for each VAO. I doubt this is the most effective way to do it. How should I do this?</p>

CC BY-SA 3.0
2017-01-29T14:58:39.057Z
Step 1: Stop confusing the act of creating a buffer with the act of using that buffer with a VAO.
Nicol Bolas
<opengl><rendering><vertex-buffer-object>
Multiple VAO share a VBO
remi000
# Multiple VAO share a VBO

(Asked by: username_0 on 2017-01-29)

Let's say I have a have 10 different terrains. Each terrain have the same x and z coordinates, but they have different y coordinate, normals and colors. The indices used for element rendering is also the same.

The data looks like this:

```
std::vector<GLfloat> xzCoords;
std::vector<GLuint> indices;

std::vector<GLfloat> yCoords[10];
std::vector<GLfloat> normals[10];
std::vector<GLfloat> colors[10];

```

And the VBO and VAO IDs:

```
GLuint VAO_IDs[10];
GLuint VBO_xzCoord_IDs[10];
GLuint VBO_yCoord_IDs[10];
GLuint VBO_indices_IDs[10];
GLuint VBO_normals_IDs[10];
GLuint VBO_colors_IDs[10];

```

If I want one VAO for each of the terrain deffinitions, how would that look if the VBO for xz coordinates and indices are the same for each?

What I am doing now looks like this:

Setting up the buffers:

```
for (size_t i = 0; i < 10; i++){
        //VAO
        glGenVertexArrays(1, &VAO_IDs[i]);
        glBindVertexArray(VAO_IDs[i]);

        //VBO
        glGenBuffers(1, &VBO_xzCoord_IDs[i]);
        glGenBuffers(1, &VBO_yCoord_IDs[i]);
        glGenBuffers(1, &VBO_indices_IDs[i]);
        glGenBuffers(1, &VBO_normals_IDs[i]);
        glGenBuffers(1, &VBO_colors_IDs[i]);

        //xz coords
        glBindBuffer(GL_ARRAY_BUFFER, VBO_xzCoord_IDs[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*xzCoords.size(), &xzCoords[0], GL_STATIC_DRAW);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
        glEnableVertexAttribArray(0);
        //y coords
        glBindBuffer(GL_ARRAY_BUFFER, VBO_yCoord_IDs[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*yCoords[i].size(), &yCoords[i][0], GL_STREAM_DRAW);
        glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, (void*)0);
        glEnableVertexAttribArray(1);
        //normals
        glBindBuffer(GL_ARRAY_BUFFER, VBO_normals_IDs[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VBO_normals_IDs[i].size(), &VBO_normals_IDs[i][0], GL_STREAM_DRAW);
        glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, (void*)0);
        glEnableVertexAttribArray(2);
        //colors
        glBindBuffer(GL_ARRAY_BUFFER, VBO_colors_IDs[i]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VBO_colors_IDs[i].size(), &VBO_colors_IDs[i][0], GL_STREAM_DRAW);
        glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, (void*)0);
        glEnableVertexAttribArray(3);

//indices
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_indices_IDs[i]);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*indices.size(), &indices[0], GL_STATIC_DRAW);
    }

```

Rendering function:

```
for (size_t i = 0; i < 10; i++)
    {
        glBindVertexArray(VAO_IDs[i]);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_indices_IDs[i]);
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void*)0);

    }

```

So as you can see, I create a new xz-coordinates and indices buffer for each VAO. I doubt this is the most effective way to do it. How should I do this?

**Tags:** opengl, rendering, vertex-buffer-object

> **Comments:**
> **username_1**: Step 1: Stop confusing the act of creating a buffer with the act of using that buffer with a VAO.  

---

## 1 answers

### Answer by username_2 on 2017-01-29. Score: 5 | Accepted answer

VAO can share VBO's because they do not store vertex data itself but references to Vertex Buffer Objects.

So you can first generate your buffers and upload your buffer data (vertex data and index data) to currently bound buffers.

```
glGenBuffers(1, &VBO_xzCoord_IDs[i]);
glGenBuffers(1, &VBO_yCoord_IDs[i]);
glGenBuffers(1, &VBO_indices_IDs[i]);
glGenBuffers(1, &VBO_normals_IDs[i]);
glGenBuffers(1, &VBO_colors_IDs[i]);

//xz coords
glBindBuffer(GL_ARRAY_BUFFER, VBO_xzCoord_IDs[i]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*xzCoords.size(), &xzCoords[0], GL_STATIC_DRAW);

...

//indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_indices_IDs[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*indices.size(), &indices[0], GL_STATIC_DRAW);

```

And then generate your VAO's and connect vertex array object data index you provide in `glVertexAttribPointer` call with currently bound `GL_ARRAY_BUFFER`.

The `GL_ELEMENT_ARRAY_BUFFER` can be a little confusing because it doesn't require `glVertexAttribPointer` call. So how it is connected with VAO? It seems that binding the buffer ties it to the currently bound VAO.

```
//VAO
glGenVertexArrays(1, &VAO_IDs[i]);
glBindVertexArray(VAO_IDs[i]);

//xz coords
glBindBuffer(GL_ARRAY_BUFFER, VBO_xzCoord_IDs[i]);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

...

//indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_indices_IDs[i]);

glBindVertexArray(0);

```

And in your rendering call you don't need to bind `GL_ELEMENT_ARRAY_BUFFER` because it was already connected with VAO.

> **Comments:**
> **username_0**: Thank you. I made it so that the "shared VBOs" are only calling glBufferData once, then they are rebounded and set to a vertex attribute for each VAO. So I don't need to call glBufferData for 10 time with the same data:)  

---

