title: Learning to use VBOs properly
body: <p>So I've been trying to teach myself to use VBOs, in order to boost the performance of my OpenGL project and learn more advanced stuff than fixed-function rendering.  But I haven't found much in the way of a decent tutorial; the best ones I've found so far are <a href="http://www.songho.ca/opengl/gl_vbo.html" rel="noreferrer">Songho's tutorials</a> and the stuff at <a href="http://www.opengl.org/wiki/Vertex_Buffer_Object" rel="noreferrer">OpenGL.org</a>, but I seem to be missing some kind of background knowledge to fully understand what's going on, though I can't tell exactly what it is I'm not getting, save the usage of a few parameters.</p>
  
  <p>In any case, I've forged on ahead and come up with some cannibalized code that, at least, doesn't crash, but it leads to bizarre results.  What I want to render is this (rendered using fixed-function; it's supposed to be brown and the background grey, but all my OpenGL screenshots seem to adopt magenta as their favorite color; maybe it's because I use SFML for the window?).</p>
  
  <p><img src="https://i.stack.imgur.com/xwu7c.png" alt="Target image"></p>
  
  <p>What I get, though, is this:</p>
  
  <p><img src="https://i.stack.imgur.com/rrqE1.png" alt="Actual image"></p>
  
  <p>I'm at a loss.  Here's the relevant code I use, first for setting up the buffer objects (I allocate lots of memory as per <a href="http://www.opengl.org/wiki/Vertex_Buffer_Object#Inner_Workings" rel="noreferrer">this guy's</a> recommendation to allocate 4-8MB):</p>
  
  <pre><code>GLuint WorldBuffer;
  GLuint IndexBuffer;
  
  ...
  
  glGenBuffers(1, &amp;WorldBuffer);
  glBindBuffer(GL_ARRAY_BUFFER, WorldBuffer);
  int SizeInBytes = 1024 * 2048;
  glBufferData(GL_ARRAY_BUFFER, SizeInBytes, NULL, GL_STATIC_DRAW);
  
  glGenBuffers(1, &amp;IndexBuffer);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
  SizeInBytes = 1024 * 2048;
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, SizeInBytes, NULL, GL_STATIC_DRAW);
  </code></pre>
  
  <p>Then for uploading the data into the buffer.  Note that CreateVertexArray() fills the vector at the passed location with vertex data, with each vertex contributing 3 floats for position and 3 floats for normal (one of the most confusing things about the various tutorials was what format I should store and transfer my actual vertex data in; this seemed like a decent approximation):</p>
  
  <pre><code>std::vector&lt;float&gt;* VertArray = new std::vector&lt;float&gt;;
  pWorld-&gt;CreateVertexArray(VertArray);
  unsigned short Indice = 0;
  for (int i = 0; i &lt; VertArray-&gt;size(); ++i)
  {
      std::cout &lt;&lt; (*VertArray)[i] &lt;&lt; std::endl;
      glBufferSubData(GL_ARRAY_BUFFER, i * sizeof(float), sizeof(float), &amp;((*VertArray)[i]));
      glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * sizeof(unsigned short), sizeof(unsigned short), &amp;(Indice));
      ++Indice;
  }
  delete VertArray;
  Indice -= 1;
  </code></pre>
  
  <p>After that, in the game loop, I use this code:</p>
  
  <pre><code>    glBindBuffer(GL_ARRAY_BUFFER, WorldBuffer);        
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);    
  
      glEnableClientState(GL_VERTEX_ARRAY);         
      glVertexPointer(3, GL_FLOAT, 0, 0);
      glNormalPointer(GL_FLOAT, 0, 0);
  
      glDrawElements(GL_TRIANGLES, Indice, GL_UNSIGNED_SHORT, 0);
  
      glDisableClientState(GL_VERTEX_ARRAY);
  
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  </code></pre>
  
  <p>I'll be totally honest - I'm not sure I understand what the third parameter of <code>glVertexPointer()</code> and <code>glNormalPointer()</code> ought to be (stride is the offset in bytes, but <a href="http://www.songho.ca/opengl/gl_vertexarray.html" rel="noreferrer">Songho</a> uses an offset of 0 bytes between values - what?), or what the last parameter of either of those is. The initial value is said to be 0; but it's supposed to be a pointer. Passing a null pointer in order to get the first coordinate/normal value of the array seems bizarre. <a href="http://www.opengl.org/wiki/Vertex_Buffer_Object" rel="noreferrer">This guy</a> uses <code>BUFFER_OFFSET(0)</code> and <code>BUFFER_OFFSET(12)</code>, but when I try that, I'm told that BUFFER_OFFSET() is undefined.</p>
  
  <p>Plus, the last parameter of <code>glDrawElements()</code> is supposed to be an address, but again, Songho uses an address of 0.  If I use <code>&amp;IndexBuffer</code> instead of 0, I get a blank screen without anything rendering at all, except the background.</p>
  
  <p>Can someone enlighten me, or at least point me in the direction of something that will help me figure this out? Thanks!</p>