The aim of this tutorial is to show how to get started with OpenGL ES for iPhone/iTouch; OpenGL ES 2.0 is only available on the iPhone 3GS, so this article focuses on 1.1.

The article is based on the GLES2Sample project from the Apple iPhone dev library. This project is ideal as a starting point for a 3D app/game for several reasons:

  • It is compatible with OpenGL-ES 1.1/2.0 and can choose the right version at runtime.
  • It provides a run loop, and will select the best strategy to setup a run loop according to whatever version of iPhone OS is running on a target.
  • We can ignore the boiler plate and start playing (or indeed, developing) right away.

In short, OpenGL-ES on iPhone requires setting up a special UIView and a run loop. You’ll need a good reason to modify the default setup. OpenGL rendering itself is all done within the ES1Renderer and ES2Renderer classes.

If you want to learn more about the boiler plate, it’s in the example (and there is apple documentation to explain the boiler plate) If you want to know how to get started with basic OpenGL commands, live in ignorance and bliss and learn more and more about OpenGL – ES, this article is just for you.

  1. Download and open the GLES2Sample project from the Apple iPhone dev library.
  2. In EAGLView.m comment out the following line:
    renderer = [[ES2Renderer alloc] init];
    This makes sure we are only using the ES1 renderer (otherwise changes described in this article will have no effect). An alternative could be to set your device version to 3.0
  3. Open ES1Renderer.m
  4. Search for - (void) render
  5. Notice the const GLfloat and const GLubyte arrays. The first array contain (2D) coordinates (vertices). The second array contains colors in RGBA format. Skip to glVertexPointer (a few lines down, same function)
    - glVertexPointer passes the array of vertices to the gl.
    - glEnableClientState(GL_VERTEX_ARRAY) tells the GL that you indeed want to use the passed vertex data.
    - glColorPointer passes colors (to be associated to vertices) to the GL.
    - glEnableClientState(GL_COLOR_ARRAY) tells GL that you indeed want to use the passed colors.
    - glDrawArrays tells gl to use the data you passed/enabled to draw triangles.

Here’s the code fragment anyway:

const GLfloat squareVertices[] = {
-0.5f, -0.5f,
0.5f,  -0.5f,
-0.5f,  0.5f,
0.5f,   0.5f,
};
const GLubyte squareColors[] = {
255, 255,   0, 255,
0,   255, 255, 255,
0,     0,   0,   0,
255,   0, 255, 255,
};
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();	// this clears the projection
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();	// this clears the model transform
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glRotatef(60.0f, 1.0f, 0.0f, 0.0f); // rotate around x axis
glRotatef(45.0f, 0.0f, 0.0f, 1.0f); // rotate around z axis

glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

NOTE: The above code fragment is reproduced with Apple’s permission (as per ES1Renderer.m license in the ES2Example)

This is pretty much how the GL works. Some GL calls are used to pass data, other GL calls are used to effect commands on this data.

Let’s have a look at the above functions in detail:

1) in glVertexPointer(2,GL_FLOAT,0,squareVertices), parameters are:
- 2 is the number of coordinates per vertex. that could be 2 or 3.
- GL_FLOAT is the vertex format. I think float is often fine – modern CPUs/GPUs are kind of optimized for float versus integer calculations, not intuitive but maybe true. floats are easy to use.
- 0 is the stride. Let’s keep this to zero to save explaining what is stride.
- squareVertices is your vertices as defined in the array.
2) in glColorPointer(4,GL_UNSIGNED_BYTE,0,squareColors),
- 4 is colors per vertex, which is red, green, blue + alpha
- GL_UNSIGNED_BYTE is color components from zero to 255. You can have floating point colors in the range [0.0-1.0] if you prefer. I don’t know which is faster. maybe the unsigned byte version.
3) in glDrawArrays(GL_TRIANGLE_STRIP,0,4)
- GL_TRIANGLE_STRIP means draw triangles in a sequence, reusing
(apparently) 2 vertices every time. You can use GL_TRIANGLES instead. not as efficient, but to make things by hand, GL_TRIANGLES is logical – you want 2 triangles, you pass 6 vertices.
- 0 is the index of the first vertex you want to draw from.
- 4 is the index of the last vertex you want to use.

Usually to do some low level 3D rendering you draw triangles. GL also lets you draw lines and vertices.