VBO best practises in openGL ES 1.3

Hi,

Happy new year to all!

I’ve been studying VBO’s and the example I’ve sourced from playcontrol.net only displays a single Cube or object. I should mention that I’m targeting iOS (no quads, only triangles) using openGL 1.3 (equivalent to openGL 1.5 desktop) as I’m not ready to take the plunge into shaders until I’ve completed my first game.

I’m wondering how to apply the following to multiple objects. This approach utilises drawElements and the cubeVBO is drawn in a single call. Can anyone direct me to an example of drawing arrays using VBO’s, or comment on this code - the only reference I currently have. I’m struggling to find source material for VBO’s drawing multiple objects, and as such confused as to whether it is even possible to draw more than one array at a time. Is is actually only possible to draw one group of triangles at a time? And can you not concatenate arrays together then draw the entire scenes geometry in a single call to drawElements using one super sized array?

Here’s hoping somebody more advanced can help!!

Referencing the tutorial http://playcontrol.net/ ewing/jibberjabber/
opengl_vertex_buffer_object.html.

I’m setting up my arrays as follows:


GLuint cubeVBO;
GLuint cubeIBO;

static GLfloat s_cubeVertices[] =
{
	-1.0, +1.0, +1.0,  -1.0, -1.0, +1.0,  +1.0, +1.0, +1.0,  +1.0, -1.0, +1.0,        
       // v0-v1-v2-v3
	+1.0, +1.0, +1.0,  +1.0, -1.0, +1.0,  +1.0, +1.0, -1.0,  +1.0, -1.0, -1.0,          
        // v2-v3-v4-v5
	+1.0, +1.0, -1.0,  +1.0, -1.0, -1.0,  -1.0, +1.0, -1.0,  -1.0, -1.0, -1.0,    
        // v4-v5-v6-v7
	-1.0, +1.0, -1.0,  -1.0, -1.0, -1.0,  -1.0, +1.0, +1.0,  -1.0, -1.0, +1.0     
        // v6-v7-v0-v1
};
#define NUMBER_OF_CUBE_VERTICES 16
#define NUMBER_OF_CUBE_COMPONENTS_PER_VERTEX 3

// color array
GLubyte s_cubeColors[] = 
{
	255,0,0,255, 255,0,0,255, 255,0,0,255, 255,0,0,255,
	0,255,0,255, 0,255,0,255, 0,255,0,255, 0,255,0,255, 
	0,0,255,255, 0,0,255,255, 0,0,255,255, 0,0,255,255,
	0,255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255,  

};
#define NUMBER_OF_CUBE_COLORS 16
#define NUMBER_OF_CUBE_COMPONENTS_PER_COLOR 4

// Describes a box, but without a top and bottom
GLubyte s_cubeIndices[] = 
{
	0,1,2,3,
	4,5,6,7,
	8,9,10,11,
	12,13,14,15
};
#define NUMBER_OF_CUBE_INDICES 16

The VBO is setup this way:


	glGenBuffers(1, &cubeVBO);
	glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
	const GLsizeiptr vertex_size = NUMBER_OF_CUBE_VERTICES*NUMBER_OF_CUBE_COMPONENTS_PER_VERTEX*sizeof(GLfloat);
	const GLsizeiptr color_size = NUMBER_OF_CUBE_COLORS*NUMBER_OF_CUBE_COMPONENTS_PER_COLOR*sizeof(GLubyte);
	glBufferData(GL_ARRAY_BUFFER, vertex_size+color_size, 0, GL_STATIC_DRAW);
#if 0
	glBufferSubData(GL_ARRAY_BUFFER, 0, vertex_size, s_cubeVertices); 
        // start at index 0, to length of vertex_size
	glBufferSubData(GL_ARRAY_BUFFER, vertex_size, color_size, s_cubeColors); 
        // append color data to vertex data. 
        // To be optimal, data should probably be interleaved and not appended
#else
	GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); 
	// transfer the vertex data to the VBO
	memcpy(vbo_buffer, s_cubeVertices, vertex_size);
	// append color data to vertex data. 
        // To be optimal, data should probably be interleaved and not appended
	vbo_buffer += vertex_size;
	memcpy(vbo_buffer, s_cubeColors, color_size);	
	glUnmapBufferOES(GL_ARRAY_BUFFER); 
#endif
	// Describe to OpenGL where the vertex data is in the buffer
	glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)((char*)NULL));
	// Describe to OpenGL where the color data is in the buffer
	glColorPointer(4, GL_UNSIGNED_BYTE, 0, (GLvoid*)((char*)NULL+vertex_size));
	// create index buffer
	glGenBuffers(1, &cubeIBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeIBO);
	// For constrast, instead of glBufferSubData and glMapBuffer, we can directly supply the data in one-shot
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUMBER_OF_CUBE_INDICES*sizeof(GLubyte), s_cubeIndices, GL_STATIC_DRAW);

And then drawn this way:


    [EAGLContext setCurrentContext:context];
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(-1.5f, 1.5f, -2.5f, 2.5f, -10.5f, 10.5f);
    glMatrixMode(GL_MODELVIEW);
    glRotatef(0.1f, 0.3f, 0.5f, 0.0f);
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    // Activate the VBOs to draw
    glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeIBO);
    // This could actually be moved into the setup since we never disable it
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    // This is the actual draw command
    glDrawElements(GL_TRIANGLE_STRIP, NUMBER_OF_CUBE_INDICES, GL_UNSIGNED_BYTE, (GLvoid*)((char*)NULL));
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];