-
Eddie is staring at water damage in his living room ceiling.
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.
- /**
- * Vertex Buffer Objects (herein after referred to as VBOs) demo.
- *
- * Author: Eddie Parker
- * www.kickingdragon.com
- *
- * This demo is a really simple example of how to use VBOs [1].
- *
- * Why would you use VBOs? Because the data is uploaded an manipulated
- * on the graphics card RAM instead of system RAM, therefore it's faster,
- * and doesn't clog up your BUS, and keeps your whites whiter.
- *
- * [1] http://steinsoft.net/index.php?site=Programming/Code%20Snippets/OpenGL/no11
- *
- */
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <SDL/SDL.h>
- #include <SDL/SDL_main.h>
- #include <GL/gl.h>
- #include <GL/glu.h>
- /**
- * glext.h snippet
- *
- * glext.h isn't always found in people's distributions.
- * I've copied the parts we need here -- if you have it available,
- * it would be better to include it directly.
- *
- * Basically, we have a couple of defines that are used later on for
- * glBindBufferARB and glBufferDataARB calls, as well as typedefs
- * that specify the function signatures for the functions we plan on using.
- *
- * Why do we need the typedefs?
- *
- * Quite simply, because the OpenGL Architecture Review Board (ARB) has
- * created these functions as 'extensions' - that is, they're not part
- * of the 'official' library, and therefore might or might not be
- * available. At runtime, it's necessary to crack open the OpenGL
- * DLL and retrieve the function pointers, assign them, and
- * then we're able to use them in our application.
- *
- * For more information, see [1].
- *
- * [1] http://www.opengl.org/resources/faq/technical/extensions.htm
- */
- #define GL_ARRAY_BUFFER_ARB 0x8892
- #define GL_STATIC_DRAW_ARB 0x88E4
- typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
- typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
- typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
- typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
- /**
- *
- * END glext.h snippet
- *
- */
- /**
- * Allocate four function pointers on the data segment so we can assign to them later,
- * if we have them available.
- */
- PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
- PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
- PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
- PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;
- /**
- * Initialization function to set up our requisite libraries.
- */
- int Initialize()
- {
- SDL_Init(SDL_INIT_VIDEO);
- SDL_SetVideoMode(640, 480, 32, 2);
- //! @TODO: I should check for the availability of DrawArrays and
- // check for failure to load these functions.
- glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
- glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
- glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
- }
- int main(int argc, char **argv)
- {
- // Setup our required libraries.
- Initialize();
- // Set up OpenGL
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- // Initialize a perspective.
- gluPerspective(45.f, 640.f / 480.f, 1.f, 512.f);
- // Set our clear colour to black
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- // Set up a purdy triangle as our vertex data.
- GLfloat vertexData[] = { 0.f, 1.f, 0.f
- , -1.f, -1.f, 0.f
- , 1.f, -1.f, 0.f
- };
- // Set a lovely teal with some Gouraud shading for
- // our triangle.
- GLfloat colourData[] = { 0.f, 0.f, 1.f
- , 0.f, 1.f, 1.f
- , 1.f, 1.f, 1.f
- };
- // Create some 'ids' for the buffers.
- GLuint vertexBuffer = 0;
- GLuint colourBuffer = 0;
- // 1.- Generated a buffer name for our vertex buffer,
- glGenBuffersARB(1, &vertexBuffer);
- // 2.- Set our current 'in-use' buffer to our vertex buffer.
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexBuffer);
- // 3.- Fill out the data buffer using our initialized values.
- glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertexData), vertexData, GL_STATIC_DRAW_ARB);
- // Same as steps 1, 2 and 3 above, but using colour data.
- glGenBuffersARB(1, &colourBuffer);
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, colourBuffer);
- glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(colourData), colourData, GL_STATIC_DRAW_ARB);
- // Initialize the ability to use vertex arrays and colour arrays.
- // I should really be making sure I have this capability and use
- // glIsEnabled first.
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
- bool bRunning = true;
- SDL_Event event;
- while (bRunning)
- {
- if(SDL_PollEvent(&event))
- {
- if(event.key.keysym.sym == SDLK_ESCAPE)
- {
- bRunning = false;
- continue;
- }
- }
- // Clear our depth buffer and color bit
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // Reset our view
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- // Move back a bit to see our triangle in it's glory.
- glTranslatef(0, 0, -5);
- // --- VBO's in action.
- // Set the vertexBuffer as the current buffer.
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexBuffer);
- // Specify that it's data is vertex data.
- glVertexPointer(3, GL_FLOAT, 0, 0);
- // Set the colourBuffer as the current buffer.
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, colourBuffer);
- // Specify that it's data is colour data.
- glColorPointer (3, GL_FLOAT, 0, 0);
- // Tell OpenGL to draw what it sees. ;)
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
- // --- End VBO's in action.
- // Swap buffers!
- SDL_GL_SwapBuffers();
- }
- // Disable the client states.
- glDisableClientState( GL_VERTEX_ARRAY );
- glDisableClientState( GL_COLOR_ARRAY );
- //!TODO: Free the buffers created in glBufferDataARB
- return 0;
- }
Popularity: 71% [?]
6 Comments »
RSS feed for comments on this post. TrackBack URI
Leave a comment


Pingback by codepixel - Vertex Buffer Objects — January 14, 2008 #
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 #
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 #
Pingback by OpenGL vertex buffer objects tutorial (://URLFAN) — June 24, 2008 #
doesn’t fucking work
Comment by dipshit — August 10, 2008 #
Feel free to tell me what your error is, previous poster, and I’ll see if I can help you.
Granted, feel free to omit the swearing.
Comment by eddie — August 11, 2008 #