title: Render a scene with a unique VAO/VBO/IBO using OpenGL
body: <p>I have written an OpenGL application which works fine and I just want to increase its performance. Of course a good way to do this is to package several meshes in a unique VBO (being carefull to the number of vertices, of course). So I'm not talking about huge scene but in my case a simple scene with only 2 meshes (a plane and a cube). Here's a quick overview of my scene :</p>
  
  <p><img src="https://i.stack.imgur.com/MZBvN.png" alt="enter image description here"></p>
  
  <p>Now here's some statistics (in bytes) for these 2 separate meshes:</p>
  
  <pre><code>Plane mesh :
   - Vertex buffer :
     - position(size=48)
     - texture(size=32)
     - normal(size=48)
       -&gt; Total = 128 bytes
  
  Box mesh :
   - Vertex buffer :
     - position(size=312)
     - texture(size=208)
     - normal(size=312)
       -&gt; Total = 832 bytes
  </code></pre>
  
  <p>Currently, my 2 meshes are contained in a unique VBO (of course I have a unique IBO that contains the indices for the two meshes). Here's the pattern I've adopted to store all the data in a single array :</p>
  
  <pre><code>[P(plane)][T(plane)][N(plane)]|[P(cube)][T(cube)][N(cube)]
  |0        |48       |80       |128      |440     |648
  
  Caption : P (all position vertices), T (all texture vertices) and N (all normal vertices)
  </code></pre>
  
  <p>It's quite a good approach but it force the programmer (belongs to me of course :) maybe it's wrong) to declare a specific VAO for each mesh because to render the geometry of my 2 meshes I have to change the buffer offset to send the data to the shader program.</p>
  
  <p>Sending of the data for the plane mesh :</p>
  
  <pre><code>glEnableVertexAttribArray(scene::VERTEX_POSITION);
  glVertexAttribPointer(scene::VERTEX_POSITION, 3,
      GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(0));
  
  glEnableVertexAttribArray(scene::VERTEX_TEXTURE);
  glVertexAttribPointer(scene::VERTEX_TEXTURE, 2,
      GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(48));
  
  glEnableVertexAttribArray(scene::VERTEX_NORMAL);
  glVertexAttribPointer(scene::VERTEX_NORMAL, 3,
      GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(80));
  
  Remark : Here, the offsets are 0, 48 and 80
  </code></pre>
  
  <p>Sending of the data for the cube mesh :</p>
  
  <pre><code>glEnableVertexAttribArray(scene::VERTEX_POSITION);
  glVertexAttribPointer(scene::VERTEX_POSITION, 3,
      GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(128));
  
  glEnableVertexAttribArray(scene::VERTEX_TEXTURE);
  glVertexAttribPointer(scene::VERTEX_TEXTURE, 2,
      GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(440));
  
  glEnableVertexAttribArray(scene::VERTEX_NORMAL);
  glVertexAttribPointer(scene::VERTEX_NORMAL, 3,
      GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(648));
  
  Remark : Here, the offsets are 128, 440 and 648
  </code></pre>
  
  <p>As you can see with this approach I need to know for each mesh the 3 offsets. So it implies 2 VAOs (one for each mesh). Is it true ? (I want to be sure it impossible to draw these two meshes with a unique VAO with this approach - Thanks in advance for this point).</p>
  
  <p>PS : To render the geometry I use the function glDrawRangeElements. So in this example, the function is called 2 times in a loop with of course a different range of elements :</p>
  
  <pre><code>for the plane mesh :
  
  glDrawRangeElements(GL_TRIANGLES, 0, 0, 6, GL_UNSIGNED_INT, OFFSET_BUFFER(0));
  
  And for the cube mesh :
  
  glDrawRangeElements(GL_TRIANGLES, 0, 6, 36, GL_UNSIGNED_INT, OFFSET_BUFFER(0));
  </code></pre>
  
  <p>Now I propose another approach, this time using a unique VAO to render all the geometry. Here's the new pattern :</p>
  
  <pre><code>[P(plane)][P(cube)]|[T(plane)][T(cube)]|[N(plane)][N(cube)]
  |0        |48      |360      |392      |600      |648
  </code></pre>
  
  <p>As you can see with this kind of solution I will need JUST 3 OFFSETS (0, 360 and 600) to render all the geometry (of course the IBO will be different than the one for the previous approach and will be built accordingly). So here I will need a unique VAO ! But this time I will need to have the knowledge of all my scene (all the vertices) before to build my VBO (filling it once) unlike the previous case where I could fill my VBO mesh by mesh in several times. Are you agree with me ?</p>
  
  <p>An other question : if I want to remove for example the cube I cannot remove the VBO. So what the method here ? Do I need to just turn the boolean value 'm_IsVisible' of my 'Mesh' class to false? (my mesh will be no longer visible but the vertices will not be free!) Or do I need to free the vertices ? How can I do this ?</p>
  
  <p>What do you think about my propositions ? Which one is the best ?</p>
  
  <p>Is a unique VAO is possible in my example ?</p>