Difference between revisions of "VBO - just examples"

From OpenGL Wiki
Jump to: navigation, search
m (categorizing)
Line 1: Line 1:
 
== Render A Triangle ==
 
== Render A Triangle ==
 
This example assumes C++ or a similar language.
 
This example assumes C++ or a similar language.
 +
 +
Warning : this is not a "tutorial" page. There isn't much code commenting or explanation of the functions. This page is referenced by other pages on this Wiki. We are using VBOs and glVertexPointer, glNormalPointer, glTexCoordPointer and glEnableClientState in the code below. The vertex format is VNT which means vertex and normals and texcoords. Since glVertexPointer and those other functions are deprecated in GL 3.0 and above forward compatible context, you should in fact use glVertexAttribPointer in modern code. Look further down for the example with glVertexAttribPointer.
  
 
   struct MyVertex
 
   struct MyVertex
Line 58: Line 60:
 
   glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(0));  //The starting point of the VBO, for the vertices
 
   glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(0));  //The starting point of the VBO, for the vertices
 
   glEnableClientState(GL_NORMAL_ARRAY);
 
   glEnableClientState(GL_NORMAL_ARRAY);
   glNormalPointer(GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(12));
+
   glNormalPointer(GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(12));   //The starting point of normals, 12 bytes away
 
   glClientActiveTexture(GL_TEXTURE0);
 
   glClientActiveTexture(GL_TEXTURE0);
 
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   glTexCoordPointer(2, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(24));
+
   glTexCoordPointer(2, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(24));   //The starting point of texcoords, 24 bytes away
  
 
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
 
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
Line 79: Line 81:
 
   glDeleteBuffers(1, &VertexVBOID);
 
   glDeleteBuffers(1, &VertexVBOID);
 
   glDeleteBuffers(1, &IndexVBOID);
 
   glDeleteBuffers(1, &IndexVBOID);
 +
 +
== Render A Triangle #2 ==
 +
This example assumes C++ or a similar language.
 +
 +
Warning : this is not a "tutorial" page. There isn't much code commenting or explanation of the functions. This page is referenced by other pages on this Wiki. We are using VBOs and glVertexAttribPointer and glEnableVertexAttribArray in the code below. The vertex format is VNT which means vertex and normals and texcoords. The example below doesn't use VAO for the sake of simplicity. Please search this Wiki for pages that explain the concept of VAO.
 +
 +
  struct MyVertex
 +
  {
 +
    float x, y, z;        //Vertex
 +
    float nx, ny, nz;    //Normal
 +
    float s0, t0;        //Texcoord0
 +
  };
 +
 +
  MyVertex pvertex[3];
 +
  //VERTEX 0
 +
  pvertex[0].x = 0.0;
 +
  pvertex[0].y = 0.0;
 +
  pvertex[0].z = 0.0;
 +
  pvertex[0].nx = 0.0;
 +
  pvertex[0].ny = 0.0;
 +
  pvertex[0].nz = 1.0;
 +
  pvertex[0].s0 = 0.0;
 +
  pvertex[0].t0 = 0.0;
 +
  //VERTEX 1
 +
  pvertex[1].x = 1.0;
 +
  pvertex[1].y = 0.0;
 +
  pvertex[1].z = 0.0;
 +
  pvertex[1].nx = 0.0;
 +
  pvertex[1].ny = 0.0;
 +
  pvertex[1].nz = 1.0;
 +
  pvertex[1].s0 = 1.0;
 +
  pvertex[1].t0 = 0.0;
 +
  //VERTEX 2
 +
  pvertex[2].x = 0.0;
 +
  pvertex[2].y = 1.0;
 +
  pvertex[2].z = 0.0;
 +
  pvertex[2].nx = 0.0;
 +
  pvertex[2].ny = 0.0;
 +
  pvertex[2].nz = 1.0;
 +
  pvertex[2].s0 = 0.0;
 +
  pvertex[2].t0 = 1.0;
 +
 +
  glGenBuffers(1, VertexVBOID);
 +
  glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
 +
  glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*3, &pvertex[0].x, GL_STATIC_DRAW);
 +
 +
  ushort pindices[3];
 +
  pindices[0] = 0;
 +
  pindices[1] = 1;
 +
  pindices[2] = 2;
 +
 +
  glGenBuffers(1, &IndexVBOID);
 +
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
 +
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ushort)*3, pindices, GL_STATIC_DRAW);
 +
 +
  //Define this somewhere in your header file
 +
  define BUFFER_OFFSET(i) ((char *)NULL + (i))
 +
 +
  glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
 +
  glEnableVertexAttribArray(0);    //We like submitting vertices on stream 0 for no special reason
 +
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));  //The starting point of the VBO, for the vertices
 +
  glEnableVertexAttribArray(1);    //We like submitting normals on stream 1 for no special reason
 +
  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));    //The starting point of normals, 12 bytes away
 +
  glEnableVertexAttribArray(2);    //We like submitting texcoords on stream 2 for no special reason
 +
  glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(24));  //The starting point of texcoords, 24 bytes away
 +
 +
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
 +
  //To render, we can either use glDrawElements or glDrawRangeElements
 +
  //The is the number of indices. 3 indices needed to make a single triangle
 +
  glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));  //The starting point of the IBO
 +
  //0 and 3 are the first and last vertices
 +
  //glDrawRangeElements(GL_TRIANGLES, 0, 3, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));  //The starting point of the IBO
 +
  //glDrawRangeElements may or may not give a performance advantage over glDrawElements
 +
 +
1. Don't forget to glDisableClientState.<br>
 +
2. Remember that as long as a VBO and IBO are bound, functions like glVertexPointer refer to the start address of a VBO<br>
 +
You must bind glBindBuffer(GL_ARRAY_BUFFER, 0); and glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if you want to source a standard memory
 +
location (RAM)<br>
 +
Don't forget to deallocate when your program will shut down.<br>
 +
 +
  glDeleteBuffers(1, &VertexVBOID);
 +
  glDeleteBuffers(1, &IndexVBOID);
 +
  
 
[[Category:Examples]]
 
[[Category:Examples]]

Revision as of 17:01, 13 December 2009

Render A Triangle

This example assumes C++ or a similar language.

Warning : this is not a "tutorial" page. There isn't much code commenting or explanation of the functions. This page is referenced by other pages on this Wiki. We are using VBOs and glVertexPointer, glNormalPointer, glTexCoordPointer and glEnableClientState in the code below. The vertex format is VNT which means vertex and normals and texcoords. Since glVertexPointer and those other functions are deprecated in GL 3.0 and above forward compatible context, you should in fact use glVertexAttribPointer in modern code. Look further down for the example with glVertexAttribPointer.

 struct MyVertex
 {
   float x, y, z;        //Vertex
   float nx, ny, nz;     //Normal
   float s0, t0;         //Texcoord0
 };
 MyVertex pvertex[3];
 //VERTEX 0
 pvertex[0].x = 0.0;
 pvertex[0].y = 0.0;
 pvertex[0].z = 0.0;
 pvertex[0].nx = 0.0;
 pvertex[0].ny = 0.0;
 pvertex[0].nz = 1.0;
 pvertex[0].s0 = 0.0;
 pvertex[0].t0 = 0.0;
 //VERTEX 1
 pvertex[1].x = 1.0;
 pvertex[1].y = 0.0;
 pvertex[1].z = 0.0;
 pvertex[1].nx = 0.0;
 pvertex[1].ny = 0.0;
 pvertex[1].nz = 1.0;
 pvertex[1].s0 = 1.0;
 pvertex[1].t0 = 0.0;
 //VERTEX 2
 pvertex[2].x = 0.0;
 pvertex[2].y = 1.0;
 pvertex[2].z = 0.0;
 pvertex[2].nx = 0.0;
 pvertex[2].ny = 0.0;
 pvertex[2].nz = 1.0;
 pvertex[2].s0 = 0.0;
 pvertex[2].t0 = 1.0;
 glGenBuffers(1, VertexVBOID);
 glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
 glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*3, &pvertex[0].x, GL_STATIC_DRAW);
 ushort pindices[3];
 pindices[0] = 0;
 pindices[1] = 1;
 pindices[2] = 2;
 glGenBuffers(1, &IndexVBOID);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ushort)*3, pindices, GL_STATIC_DRAW);
 //Define this somewhere in your header file
 define BUFFER_OFFSET(i) ((char *)NULL + (i))
 glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
 glEnableClientState(GL_VERTEX_ARRAY);
 glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(0));   //The starting point of the VBO, for the vertices
 glEnableClientState(GL_NORMAL_ARRAY);
 glNormalPointer(GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(12));   //The starting point of normals, 12 bytes away
 glClientActiveTexture(GL_TEXTURE0);
 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 glTexCoordPointer(2, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(24));   //The starting point of texcoords, 24 bytes away
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
 //To render, we can either use glDrawElements or glDrawRangeElements
 //The is the number of indices. 3 indices needed to make a single triangle
 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
 //0 and 3 are the first and last vertices
 //glDrawRangeElements(GL_TRIANGLES, 0, 3, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
 //glDrawRangeElements may or may not give a performance advantage over glDrawElements

1. Don't forget to glDisableClientState.
2. Remember that as long as a VBO and IBO are bound, functions like glVertexPointer refer to the start address of a VBO
You must bind glBindBuffer(GL_ARRAY_BUFFER, 0); and glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if you want to source a standard memory location (RAM)
Don't forget to deallocate when your program will shut down.

 glDeleteBuffers(1, &VertexVBOID);
 glDeleteBuffers(1, &IndexVBOID);

Render A Triangle #2

This example assumes C++ or a similar language.

Warning : this is not a "tutorial" page. There isn't much code commenting or explanation of the functions. This page is referenced by other pages on this Wiki. We are using VBOs and glVertexAttribPointer and glEnableVertexAttribArray in the code below. The vertex format is VNT which means vertex and normals and texcoords. The example below doesn't use VAO for the sake of simplicity. Please search this Wiki for pages that explain the concept of VAO.

 struct MyVertex
 {
   float x, y, z;        //Vertex
   float nx, ny, nz;     //Normal
   float s0, t0;         //Texcoord0
 };
 MyVertex pvertex[3];
 //VERTEX 0
 pvertex[0].x = 0.0;
 pvertex[0].y = 0.0;
 pvertex[0].z = 0.0;
 pvertex[0].nx = 0.0;
 pvertex[0].ny = 0.0;
 pvertex[0].nz = 1.0;
 pvertex[0].s0 = 0.0;
 pvertex[0].t0 = 0.0;
 //VERTEX 1
 pvertex[1].x = 1.0;
 pvertex[1].y = 0.0;
 pvertex[1].z = 0.0;
 pvertex[1].nx = 0.0;
 pvertex[1].ny = 0.0;
 pvertex[1].nz = 1.0;
 pvertex[1].s0 = 1.0;
 pvertex[1].t0 = 0.0;
 //VERTEX 2
 pvertex[2].x = 0.0;
 pvertex[2].y = 1.0;
 pvertex[2].z = 0.0;
 pvertex[2].nx = 0.0;
 pvertex[2].ny = 0.0;
 pvertex[2].nz = 1.0;
 pvertex[2].s0 = 0.0;
 pvertex[2].t0 = 1.0;
 glGenBuffers(1, VertexVBOID);
 glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
 glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*3, &pvertex[0].x, GL_STATIC_DRAW);
 ushort pindices[3];
 pindices[0] = 0;
 pindices[1] = 1;
 pindices[2] = 2;
 glGenBuffers(1, &IndexVBOID);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ushort)*3, pindices, GL_STATIC_DRAW);
 //Define this somewhere in your header file
 define BUFFER_OFFSET(i) ((char *)NULL + (i))
 glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
 glEnableVertexAttribArray(0);    //We like submitting vertices on stream 0 for no special reason
 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));   //The starting point of the VBO, for the vertices
 glEnableVertexAttribArray(1);    //We like submitting normals on stream 1 for no special reason
 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));     //The starting point of normals, 12 bytes away
 glEnableVertexAttribArray(2);    //We like submitting texcoords on stream 2 for no special reason
 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(24));   //The starting point of texcoords, 24 bytes away
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
 //To render, we can either use glDrawElements or glDrawRangeElements
 //The is the number of indices. 3 indices needed to make a single triangle
 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
 //0 and 3 are the first and last vertices
 //glDrawRangeElements(GL_TRIANGLES, 0, 3, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
 //glDrawRangeElements may or may not give a performance advantage over glDrawElements

1. Don't forget to glDisableClientState.
2. Remember that as long as a VBO and IBO are bound, functions like glVertexPointer refer to the start address of a VBO
You must bind glBindBuffer(GL_ARRAY_BUFFER, 0); and glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if you want to source a standard memory location (RAM)
Don't forget to deallocate when your program will shut down.

 glDeleteBuffers(1, &VertexVBOID);
 glDeleteBuffers(1, &IndexVBOID);