Friday, December 12, 2008

NeHe Tutorials, Lesson 2 Ported to iPhone

The first substantive OpenGL lesson over at the great NeHe Productions website is Lesson 02

I have ported this lesson's code to the iPhone. Here is the source code.

You should read the lesson, but you should also note that the drawing technique used in the early NeHe lessons (using glBegin(); and glEnd();) is not supported on OpenGL ES 1.1. As a result, the project linked above uses something called vertex arrays, which aren't covered until much later in the NeHe lessons. Here is the basic difference in the drawing code:

In the NeHe tutorial, they do this:
glBegin(GL_TRIANGLES);     // Drawing Using Triangles
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glEnd(); // Finished Drawing The Triangle

The call to glBegin() tells OpenGL that the code that follows is going to define points (or vertices) in virtual space. Then the three calls to glVertex3f define the vertices using cartesian coordinates (x, y, z). Because GL_TRIANGLES was specified in glBegin(). OpenGL will draw and fill the triangle defined by the three vertices specified before the call to glEnd()

On the iPhone, instead of doing that, we have to place the same three vertices into an array (not an NSArray - a good old-fashioned C array). This array, oddly enough, is called a "vertex array". Here's what a vertex array containing the three vertices in the code above looks like:

const GLfloat triVertices[] = { 
0.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f
};
Notice that we have nine elements in the array - that's three vertices with three values each (x,y,z). Vertices can be defined by either 2 or 3 points depending on whether you are doing three-dimensional or two-dimensional drawing. Although we are drawing flat, two-dimensional shapes here, we are actually drawing them in three-dimensional space, so the first value in our array is an x location, the second is a y location, and the third is a z location. Then we move on to the next vertex, with another x, then y, then z, etc.

In order to use vertex arrays, we have to enable that feature in OpenGL, like so:
glEnableClientState(GL_VERTEX_ARRAY);
The call to glEnableClientState can be either in the setup code, or in the drawing code, depending on your needs, and states can be enabled and disabled during the life of the application, so if you only use vertex arrays in one part, you could enable it, do your vertex array drawing, then disable it by calling glDisableClientState(GL_VERTEX_ARRAY);.

After defining the vertex array and turning vertex arrays on, we have to tell OpenGL ES to draw the vertex array. We do that like so:
glVertexPointer(3, GL_FLOAT, 0, triVertices);
This function tells it that the triVertices array is a vertex array, and that each vertex has three data elements (x, y, z). If we were doing two-dimensional drawing and using vertices with two values, we would have passed 2 instead of 3 for the first argument. The second argument GL_FLOAT tells OpenGL ES that our array is an array of floating point (GLfloat) values. The third parameter isn't used here, so we pass 0. This parameter can be used to "skip" values in a vertex array while drawing - don't worry about this, it's not something you're likely to use until you know more about OpenGL than I do. The final argument is a pointer to the array we're telling OpenGL about.

Now that OpenGL ES knows about the vertex array, we can tell it to draw the vertices in that array. We do that like so:
glDrawArrays(GL_TRIANGLES, 0, 3);

In this function call, the first argument mirrors the one used in the glBegin(); call in the original tutorial - it tells OpenGL which to use from several ways it knows how to draw. Some of the options include drawing points, lines, triangles, and several more advanced options.

And that's it - everything else from the tutorial should be the same - glIdentity(), glTranslate() etc, all function exactly the same, we just had to fast-forward a little to vertex arrays because of the limitations of OpenGL ES.



8 comments:

Heber said...

Thanks for the tutorials - this is exactly what I've been looking for!

Rob said...

Awesome! This definitely clear some things up for me.

How would this work for glBegin(GL_LINE_LOOP) since the number of vertices are not known in advance?

Ragesh said...

Really A Great Work... Keep It up :)

RagesH.

gonzobrains said...

I tried to run the project but all I get is a blank screen.

johnfoxxe said...

yeah, I get a blank screen too. When I exit the program, the shapes are visible (but the program closes!)

I tried changing the background color
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

but that didn't work either.

Edwin said...

scrub m65 kamagra attorney lawyer body scrub field jacket lovegra marijuana attorney injury lawyer

Pavel said...

We developed mobile applications that take advantage of the following iPhone technologies: multi-touch interface, accelerometer, GPS, proximity sensor, dialer, address book and calendar, etc. We have made GPS-based iPhone application development and (Location Based Service) LBS based location tracking applications for iPhone.
java software company | software development company | java web development | blackberry application development | iphone application development | android application development | java outsourcing | it outsourcing services | http://www.tenaxtechnologies.com

h4ns said...

What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.

Arsenal vs Huddersfield Town live streaming
Arsenal vs Huddersfield Town live streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Notts County vs Manchester City Live Streaming
Notts County vs Manchester City Live Streaming
Bologna vs AS Roma Live Streaming
Bologna vs AS Roma Live Streaming
Juventus vs Udinese Live Streaming
Juventus vs Udinese Live Streaming
Napoli vs Sampdoria Live Streaming
Napoli vs Sampdoria Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
AS Monaco vs Marseille Live Streaming
AS Monaco vs Marseille Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Technology News | News Today | Live Streaming TV Channels