OpenGL vertex buffer objects tutorial
lairotut stcejbo reffub xetrev LGnepO
rss

I’ve been dabbling in graphics programming a bit, mostly OpenGL glBegin/glEnd schtuff lately. A friend pointed me to vertex buffer objects (VBO’s) as a better alternative, so I decided to learn a bit about them. That said, I couldn’t find a tutorial that suited my needs, so I thought I’d offer one here.

First off, there are tutorials out there, just not what I need/want. Let me list them.

  • NeHe, purveyor of all things graphical has a great tutorial (#45), that I even used as a reference for mine.

The problem for me was that it came with way more than what I wanted to learn at this point (heightmaps and the like), and I just wanted a focused example on VBO’s without having to worry about setting everything up “just right”.

  • DevMaster, my surrogate home, had a decent tutorial that was brief (here), but had various errors and didn’t compile out of the box. It also didn’t work, at least not for me!

So here I decided to cobble together a working demo (once I figured out how), and post it up for all the world to see.

Now keep in mind a few things about this:

1.- I might have my terminology messed up. I keep hearing people refer to this as DrawArrays, Vertex Buffer Objects, Vertex Array something-or-other, etc. If someone can clear this up for me, I’d be happy to hear from you.

2.- I don’t do a lot of error checking in this demo. It’s definitely bad practice, but I wanted to keep things brief. There’s a couple of comments in there noting where I should be, and there might be a few places that I should mention these things.

Anyhow, without further ado, here’s the demo. I hope it helps someone.

  1. /**
  2.   * Vertex Buffer Objects (herein after referred to as VBOs) demo.
  3.   *
  4.   * Author: Eddie Parker
  5.   * www.kickingdragon.com
  6.   *
  7.   * This demo is a really simple example of how to use VBOs [1].
  8.   *
  9.   * Why would you use VBOs? Because the data is uploaded an manipulated
  10.   * on the graphics card RAM instead of system RAM, therefore it's faster,
  11.   * and doesn't clog up your BUS, and keeps your whites whiter.
  12.   *
  13.   * [1] http://steinsoft.net/index.php?site=Programming/Code%20Snippets/OpenGL/no11
  14.   *
  15.   */
  16.  
  17. #define WIN32_LEAN_AND_MEAN
  18. #include <windows.h>
  19.  
  20. #include <SDL/SDL.h>
  21. #include <SDL/SDL_main.h>
  22. #include <GL/gl.h>
  23. #include <GL/glu.h>
  24.  
  25. /**
  26.   * glext.h snippet
  27.   *
  28.   * glext.h isn't always found in people's distributions.
  29.   * I've copied the parts we need here -- if you have it available,
  30.   * it would be better to include it directly.
  31.   *
  32.   * Basically, we have a couple of defines that are used later on for
  33.   * glBindBufferARB and glBufferDataARB calls, as well as typedefs
  34.   * that specify the function signatures for the functions we plan on using.
  35.   *
  36.   * Why do we need the typedefs?
  37.   *
  38.   * Quite simply, because the OpenGL Architecture Review Board (ARB) has
  39.   * created these functions as 'extensions' - that is, they're not part
  40.   * of the 'official' library, and therefore might or might not be
  41.   * available. At runtime, it's necessary to crack open the OpenGL
  42.   * DLL and retrieve the function pointers, assign them, and
  43.   * then we're able to use them in our application.
  44.   *
  45.   * For more information, see [1].
  46.   *
  47.   * [1] http://www.opengl.org/resources/faq/technical/extensions.htm
  48.   */
  49. #define GL_ARRAY_BUFFER_ARB 0x8892
  50. #define GL_STATIC_DRAW_ARB 0x88E4
  51. typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
  52. typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
  53. typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
  54. typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
  55. /**
  56.   *
  57.   * END glext.h snippet
  58.   *
  59.   */
  60.  
  61. /**
  62.   * Allocate four function pointers on the data segment so we can assign to them later,
  63.   * if we have them available.
  64.   */
  65. PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
  66. PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
  67. PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
  68. PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;
  69.  
  70. /**
  71.   * Initialization function to set up our requisite libraries.
  72.   */
  73. int Initialize()
  74. {
  75.     SDL_Init(SDL_INIT_VIDEO);
  76.     SDL_SetVideoMode(640, 480, 32, 2);
  77.    
  78.     //! @TODO: I should check for the availability of DrawArrays and
  79.     // check for failure to load these functions.
  80.     glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
  81.     glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
  82.     glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
  83. }
  84.  
  85. int main(int argc, char **argv)
  86. {
  87.     // Setup our required libraries.
  88.     Initialize();
  89.    
  90.     // Set up OpenGL
  91.     glMatrixMode(GL_PROJECTION);
  92.     glLoadIdentity();
  93.    
  94.     // Initialize a perspective.
  95.     gluPerspective(45.f, 640.f / 480.f, 1.f, 512.f);
  96.    
  97.     // Set our clear colour to black
  98.     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  99.    
  100.     // Set up a purdy triangle as our vertex data.
  101.     GLfloat vertexData[] =    { 0.f, 1.f, 0.f
  102.                             , -1.f, -1.f, 0.f
  103.                             , 1.f, -1.f, 0.f
  104.                             };
  105.    
  106.     // Set a lovely teal with some Gouraud shading for
  107.     // our triangle.
  108.     GLfloat colourData[] =    { 0.f, 0.f, 1.f
  109.                             , 0.f, 1.f, 1.f
  110.                             , 1.f, 1.f, 1.f
  111.                             };
  112.    
  113.     // Create some 'ids' for the buffers.
  114.     GLuint vertexBuffer = 0;
  115.     GLuint colourBuffer = 0;
  116.    
  117.     // 1.- Generated a buffer name for our vertex buffer,
  118.     glGenBuffersARB(1, &vertexBuffer);
  119.    
  120.     // 2.- Set our current 'in-use' buffer to our vertex buffer.
  121.     glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexBuffer);
  122.    
  123.     // 3.- Fill out the data buffer using our initialized values.
  124.     glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertexData), vertexData, GL_STATIC_DRAW_ARB);
  125.    
  126.     // Same as steps 1, 2 and 3 above, but using colour data.
  127.     glGenBuffersARB(1, &colourBuffer);
  128.     glBindBufferARB(GL_ARRAY_BUFFER_ARB, colourBuffer);
  129.     glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(colourData), colourData, GL_STATIC_DRAW_ARB);
  130.    
  131.     // Initialize the ability to use vertex arrays and colour arrays.
  132.     // I should really be making sure I have this capability and use
  133.     // glIsEnabled first.
  134.     glEnableClientState(GL_VERTEX_ARRAY);
  135.     glEnableClientState(GL_COLOR_ARRAY);
  136.    
  137.     bool bRunning = true;
  138.     SDL_Event event;
  139.    
  140.     while (bRunning)
  141.     {
  142.         if(SDL_PollEvent(&event))
  143.         {
  144.             if(event.key.keysym.sym == SDLK_ESCAPE)
  145.             {
  146.                 bRunning = false;
  147.                 continue;
  148.             }
  149.         }
  150.        
  151.         // Clear our depth buffer and color bit
  152.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  153.        
  154.         // Reset our view
  155.         glMatrixMode(GL_MODELVIEW);
  156.         glLoadIdentity();
  157.        
  158.         // Move back a bit to see our triangle in it's glory.
  159.         glTranslatef(0, 0, -5);
  160.        
  161.         // --- VBO's in action.
  162.         // Set the vertexBuffer as the current buffer.
  163.         glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexBuffer);
  164.        
  165.         // Specify that it's data is vertex data.
  166.         glVertexPointer(3, GL_FLOAT, 0, 0);
  167.        
  168.         // Set the colourBuffer as the current buffer.
  169.         glBindBufferARB(GL_ARRAY_BUFFER_ARB, colourBuffer);
  170.        
  171.         // Specify that it's data is colour data.
  172.         glColorPointer (3, GL_FLOAT, 0, 0);
  173.        
  174.         // Tell OpenGL to draw what it sees. ;)
  175.         glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  176.         // --- End VBO's in action.
  177.        
  178.         // Swap buffers!
  179.         SDL_GL_SwapBuffers();
  180.     }
  181.    
  182.     // Disable the client states.
  183.     glDisableClientState( GL_VERTEX_ARRAY );
  184.     glDisableClientState( GL_COLOR_ARRAY );
  185.    
  186.     //!TODO: Free the buffers created in glBufferDataARB
  187.    
  188.     return 0;
  189. }

Popularity: 65% [?]

Share or Store: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us

4 Comments »

RSS feed for comments on this post. TrackBack URI

  1. Kramer auto Pingback[…] probado los vertex buffer objects, y este articulo os dara un poco igual. Para el resto, aqui podeis leer una descripcion sencilla de como conseguir un uso mas optimizado a la memoria de la […]

    Pingback by codepixel - Vertex Buffer Objects — January 14, 2008 #

  2. I’ve been struggling for ages trying to get VBO’s working. All I needed was a simple demo that works to show me exactly how its done without all the extra bits often seen in other demos.
    I now have a working program that I can make modifications to so thanks very much for a useful resource.

    Comment by Lynton — January 22, 2008 #

  3. I know what you mean, Lynton. I find I need to grasp a concept in small terms so I can put it to good use in a much larger project.

    Glad my little code snippet could help!

    Comment by eddie — January 22, 2008 #

  4. Kramer auto Pingback[…] vertex buffer objects tutorialSource: http://www.kickingdragon.com/2006/07/25/opengl-ver…Displaying mentions in this article, for full text please visit source.I’ve been dabbling in […]

    Pingback by OpenGL vertex buffer objects tutorial (://URLFAN) — June 24, 2008 #

Leave a comment