Friday, December 12, 2008

NeHe Tutorials, Lesson 3 Ported to iPhone

Here is the iPhone version of NeHe Lesson 3.

Here is the ported code for lesson 3.

Again, most of what's there is valid, and you should read the original lesson - I'm not going to cover everything - but there are some bits of functionality in Lesson 03 that are not available on the iPhone. <

First of all, glColor3f() does not exist in OpenGL ES - you have to use glColor4f() instead. The only difference is that you must pass in not only a value for red, green, and blue, but also for alpha. You could always define your own glColor3f() like so:

#define glColor3f(r,g,b) glColor4f(r,g,b,1.0)

Though it's probably easier if you just get used to using glColor4f().

The other bit of missing functionality is a little more complex, and it requires us to jump ahead of the tutorial once again. In the tutorial, when drawing the triangle, they change the color at each vertex. Between the calls to glBegin() and glEnd(), they set a color, define a vertex, set a new color, define another vertext, etc. OpenGL then interpolates the inbetween values to give a nice gradient effect. However, because we have to define our vertices using a vertex array in OpenGL ES, there's no way to change colors between the vertices the way they do in this lesson.

All is not lost, however. There is very little in OpenGL that can't be done in OpenGL ES, and in this case, we can achieve the same functionality by using a color array, which is just an array of values like the vertex array from last lesson. In the lesson, they set the color to red before defining the first vertex, then to green before the second, then to blue for the third vertex. We can achieve the same thing by defining another array of GLFloat values, like so:

const GLfloat triVertexColors[] = {
1.0f, 0.0f, 0.0f, 1.0f, // Red
0.0f, 1.0f, 0.0f, 1.0f, // Green
0.0f, 0.0f, 1.0f, 1.0f // Blue
};

In this case, we're defining each color with 4 values (red, green, blue, alpha), and our array has one color to correspond to each of the vertices in our vertex array, meaning an array of twelve items (4 floats per color times three vertices). When OpenGL goes to draw, it will use the first four values from this array to set the color for the first vertex in the vertex array, the second four values to set the color for the second vertex in our array, and the last four values to set the color for the last vertex.

In order to use a color array, we have to enable it, just like we did with vertex arrays. Again, this can be done once, in setup, or can be enabled and disabled as needed at runtime. Generally, you will enable it before you use it, and then disable it afterwords, otherwise future calls to glColor4f() will be ignored, which may not be what you want. Here is the call to enable color arrays:
glEnableClientState (GL_COLOR_ARRAY);
and to disable
glDisableClientState (GL_COLOR_ARRAY);

Then, before we call glDrawArrays(), we have to tell OpenGL about our color array. We do that like so:
glColorPointer (4, GL_FLOAT, 0, triVertexColors);
The call is very similar to our glVertexPointer() from Lesson 02 (which is also used in this project, of course). The first argument tells OpenGL that each color is made up of four values. The second argument tells OpenGL that those values are GLfloats. The third value is that one you can forget about for now, and the last one is the pointer to the color array.

That's all there is to it - run it now, and you'll get your pretty triangle, just like in the NeHe lesson:

No comments:

Post a Comment