I'd like to use Vertex Buffer Objects (VBOs) to improved my rendering of somewhat complicated models in my Open GL ES 1.1 game for iPhone. After reading several posts on SO and this (http://playcontrol.net/ewing/jibberjabber/opengl_vertex_buffer_object.html) tutorial, I'm still having trouble understanding VBOs and how to implement them given my Cheetah 3D export model format. Could someone please give me an example of implementing a VBO and using it to draw my vertices with the given data structure and explain the syntax? I greatly appreciate any help!
#define body_vertexcount 434
#define body_polygoncount 780
// The vertex data is saved in the following format:
// u0,v0,normalx0,normaly0,normalz0,x0,y0,z0
float body_vertex[body_vertexcount][8]={
{0.03333, 0.00000, -0.68652, -0.51763, 0.51063, 0.40972, -0.25028, -1.31418},
{...},
{...}
}
GLushort body_index[body_polygoncount][3]={
{0, 1, 2},
{2, 3, 0}
}
I've written the following code with the help of Chapter 9 from Pro OpenGL ES (Appress). I'm getting EXC_BAD_ACCESS with the DrawElements command and I'm not sure why. Could someone please shed some light? Thanks -
// First thing we do is create / setup the index buffer
glGenBuffers(1, &bodyIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO);
// For constrast, instead of glBufferSubData and glMapBuffer,
// we can directly supply the data in one-shot
glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*sizeof(GLubyte), body_index, GL_STATIC_DRAW);
// Define our data structure
int numXYZElements = 3;
int numNormalElements = 3;
int numTextureCoordElements = 2;
long totalXYZBytes;
long totalNormalBytes;
long totalTexCoordinateBytes;
int numBytesPerVertex;
// Allocate a new buffer
glGenBuffers(1, &bodyVBO);
// Bind the buffer object to use
glBindBuffer(GL_ARRAY_BUFFER, bodyVBO);
// Tally up the size of the data components
numBytesPerVertex = numXYZElements;
numBytesPerVertex += numNormalElements;
numBytesPerVertex += numTextureCoordElements;
numBytesPerVertex *= sizeof(GLfloat);
// Actually allocate memory on the GPU ( Data is static here )
glBufferData(GL_ARRAY_BUFFER, numBytesPerVertex * body_vertexcount, 0, GL_STATIC_DRAW);
// Upload data to the cache ( memory mapping )
GLubyte *vboBuffer = (GLubyte *)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
// Caclulate the total number of bytes for each data type
totalXYZBytes = numXYZElements * body_vertexcount * sizeof(GLfloat);
totalNormalBytes = numNormalElements * body_vertexcount * sizeof(GLfloat);
totalTexCoordinateBytes = numTextureCoordElements * body_vertexcount * sizeof(GLfloat);
// Set the total bytes property for the body
self.bodyTotalBytes = totalXYZBytes + totalNormalBytes + totalTexCoordinateBytes;
// Setup the copy of the buffer(s) using memcpy()
memcpy(vboBuffer, body_vertex, self.bodyTotalBytes);
// Perform the actual copy
glUnmapBufferOES(GL_ARRAY_BUFFER);
Here are the drawing commands where I'm getting the exception:
// Activate the VBOs to draw
glBindBuffer(GL_ARRAY_BUFFER, bodyVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO);
// Setup drawing
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glClientActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,lightGreyInt);
// Setup pointers
glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0 );
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 12 );
glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 24 );
// Now draw the body
glDrawElements(GL_TRIANGLES, body_polygoncount,GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL));
//glDrawElements(GL_TRIANGLES, body_polygoncount, GL_UNSIGNED_SHORT, nil);
//glDrawElements(GL_TRIANGLES,body_polygoncount*3,GL_UNSIGNED_SHORT,body_index);