Simon Maurice's iPhone OpenGL ES Tutorial -Back up



Simon Maurice's iPhone OpenGL ES Tutorial -Back up




OpenGL ES 00 - Xcode Project Set Up


OpenGL ES 01 - Drawing Primitives 1 - Triangles


OpenGL ES 02 - Drawing Primitives 2 - Squares


OpenGL ES 03 - Transformations


OpenGL ES 04 - Color and Shading


OpenGL ES 05 - Texture Mapping Our Square



OpenGL ES 06 - Objects in 3D


OpenGL ES 07 - Translating Objects Independently


OpenGL ES 08 - The Final Primitives: Points and Lines in a Stride


OpenGL ES 09 - Blending Without Mr. Buzzy Part 1


OpenGL ES 10 - Multiple Textures, Repeating Textures, and The End of the Book Era


OpenGL ES 11 - Single Texture, Multiple Looks, Render to Texture, and Getting Inspired in Maths


OpenGL ES 12 - Landscape View & Handling Touches Part 1 - 2D World


OpenGL ES 13 - Moving in 3D


OpenGL ES 13.5 - Moving in 3D Part 2: Some Theory that I Should Have Explained


OpenGL ES 14 - Blender Models Part 1: Learning Some Blender Internals


OpenGL ES 15 - Blender Models Part 2: Loading and Rendering


OpenGL ES 16 - Blender Models Part 3: Textures and UV Mapped Objects


OpenGL ES 17 - Collision Detection


OpenGL ES 18 - Monkeys on Your Back and Geometric Shapes


OpenGL ES 19 - So You Wanna Be an iPhone Games Programmer?


Source codes can be found here

Since the original website of Simon Maurice seems not available, many people have been searching for this cool tutorial. This one is pretty good to start learning Open GL ES for iPhone programming . It gives a detailed explanation for every code and also gives sample source codes. Hope it may help you. All the best!




Disclaimer: This post and the whole blog is just a copy of iPhone-OpenGL-ES-tutorial-Series  (seems to have ) written by Simon Maurice. This blog does NOT have a written permission or any kind of permission from the original author (Simon Maurice). Please use it at your own risk. If you have any complaints regarding any content of this blog, please let me know I will remove it right away. Just hoping that it would be helpful for people who are trying to learn OpenGL. Happy coding!



Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.





OpenGL ES 00 - Xcode Project Set Up


OpenGL ES 00 - Xcode Project Set Up

Since the original website of Simon Maurice seems not available, many people have been searching for this cool tutorial. This one is pretty good to start learning Open GL ES for iPhone programming . It gives a detailed explanation for every code and also gives sample source codes. Hope it may help you. All the best!


Disclaimer: This post and the whole blog is just a copy of iPhone-OpenGL-ES-tutorial-Series  (seems to have )written by Simon Maurice. This blog does NOT have a written permission or any kind of permission from the original author (Simon Maurice). Please use it at your own risk. If you have any complaints regarding any content of this blog, please let me know I will remove it right away. Just hoping that it would be helpful for people who are trying to learn OpenGL. Happy coding!



Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Source codes can be found here

Original tutorial starts from here onwards..


OpenGL ES on the iPhone is a cinch to set up with Xcode, especially since Apple introduced the template with the SDK release. All we really need is a place where you can get to and start adding in code quickly and easily. This is what we’re going to do today.


To be quite honest, I really don’t think that it’s necessary to type everything in from this and if you just want to get into the meatier OpenGL tutorials which follow, skip this by all means. In this case, there’s nothing wrong with skipping the set up as I’m not going to go into the detail of it. Just head down to the end of this tutorial and download the project file.


Start by firing up Xcode and creating a new project. Choose the template called: “OpenGL ES Application” (Figure 1) and save the project somewhere convenient for you.






OK, I’m going to assume at this point that you’ve probably already had a quick look around this template at some point in the past, probably had a look at the running application. What we’re going to do is to remove the code for the spinning coloured square and convert the view to use a depth buffer (ie make it “true” 3D). This will give us a space for our tutorials.


2D in a 3D Space


Like this Apple template, most OpenGL tutorials start off by ignoring depth, usually using a 2 point co-ordinate system (X, Y) rather than the more standard 3 co-ordinate system (X, Y, Z). You may have noticed that the vertices for the square in Apple’s template only uses the (X, Y) co-ordinates, that’s because they are not using depth!


This is called Orthographic projection. As the goal of this tutorial series is to get you to 3D, I’l not going to cover orthographic projection at this point; maybe later in the series but for now, we’re going to keep heading into 3D.


Enabling Depth Buffer

The first thing we need to do is to enable the depth buffer. Apple’s example square is only a 2D object so doesn’t actually need a depth buffer. We need depth so we’ll enable it. Apple has kindly provided the code to setup the depth buffer so we’ll just take advantage of it.


Open EAGLView.m in the editor and look for the following line:


#define USE_DEPTH_BUFFER 0
Needless to say, change that 0 to a 1. This will turn on the code in the view setup area to create the depth buffer. This code is contained in the createFrameBuffer method. Don’t worry too much about this method at the moment. It’s written by Apple so just accept it does what it’s supposed to.

Now, we need to enable depth testing within OpenGL. To do this, we do need to create a new method which will be called once to enable our view to work. Start by creating a new method called setupView and insert the following code into this new method:


- (void)setupView {
   const GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 60.0;
   GLfloat size;
   glEnable(GL_DEPTH_TEST);
   glMatrixMode(GL_PROJECTION);
   size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
// This give us the size of the iPhone display
   CGRect rect = self.bounds;
   glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / 
(rect.size.width / rect.size.height), zNear, zFar);
   glViewport(0, 0, rect.size.width, rect.size.height);
   glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

All this code does is set up the conditions in which OpenGL will operate by creating a View Port which will be mapped to the actual size of our display. Like I said, I’ll go into detail about this later on but for now, just take note of the following:


glEnable(GL_DEPTH_TEST);
This enables the Depth Testing in OpenGL. You need to remember that once you turn something “on” in OpenGL, you need to turn it off later if you don’t want to continue using it. As we will only turn on depth testing and never turn it off, it can go here in the view setup.


glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
What we’re doing here is defining what colour to use when we clear the screen. All colours in OpenGL ES must be RGBA values (ie Red, Green, Blue, Alpha), and cannot just be RGB values as in OpenGL. So, later on when we clear our screen, OpenGL ES will already know we want it cleared in a black colour. It will continue to use this colour until we change it.


The colour values can be 0 -> 1 if using floating point or 0 -> 255 if using unsigned bytes. The higher the value, the higher the colour intensity.


OK, back to the top of the file and find the #define we had changed earlier. We just need to install a macro here which is needed for the setupView method we just inserted.


#define USE_DEPTH_BUFFER 1
#define DEGREES_TO_RADIANS(__ANGLE) ((__ANGLE) / 180.0 * M_PI)
Draw View - The drawing method


Now, go down to the drawView method. This is where everything happens in our tutorials. You can see here where Apple has even given us a pointer to the fact this is where we’re going to be doing our work.


First of all, delete everything in this method, and replace the contents with the following code:

- (void)drawView {
   [EAGLContext setCurrentContext:context];   
   glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
   glViewport(0, 0, backingWidth, backingHeight);
   glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
   [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

The first three lines of the code above, just sets up our drawing space. The last two lines swaps our drawing space with the space which is currently viewed on screen. If you’ve ever done animation or game programming before, you’ll know that this is what’s called “double buffered”.


For those who don’t know, what this means is that we create two identical buffers: one which is displayed to the user, the other is cleared and we draw on it. When we finish drawing, we swap the views so the user sees the new view. The reason why we go to all this trouble is to make the animation smooth.


We’re not going to add any more code to make this display anything at the moment, we’ve still got some more set up to do.


Firstly, right before the dealloc method, insert the following code:

- (void)checkGLError:(BOOL)visibleCheck {
   GLenum error = glGetError();
   switch (error) {
       case GL_INVALID_ENUM:
           NSLog(@"GL Error: Enum argument is out of range");
           break;
       case GL_INVALID_VALUE:
           NSLog(@"GL Error: Numeric value is out of range");
           break;
       case GL_INVALID_OPERATION:
           NSLog(@"GL Error: Operation illegal in current state");
           break;
       case GL_STACK_OVERFLOW:
           NSLog(@"GL Error: Command would cause a stack overflow");
           break;
       case GL_STACK_UNDERFLOW:
           NSLog(@"GL Error: Command would cause a stack underflow");
           break;
       case GL_OUT_OF_MEMORY:
           NSLog(@"GL Error: Not enough memory to execute command");
           break;
       case GL_NO_ERROR:
           if (visibleCheck) {
               NSLog(@"No GL Error");
           }
           break;
       default:
           NSLog(@"Unknown GL Error");
           break;
   }
}

OpenGL has an error checking method as called above (glGetError()) but the error code returned needs to be manually converted to a human readable message from the error code. That is what the above method does.

The BOOL parameter “visibleCheck” is only there so that sometimes you can check and see that the routine was called and when there are no errors.

The last thing we need to do in EAGLView.m is to go to the initWithCoder method and actually call the “setupView” method we created earlier. Below the setting of the variable “animationInterval”, insert the following to call the setupView method:

       [self setupView];

Note of course that we could have put the setupView method’s code in the initWithCoder method rather than create a new method, as generally it’s only ever called once.

OK, done in EAGLView.m; Switch to EAGLView.h!

EAGLView.h
Fortunately, there is not much work to be done here. All we need to do is to create the prototypes for the two methods we created as follows:

- (void)setupView;
- (void)checkGLError:(BOOL)visibleCheck;
And that’s us done for this tutorial.

Next Steps...

If you were to build and run this in the simulator, you’d just get a blank screen and nothing interesting would happen. In the next tutorial, we’re going to start drawing primitives on the screen, primitives are just basic drawings like points, lines and triangles.

For those of you who just want to download the project files and not type it all in, here it is:

AppleCoder-OpenGLES-00.zip
The home of the tutorials is in the “Tutorials” section of the iphonedevsdk.com forums. Check out the thread there.

Until then, hooroo!

Simon Maurice

Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.
Linking to these pages on other websites is permitted.

OpenGL ES 01 - Drawing Primitives 1 - Triangles


OpenGL ES 01 - Drawing Primitives 1 - Triangles

Since the original website of Simon Maurice seems not available, many people have been searching for this cool tutorial. This one is pretty good to start learning Open GL ES for iPhone programming . It gives a detailed explanation for every code and also gives sample source codes. Hope it may help you. All the best!

Disclaimer: This post and the whole blog is just a copy of iPhone-OpenGL-ES-tutorial-Series  (seems to have )written by Simon Maurice. This blog does NOT have a written permission or any kind of permission from the original author (Simon Maurice). Please use it at your own risk. If you have any complaints regarding any content of this blog, please let me know I will remove it right away. Just hoping that it would be helpful for people who are trying to learn OpenGL. Happy coding!



Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Source codes can be found here

Original tutorial starts from here onwards..


Primitives are the basic drawing elements which make up complex objects. In OpenGL ES the primitives you can use are Points, Lines, & Triangles. These are pretty self explanatory and I doubt you need an explanation of what these look like.

First of all, let’s look at some code and then we can talk about what’s going on so you can then use it to create some of your own code.

Primitive #1 - Triangles

Triangles are the most “complex” of the primitives but they’re so easy to use and so useful, this will be the first OpenGL primitive that you’ll draw. When drawing a triangle, all we need to do is to feed OpenGL with the three co-ordinates in 3D space for the triangle and it will render it quite happily.

To get started, make a copy of the project from the OpenGL ES 00 tutorial or just download it from here: AppleCoder-OpenGLES-00.tar.gz Open it up in Xcode and go straight to the EAGLView.m file and find the drawView method. This is where the magic starts!

First, we need to define the triangle. In order to do this, you need to understand there are two types of co-ordinates that we are going to deal with: Model and World. The Model co-ordinates are in reference to the actual primitive that we are drawing, the world co-ordinates tell OpenGL where it is in relation to viewer (the viewer is always at world co-ordinates of (0.0, 0.0, 0.0).

This first example will illustrate this. First, we define the triangle in the model space using 3 x 3D co-ordinates (X, Y, Z):

const GLfloat triangleVertices[] = {
       0.0, 1.0, -6.0,// Triangle top centre
       -1.0, -1.0, -6.0,// bottom left
       1.0, -1.0, -6.0,// bottom right
};
As to be expected, there are 3 co-ordinates giving the triangle and note that they are described sequentially in an anti-clockwise direction. Whilst they can be described in a clockwise or anti-clockwise direction, they must be described sequentially and be consistent. However, I would encourage you to start off using anti-clockwise co-ordinates as it’s needed for some more advanced functions much later on.

While this tutorial is supposed to be purely iPhone OpenGL ES, for the beginners, I’ll describe the 3D co-ordinate system briefly here. Take a look at this picture:

5_627_5a28c5bfe492dc5.jpg

Sorry about my drawing skills but this is a representation of what either the model space or world space looks like. Just imagine this is you’re computer screen with X and Y being horizontal and vertical as you would expect, and Z being depth. The centre co-ordinates being (0.0, 0.0, 0.0).

So, looking at our triangle as described in the vertices above, the first point (0.0, 1.0, -6.0) would be dead centre on the Y axis, up 1 point and back into the screen 6 points. The second co-ordinate is to the right of the Y axis 1.0 points, below the X axis (hence -1.0 for the Y value), and still back into the screen -6.0 points. The same applies to the third co-ordinate.

The reason why we have set the object back (ie negative Z value) is so that it will be visible (remember, our viewer or “camera” is at (0.0, 0.0, 0.0) so it would “fail” OpenGL’s depth test and not render it at all.

I can hear you screaming “Hey, I thought you said this was Model co-ordinates which are not world co-ordinates!!”. Yes, that’s true, but when we get to rendering this triangle next, OpenGL will simply place the object at (0.0, 0.0, 0.0). So we set it back into the screen so it is visible. When we get into transformations (moving, rotating etc), you’ll see ways that you don’t need to set the object into a negative Z value to make it visible. Until then, leave the Z co-ordinate at -6.0.

The Drawing Code

So all we’ve done so far is to describe the triangle. We now need to tell OpenGL where that data is stored and how to draw it. This is accomplished with only a few lines of code. Go back to the drawView method and implement it as follows:

- (void)drawView {
   const GLfloat triangleVertices[] = {
       0.0, 1.0, -6.0,                    // Triangle top centre
       -1.0, -1.0, -6.0,                  // bottom left
       1.0, -1.0, -6.0                    // bottom right
};
   [EAGLContext setCurrentContext:context];
   glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
   glViewport(0, 0, backingWidth, backingHeight);
// -- BEGIN NEW CODE
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glVertexPointer(3, GL_FLOAT, 0, triangleVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, 3);
// -- END NEW CODE
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
[self checkGLError:NO];
}
As you can see, in 4 lines of code we can render a triangle. Let me break this down line by line and you’ll see it’s actually quite simple.

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

This line simply clears the screen. The control bits we feed it tells OpenGL to use the colour we set up in the setupView method from the last tutorial (black colour) and to clear the depth buffer. Note that if we did not clear the depth buffer and have depth buffer turned on (as we do), the scene would not render. If we did not enable the depth buffer, we would not need to pass glClear() the GL_DEPTH_BUFFER_BIT.

So, we’ve cleared whatever was previously drawn on this buffer (remember, it’s double buffered animation; draw on one buffer while another buffer is displayed).

glVertexPointer(3, GL_FLOAT, 0, triangleVertices);

This function tells OpenGL where our data is and what format it is in. There are 4 parameters for this function and is quite simply broken down as:

1.Size - this is the number of values in each co-ordinate. In our case it is 3 for the values being (X, Y, Z). If you were doing 2D drawing and didn’t have a depth (ie Z value), then you could pass 2 here.

2.Data Type - GL_FLOAT means that we are passing floating point values. You could also use integer values if you want but you need to get used to floating point values as 3D worlds are floating point.

3.Stride - the stride tell OpenGL to ignore a certain number of bytes between each co-ordinate. Don’t worry about this, keep it as zero. You only use this when you are loading vertex data from file in a format which has additional padding data or colour data from, say, a 3D program like Blender.

4.Pointer to the Data - exactly as it appears, the data itself.

So, we’ve told OpenGL to clear the buffer, told it where the data is for our object and it’s format, now we need to tell OpenGL something quite important:



glEnableClientState(GL_VERTEX_ARRAY);

OpenGL is a “State” machine. This means that you turn on and off functionality by calling enable and disable commands. Previously, we had used glEnable() which affects the “server” side of OpenGL. glEnableClientState() affects our program side (ie the client side). So, what we’ve done is told OpenGL that our vertex data is in a vertex array and turned on OpenGL’s functionality for drawing a vertex. A vertex could be a colour array in which case we would call glEnableClientState(GL_COLOR_ARRAY) or perhaps a texture co-ordinate array in the case of texture mapping (stop salivating! You need to get through the basics before I cover texture mapping!!).

As we get further into OpenGL, we’ll use the different client states and this will become clearer with use.

Now comes the the command to make OpenGL render a triangle:

glDrawArrays(GL_TRIANGLES, 0, 3);

Once this function is called, OpenGL takes the information which we had fed it from the previous two functions and executes it. On the screen will be a triangle solid white in colour (white is the default drawing colour). Triangles are filled objects, if you needed an unfilled triangle, then you need to draw it differently.

Breaking down this function, the three arguments are:

1.Drawing Method - in this case, we have passed GL_TRIANGLES which seems fairly obvious as we are drawing a triangle. However, the power of this first argument will become apparent when we use this function to draw a square.

2.First Vertex - our array consists of only three points so we want OpenGL to draw from the first co-ordinate in our array which is specified as Zero just as in accessing a standard array. If we had multiple primitives in our vertex array, we could put the offset in here. I’ll cover the use of this in a later tutorial when I show you how to build complex objects. For now, just use 0 here.

3.Vertex Count - This tells OpenGL how many vertices are in our array that it needs to draw. Again, we are drawing a triangle so only three points are required. A square would have 4 points, a line 2 points (or more) and a Point would be 1 or more (in the case of rendering multiple Points).

Once you’ve entered the code and you’re drawView method looks like mine above, hit “Build and Go” running it in the simulator. You’re simulator should look like this:

5_627_3016897660d33fc.png


As promised, there’s a solid white triangle in the centre of the screen.

Before we go onto other primitives, try changing the Z value and you will see what I mean if you change it to 0.0. Nothing will render.

There’s been a lot of typing over a couple of lines of code, but I hope it’s been worth it for you to see just how OpenGL ES works. If you’ve ever tried to follow a “standard” OpenGL tutorial and just got stuck, I hope you can start to see the difference between OpenGL and OpenGL ES.

Looking Forward

The next tutorial will focus on expanding the code above and producing a square. Below is the link to the project code for you to download if you couldn’t get yours working.

If you have any questions, just email me (link below). And here’s the source code for this tutorial:

AppleCoder-OpenGLES-01.zip
The home of the tutorials is in the “Tutorials” section of the iphonedevsdk.com forums. Check out the thread there.

Until then, hooroo!

Simon Maurice

Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.
Linking to these pages on other websites is permitted.

OpenGL ES 02 - Drawing Primitives 2 - Squares


OpenGL ES 02 - Drawing Primitives 2 - Squares

Since the original website of Simon Maurice seems not available, many people have been searching for this cool tutorial. This one is pretty good to start learning Open GL ES for iPhone programming . It gives a detailed explanation for every code and also gives sample source codes. Hope it may help you. All the best!

Disclaimer: This post and the whole blog is just a copy of iPhone-OpenGL-ES-tutorial-Series  (seems to have ) written by Simon Maurice. This blog does NOT have a written permission or any kind of permission from the original author (Simon Maurice). Please use it at your own risk. If you have any complaints regarding any content of this blog, please let me know I will remove it right away. Just hoping that it would be helpful for people who are trying to learn OpenGL. Happy coding!



Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Source codes can be found here

Original tutorial starts from here onwards..



Strictly speaking, squares are not a primitive in OpenGL ES but, let’s face it, they’re pretty handy and just as easy as rendering a triangle. In this tutorial, we’re going to take the code from the triangle primitive and turn it into a square. Again, it will be rendered statically but we’re going to get into transformations (ie moving them around) quickly enough. Of course, once we’ve done a square, we can then make a cube, then even a texture mapped cube...


Quick Recap and Details of This Tutorial


Last tutorial, we took our “blank canvas” Xcode project and rendered a solid white triangle. In doing so, you created a vertex array, told OpenGL about the data and it’s format using glVertexPointer(), put it in the state for rendering the vertex array, and then rendered it using glDrawArrays().


Today, we’re going to take that code, and make a square from the triangle. In order to do that, we will only need to change a couple of lines of code. The first one is probably obvious, we need to specify 4 points for the square instead of 3 for a triangle. Then we need to tell OpenGL to draw it differently by passing a different drawing methodology to glDrawArrays().


Let’s get going.
 
Defining the Square’s Vertices

Open up the Xcode project from the last tutorial and go to the drawView method. Comment out the triangleVertices[] constant - don’t discard it as we’ll use it when we get into transformations - and add in the following code:

const GLfloat squareVertices[] = {
       -1.0, 1.0, -6.0,            // Top left
       -1.0, -1.0, -6.0,           // Bottom left
       1.0, -1.0, -6.0,            // Bottom right
       1.0, 1.0, -6.0              // Top right
 };

That describes our square. Note the anti-clockwise direction of the vertices (the four points) of the square?

Now go down into the body and comment out the drawing code for the triangle, again we’ll bring this code back to life later on. So comment out the three function calls of glVertexArray(), glEnableClientState(), and glDrawArrays() and add the following code:

glVertexPointer(3, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

It’s the same three functions but just slightly different.

glVertexPointer(3, GL_FLOAT, 0, squareVertices);
The only change here is that we are telling OpenGL to use a different set of vertices; the square now and not the triangle.

glEnableClientState() is the same as we are telling OpenGL to draw from a vertex array (not a colour array or something else).

glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
This is the main change. In the last tutorial, we used GL_TRIANGLES as the first parameter and 3 as the 3rd parameter. Remember the second parameter is the offset from the start of the array to being from, again this is zero because our vertex array only contains the vertices for the square.


The first argument is the drawing mode and you’ve now seen two possible drawing modes for OpenGL. I do want to take the time now to discuss the different drawing modes. They are:


GL_POINTS
GL_LINES
GL_LINE_LOOP
GL_LINE_STRIP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN

We haven’t discussed points or lines yet so I’ll stick to the last three which refer to triangles. Before I commence, I want to remind you that a vertex array may contain more than one triangle so while you have only seen one object per vertex array, you’re not limited to that.


GL_TRIANGLES - passing this parameter means that OpenGL treats the vertex array in sets of 3 vertices. So, for the first three, it makes a triangle bound by vertex 1, vertex 2, and vertex 3. Then it will process the next three vertices and so on to the end of the array.


GL_TRIANGLE_STRIP - OpenGL will start off using the first two vertices, then for each successive vertex, it will use the previous 2 vertices to make a triangle. That is, for squareVertices[6~8], a triangle is formed with squareVerticies[0~2] and squareVerticies[3~5]. For squareVertices[9~11], a triangle is formed with squareVertices[3~5] and squareVertices[6~8]. And so on through the array.


Note: the reference to squareVertices[0~2] refers to:


squareVertices[0] - X co-ordinate

squareVertices[1] - Y co-ordinate

squareVertices[2] - Z co-ordinate

I’ll cover this in an example further on in this tutorial if that doesn’t make sense.

GL_TRIANGLE_FAN - After the first 2 vertices, for each successive vertex, OpenGL will form a triangle with with the previous vertex and the first vertex. So, for squareVertices[6~8], a triangle is formed with squareVertices[3~5] (previous vertex) and squareVertices[0~2] (first vertex).


Since we used GL_TRIANGLES_FAN, we will get a square on the display. Hit “Build & Go”, and you should be rewarded with a white square on the screen like this:


5_627_1951b4ea6ee611e.png

Go back and have a look at your vertex array. Try to imagine the triangles being drawn to make the square. OpenGL renders it like this.


Triangle Point 1: squareVertices[0~2] -- Top left of square

Triangle Point 2: squareVertices[3~5] -- Bottom left of square

Triangle Point 3: squareVertices[6~8] -- Bottom right of square


Taking the above 3 points, OpenGL draws a triangle which will make up the bottom left half of the square. Imagine the square is divided in two with a diagonal line starting at the top left corner of the square to the bottom right corner. Notice how two triangles form? OpenGL just drew the bottom left half.


Note: the reference to squareVertices[0~2] refers to:


squareVertices[0] - X co-ordinate

squareVertices[1] - Y co-ordinate

squareVertices[2] - Z co-ordinate

Triangle Point 1: squareVertices[9~11] -- Top right of square

Triangle Point 2: squareVertices[6~8] -- Previous vertex, bottom right

Triangle Point 3: squareVertices[0~2] -- First vertex, top left


Taking only 1 new point, OpenGL is able render a triangle to complete the square.

GL_TRIANGLE_STRIP
Go back to the code and change the first parameter into glDrawArrays() from GL_TRIANGLE_FAN to GL_TRIANGLE_STRIP:




glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Hit “Build & Go” and you’ll get the following image:

5_627_b343c3eb00ab83c.jpg
Let’s have a look and see why we didn’t get a square due to the single change in the drawing method. OpenGL processes our vertex array in the following manner:


Triangle Point 1: squareVertices[0~2] -- top left


Triangle Point 2: squareVertices[3~5] -- bottom left


Triangle Point 3: squareVertices[6~8] -- bottom right


OpenGL now renders a triangle using the first three points, hence, the bottom left half of the previous square rendered as per the previous example.


Triangle Point 1: squareVertices[9~11] -- top right

Triangle Point 2: squareVertices[6~8] -- Previous Vertex, bottom right

Triangle Point 3: squareVertices[3~5] -- 2nd Previous, bottom left

OpenGL now renders a triangle using these three points. In this example, it has rendered a triangle 90º away from what we want to make a square.


If we had of provided our vertex array differently, we could have produced a correct square using GL_TRIANGLE_STRIP just as well as we did we GL_TRIANGLE_FAN. Just remember the drawing method and your vertex array need to be considered together otherwise you’ll get odd results like we did when we changed from FAN to STRIP.

const GLfloat stripSquare[] = {
      -1.0, -1.0, -6.0,               // bottom left
       1.0, -1.0, -6.0,                // bottom right
      -1.0, 1.0, -6.0,                // top left
       1.0, 1.0, -6.0                  // top right
 };
So working with the above, we can see the first triangle will be formed through the first three vertices, producing a triangle as follows:


5_627_9c0a6b7a31bc4bb.png
Now, by specifying the point of the top right vertex (P4), a new triangle will be formed with the top left (P3) and the 2nd previous vertex (P2) which is at the bottom right. The new vertices are shown in Orange, Green and Red below:

5_627_0fcbb48e1c13663.png

As a result, we have produced a square. The end result is still the same but it’s just a reminder that you need to match your drawing methodology to the way you have specified your vertices.

So you’ve now seen triangles and squares. We still need to cover points and lines yet. Both are quite simple and will be covered next. As we’re building upon what we’ve already covered, we’ll add some colour into the mix next time.


Once we can colour our objects, we’ll move them around and then texture map them in 3D. Granted, it won’t be Doom 3 but you’ll start to be able to build 3D objects and then, I’ll start to cover 3D worlds.

Here’s the code for this tutorial:


AppleCoder-OpenGLES-02.zip
The home of the tutorials is in the “Tutorials” section of the iphonedevsdk.com forums. Check out the thread there.

As always, feel free to email me. Home base for these tutorials is over at the iphonedevsdk.com forum under the tutorials section.

Until next time, hooroo!

Simon Maurice

Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Linking to these pages on other websites is permitted.

OpenGL ES 03 - Transformations


OpenGL ES 03 - Transformations


Since the original website of Simon Maurice seems not available, many people have been searching for this cool tutorial. This one is pretty good to start learning Open GL ES for iPhone programming . It gives a detailed explanation for every code and also gives sample source codes. Hope it may help you. All the best!

Disclaimer: This post and the whole blog is just a copy of iPhone-OpenGL-ES-tutorial-Series  (seems to have )written by Simon Maurice. This blog does NOT have a written permission or any kind of permission from the original author (Simon Maurice). Please use it at your own risk. If you have any complaints regarding any content of this blog, please let me know I will remove it right away. Just hoping that it would be helpful for people who are trying to learn OpenGL. Happy coding!



Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Source codes can be found here

Original tutorial starts from here onwards..


Today, we’re going to build on what’s been covered so far and put both the triangle and square on the screen at the same time. To do this, we are going to move them. Moving an object is one thing of what’s called Transformation.

With OpenGL ES, there are three different types of transformations which you can use on your model (object). They are:


  1.
     •Translate - Move the object within 3D space.
  2.
     •Rotate - Rotation around either the X, Y, or Z axis.
  3.
     •Scale - Alter the size of the object. Primarily this is used in 2D orthographic projection systems as in 3D the farther an object is away (ie the more negative the Z co-ordinate) the smaller the object is rendered. But can of course be used for “special effects”.

To demonstrate these different functions, what we’re going to do is to bring both the square and the triangle onto the screen at the same time using the translate function and then proceed to the other two.

Translate
In order to effect a translation, OpenGL ES gives us a single function which we can use, aptly called glTranslatef(). Note the “f” at the end of the word translate? That just means that we are going to feed OpenGL floating point data. OpenGL ES also provides the opportunity to use fixed point data and thus call the function glTranslatex(). Fixed point data would be used on hardware without a dedicated floating point maths co-processor but as the iPhone has one built in, we don’t need to use fixed-point maths and we can just stick to floating point maths.

I just wanted to mention that in case you’re Xcode code completion prompts you to using glTranslatex() and you weren’t sure what the difference is.

OK, time to start cutting some code. Fire up Xcode and open your project. I hope you took my advice and commented out the triangle data and rendering calls and didn’t delete them otherwise you’re going to have to re-type them again.

First of all, let’s look at the two vertex arrays. We are going to make a change to the vertex data but only for the Z co-ordinates. Change all the Z co-ordinates to 0.0 like the following:

const GLfloat triangleVertices[] = {
       0.0, 1.0, 0.0,                // Triangle top centre
       -1.0, -1.0, 0.0,              // bottom left
       1.0, -1.0, 0.0                // bottom right
   };

const GLfloat squareVertices[] = {
       -1.0, 1.0, 0.0,               // Top left
       -1.0, -1.0, 0.0,              // Bottom left
       1.0, -1.0, 0.0,               // Bottom right
       1.0, 1.0, 0.0                 // Top right
   };

Do you remember why we had the Z co-ordinates as -6.0? It was because we needed to set the objects back into the screen because our “camera” is at (0.0, 0.0, 0.0). What we’re going to do is to use the glTranslatef() function to set them back 6 points instead of specifying it in our vertex arrays.

First, we need to tell OpenGL what we’re going to be translating: either the Projection (view of the world) or the Objects (models within that world). In this case, it’s the square and the triangle so we need to tell OpenGL this. Below the call to glClear() in your drawView method, call the following OpenGL function:


   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


   glMatrixMode(GL_MODELVIEW);

The call to glMatrixMode tells OpenGL to work on our vertex data rather than the projection. In our setupView method, we call this same function but use the GL_PROJECTION enum as the parameter. OpenGL is an engine which remains in the same “state” until you tell it otherwise. So, the Matrix Mode will stay in GL_PROJECTION until we say go to the model view by calling glMatrixMode(GL_MODELVIEW). Now that we have set the OpenGL state to GL_MODELVIEW, it will remain there until we tell it otherwise.

So, in fact, we could actually make this call at the end of the setupView method we created in the first tutorial if we wanted maximum performance. However, we are in tutorial world and not real world at the moment so just leave it in the drawView method.

I know I haven’t really covered using OpenGL ES in projection mode yet so don’t panic if you don’t fully understand the above. All we’re doing is putting some objects onto a screen and playing around with them while you learn OpenGL ES.

Now, remove the comments around the draw triangle code which looks like this:

glVertexPointer(3, GL_FLOAT, 0, triangleVertices);
   glEnableClientState(GL_VERTEX_ARRAY);
   glDrawArrays(GL_TRIANGLES, 0, 3);

Before these three lines of code, add the following two lines:

glLoadIdentity();
glTranslatef(-1.5, 0.0, -6.0);
glVertexPointer(3, GL_FLOAT, 0, triangleVertices);
   glEnableClientState(GL_VERTEX_ARRAY);
   glDrawArrays(GL_TRIANGLES, 0, 3);

glLoadIdentity() is just a connivence function to basically reset everything back to the original conditions. If we didn’t call this function, the glTranslatef() call would continue to move the object to the left and back into the screen until it disappeared. I’m actually going to cover a better way to do this later on (the tutorial after next in fact) so just accept for now that we’re just resetting the object data.

The next function call is where the action happens.

glTranslatef() takes three parameters:


   glTranslatef(GLfloat xtrans, GLfloat ytrans, GLfloat Ztrans);

Just review my drawing of the 3D world space before continuing.

5_627_d524bd7fb47f8de.jpg

Remember the “camera” is at (0.0, 0.0, 0.0). Our call to glTranslatef() above has the following values:


   xtrans = -1.5
   ytrans =  0.0
   ztrans = -6.0

The next thing you need to recall is that when we draw both the square and the triangle, the appeared in the centre of the screen. If we were to draw them as per the previous tutorials, they would be drawn on top of each other.

So, in order to get around this, I have moved the X co-ordinate of the centre of the triangle to the left 1.5 points. Referring to the image above of the co-ordinate space, you can see that left of screen centre is negative, hence the negative 1.5.

The -6.0 for the Z transformation replaces the -6.0 which we had originally in the object’s vertex array.

We have moved the triangle to the left 1.5 and back 6.0 points.

Moving Onto the Square
The code for the square is almost the same as the triangle. It is as follows:


   glLoadIdentity();
   glTranslatef(1.5, 0.0, -6.0);
   glVertexPointer(3, GL_FLOAT, 0, squareVertices);
   glEnableClientState(GL_VERTEX_ARRAY);
   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

This time, we have moved the square to the right by passing a positive value to the xtrans value in glTranslatef().

Hit “Build and Go” and have a look at what’s on the screen, you should get this image:

5_627_e07938f8d5ae803.png

Note that the Y co-ordinate is still centred on the screen, the sizing is the same as before because we have set them back -6.0, and they are nicely placed side-by-side.

Before We Move On
Experiment by changing values of the xtrans, ytrans, and ztrans in glTranslatef() and see what happens. I spent many an hour just changing values and watching what happens. You can even try commenting out glLoadIdentity() and see what happens.

Rotation
Get your code back to the way it is above after your experimentation and let’s have a quick look at rotation. We’ll rotate in 2D as our objects are only 2D (but in a 3D world). Later on, when we create a full 3D object, we can rotate in full 3D (and yes, we can texture map it...).

Rotation is as simple as:

glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);

This function is simple to use. First you supply how much of an angle to rotate which is the first argument, then we simply specify which axis or axes to rotate.

I will demonstrate rotation in two ways. First, we will do a static rotation, then animate it by keeping the rotation going; making our square and cube spin in effect.

First, let’s just do a simple rotation. Go to the drawView method and add the change the drawing code for the triangle and the square as follows:


   glLoadIdentity();
   glTranslatef(-1.5, 0.0, -6.0);
   glRotatef(45.0, 0.0, 0.0, 1.0);         // Add this line
   glVertexPointer(3, GL_FLOAT, 0, triangleVertices);
   glEnableClientState(GL_VERTEX_ARRAY);
   glDrawArrays(GL_TRIANGLES, 0, 3);


   glLoadIdentity();
   glTranslatef(1.5, 0.0, -6.0);
   glRotatef(45.0, 0.0, 0.0, 1.0);         // Add this line
   glVertexPointer(3, GL_FLOAT, 0, squareVertices);
   glEnableClientState(GL_VERTEX_ARRAY);
   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

All we’ve done is rotated the triangle and square by 45º along the Z axis. See the value 1.0 for the Z parameter? That tells OpenGL to rotate our object 45º along the Z axis.

Make the changes to the code and hit “Build and Run” and you should get the following on screen:

5_627_6bb72746dd59c77.jpg

Rotation along the Z axis “spins” the object on the screen - much like looking at a car tyre spinning when you’re side onto the car. Remember, the Z axis goes into the screen so it is rotating around this axis.

Rotating the X axis, would be like looking at a spinning car tyre with the car heading towards you (ie you facing the car’s front grill). Rotating the Y axis is what the tyre would look like as the driver turns the steering wheel to avoid you (hopefully!). Don’t panic if you’re a bit confused by that, this next example will allow you to play with rotation and really see what’s going on.

Spinning Our Objects
In order to make our square and triangle “spin”, we need to increase the angle each time we draw the frame. Switch to EAGLView.h and add the following variable:


   GLfloat rota;

Then switch back to EAGLView.m and, in the initWithCoder method, add the following line below the animationInterval assignment:


   rota = 0.0;

All we’ve done is to create a variable to hold the current rotation angle.

Now, head back to drawView, and add the following line of code right before the first glLoadIdentity() function call:


   rota += 0.5;

All we’re doing is increasing the rotation angle by 0.5º each time we draw our two objects. Finally, change both the glRotatef() function calls to the following:


       glRotatef(rota, 0.0, 0.0, 1.0);

So, what we’re doing is increasing the rotation angle every time we draw the objects, resulting in a spinning object. The first time we draw the objects, they will be rotated through 0.5º; the second time they are drawn, they will be rotated 1.0º etc.

Hit build and run and the two objects should spin like a car tyre when viewed side on.

For Your Experimentation
Before leaving this tutorial, I want you to do a couple of things and note what happens:


  1.
     1.Change the axis which you rotate around. Make the Z axis 0.0 and turn on each the X axis and Y axis one axis at a time and note how the objects rotate so you can get an understanding of rotation along each individual axis.
  2.
     2.Change the 1.0 on the current rotation axis to -1.0. Note that they now rotate in the opposite direction.
  3.
     3.Change the rota parameter in glRotatef() to -rota. What happens?

I hope you got something out of this. Here’s the completed code for the tutorial:

AppleCoder-OpenGLES-03.zip

The home of the tutorials is in the “Tutorials” section of the iphonedevsdk.com forums. Check out the thread there.

Now, I don’t know about you but I’m a bit bored with white objects. Next thing we’re going to do is to add some colour to these objects.

Until next time, hooroo!
Simon Maurice


Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Linking to these pages on other websites is permitted.

OpenGL ES 04 - Colour and Shading


OpenGL ES 04 - Colour and Shading


Disclaimer: This post and the whole blog is just a copy of iPhone-OpenGL-ES-tutorial-Series  (seems to have )written by Simon Maurice. This blog does NOT have a written permission or any kind of permission from the original author (Simon Maurice). Please use it at your own risk. If you have any complaints regarding any content of this blog, please let me know I will remove it right away. Just hoping that it would be helpful for people who are trying to learn OpenGL. Happy coding!



Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Source codes can be found here



Original tutorial starts from here onwards..

Like I said in the last tutorial, I’m getting a bit bored with plain white objects on the screen, let’s add some colour just like the original Apple template had before we removed it. Do pay attention to this one because some of the concepts that I will introduce will also come into play when we start texture mapping (which will be Real Soon Now).

In OpenGL ES, colour can be set as a single block colour for the entire object, or can be multi-coloured and have shading so the colours drift through the spectrum from one colour to the next. Single colour is not very complicated so let’s colour up our objects in a single colour.

Like all things with OpenGL, changing the colour puts OpenGL in a “state” where all following drawing operations will be in that colour, even if we call our “reset” being glLoadIdentity() (this is because glLoadIdentity() operates on the actual vertices only). So by adding a single line of code, we can make our two objects appear in any colour; anything’s better than white, but I’m just going to go with blue for now.

Fire up Xcode and head off to drawView. After the first glLoadIdentity() call, add the following GL function call:


   glLoadIdentity();
   glColor4f(0.0, 0.0, 0.8, 1.0);

This function call, glColor4f() tell OpenGL to commence drawing (and filling) in this colour which is a blue colour. The parameters are:


      glColor4f(  GLfloat red,
               GLfloat green,
               GLfloat blue,
               GLfloat alpha);

In OpenGL ES, you must provide colours with these four parameters (ie RGBA), there is no option for RGB colours. In case you don’t know, alpha is the level of transparency with 1.0 being fully solid, down to 0.0 which is fully transparent.

The red, green, & blue parameters are floating point values being between 0.0 and 1.0 with 0.0 being nil intensity, and 1.0 being full intensity. Therefore white would be (1.0, 1.0, 1.0, 1.0).

Add the line and hit “Build and Go”. Our two objects will look like this:

5_627_9cbe267c93ed244.jpg

Better than plain white but not very inspiring. The psychedelic colours of the Apple rotating square was more interesting so let’s have a look at how to create that.

Multiple Colours
Having an object with multiple colours is not too much more work. We need to define and array just like the vertex arrays we have been using and then tell OpenGL to get it’s colours from that array. Each colour in the colour array, represents a colour at each vertex (point) within our object’s vertex array.

Let me make that a bit clearer as we colour up the square. Have a look at the following code where I have defined a colour array to go with the square’s vertex array:

const GLfloat squareVertices[] = {
       -1.0, 1.0, 0.0,               // Top left
       -1.0, -1.0, 0.0,              // Bottom left
       1.0, -1.0, 0.0,               // Bottom right
       1.0, 1.0, 0.0                 // Top right
   };


   const GLfloat squareColours[] = {
       1.0, 0.0, 0.0, 1.0,// Red - top left - colour for squareVertices[0]
       0.0, 1.0, 0.0, 1.0,   // Green - bottom left - squareVertices[1]
       0.0, 0.0, 1.0, 1.0,   // Blue - bottom right - squareVerticies[2]
       0.5, 0.5, 0.5, 1.0    // Grey - top right- squareVerticies[3]
   };
I hope this illustrates that each colour we have given, represents a vertex for the square. Before we can run this though, we need to add some more code for colouring the square:


   glLoadIdentity();
   glTranslatef(1.5, 0.0, -6.0);
   glRotatef(rota, 0.0, 0.0, -1.0);
   glVertexPointer(3, GL_FLOAT, 0, squareVertices);
   glEnableClientState(GL_VERTEX_ARRAY);
   glColorPointer(4, GL_FLOAT, 0, squareColours);      // NEW
   glEnableClientState(GL_COLOR_ARRAY);                // NEW
   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
   glDisableClientState(GL_COLOR_ARRAY);               // NEW

There are three new lines of code. Let’s deal with them one-by-one:


  glColorPointer(4, GL_FLOAT, 0, squareColours);

This is in fact similar to the function which we call to set up our co-ordinate vertex array. The four parameters are:


  1.
     •Size - the number of colours in the array
  2.
     •Data Format - we’ve used GL_FLOAT here because our vertex array contains floating point numbers. You can also use bytes if you want to specify the colours in 0-255 format.
  3.
     •Stride - Again, this tells OpenGL to skip a number of bytes between each value if your data contains other information.
  4.
     •Array Points - where the data is stored.

Note that when specifying the data format, GL_FLOAT is the parameter format (an enumeration) telling OpenGL what format; GLfloat is the data type for declaring a floating point number for OpenGL.

OK, so that function call tells OpenGL where the data is and what format it is in. However, like the co-ordinate vertex array which tells OpenGL the co-ordinates of the object, we need to put OpenGL into the required “state” which will make OpenGL use our colours when rendering the object.

So this call:


   glEnableClientState(GL_COLOR_ARRAY);

This enables the appropriate state in the OpenGL engine. Instead of passing GL_VERTEX_ARRAY, we just tell OpenGL that it’s a colour array with GL_COLOR_ARRAY.

Next we simply draw the square as per normal. After the square has been drawn, we need to then disable the colour array. If we don’t, the next time we draw the triangle, it too will be coloured like the square. So we call:


  glDisableClientState(GL_COLOR_ARRAY);

This takes the colour array off the list of OpenGL’s current state. If we didn’t do this, the first call to drawView will have the triangle in blue, the second call to drawView will use the colour array to colour the triangle. However, there being only three vertices in the triangle’s co-ordinate array (triangleVerticies[]), it will only use the first three colours.

So, make the changes to drawView, adding those three new lines as shown above, then hit “Build and Go” and you’re display should like this:

5_627_c189fca22983172.jpg

If you like, you can turn off rotation (comment the glRotatef() function call) so you can see the relation of the square’s vertex array vertices with the colour array.

Shading
Notice how the square gradually goes from one colour to the next? OpenGL achieves this through shading. There are two shading models which can be used by OpenGL: GL_FLAT & GL_SMOOTH. What you’re seeing already is the GL_SMOOTH shading which is the default.

Just to show the difference, before the glLoadIdentity() for the square, insert the following line:


       glShadeModel(GL_FLAT);

The glShadeModel() function changes the OpenGL state to the flat shading model from the smooth shading model. Again, OpenGL changes it’s state and retains this state until you tell it otherwise so you could put that in the setupView method if you like. After doing a “Build and Go”, the shading of the square will change to the following:
5_627_dbe6693d3cb9a96.jpg

Let me explain what’s happening here.

The triangle is being rendered as per normal. Being a flat colour, shading does not affect the drawing of the triangle. With the square, you can clearly see now the two triangles which OpenGL uses to make up the square. Due to the flat shading model, OpenGL only uses the last colour for filling the each triangle, being squareColours[2] (blue) and squareColours[3] (grey). Please review the Square Primitives tutorial if you’re unsure why these two colours represent the last two points in rendering the two triangles which make up the square.

As a recap: GL_SMOOTH is smooth shading, which means that when it comes to filing the square, OpenGL takes the defined colour in our squareColours[] array for each vertex in our squareVertices[] array, and uses interpolation for each pixel in the square between the points to smoothly change the colour between each of the four points. In other words, it gives us that coloured square shown originally.

GL_FLAT uses the colour defined for the last vertex of the object and fills the entire primitive with that colour. Squares are made up of two triangles so we have the square coloured in two halves.

Conculsion
Well I hope this has been useful for you. In reality, you probably just want to leave the shading as GL_SMOOTH unless you’re doing one of those retro-3D games from the C64 days. GL_SMOOTH is the default so you don’t need to enable it.

Also, please note, that what you used above for the colour points is also used for texture mapping so I’ll be coming back to this in a tutorial or two.

Texture mapping is just around the corner now. I’m going to show you how to create a 3D object in the next tutorial. It will be flat coloured but that’s okay because we’ll texture map it in the following tutorial.

Here’s the finished code for today’s tutorial.

AppleCoder-OpenGLES-04.zip

The home of the tutorials is in the “Tutorials” section of the iphonedevsdk.com forums. Check out the thread there.

Until next time, hooroo!
Simon Maurice




Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Linking to these pages on other websites is permitted.

OpenGL ES 05 - Texture Mapping Our Square


OpenGL ES 05 - Texture Mapping Our Square


Disclaimer: This post and the whole blog is just a copy of iPhone-OpenGL-ES-tutorial-Series  (seems to have )written by Simon Maurice. This blog does NOT have a written permission or any kind of permission from the original author (Simon Maurice). Please use it at your own risk. If you have any complaints regarding any content of this blog, please let me know I will remove it right away. Just hoping that it would be helpful for people who are trying to learn OpenGL. Happy coding!



Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Source codes can be found here

Original tutorial starts from here onwards..


I’ve decided to bring forward texture mapping because it’s probably easier to texture map a single faced object rather than a multi-faced (or 3D object). Also, it seems this is where most iPhone OpenGL ES programmers seem to get a bit stuck so I’ll run through texture mapping now.

I know that I have skipped a lot of the detail of OpenGL in favour of enabling you to get objects on the screen and experiment with them rather than go through pages and pages of OpenGL history, differences between OpenGL ES and OpenGL etc etc. However, this time I am going to go through some of the technical details that I have skipped in the past.

That, coupled with the fact I need to cover quite a bit of detail, means that this is going to be a long tutorial.

Having said that, the majority of the code has to do with loading the texture into our program and getting it into the OpenGL engine so OpenGL can use it. It’s not complicated, it just requires a bit of work in the iPhone SDK.

Getting Ready for the Texture
Before we can use a texture, we need to load it into our application, format it for OpenGL, and then tell OpenGL where to find it. Once we have done that, the rest is as easy as colouring our square was in the last tutorial.

Fire up Xcode and open EAGLView.h in the editor. First of all we need to provide a variable which OpenGL requires. Add the following declaration:


   GLuint textures[1];

Obviously, this is an array of 1 GLuint. You’ve seen me use GLfloat before and, once again, GLuint is just an OpenGL connivence typedef for an unsigned integer. You should always use the GLxxxx typedefs rather than the Objective C types because the OpenGL typedefs have been defined for the OpenGL implementation, not the development environment.

Later on, we will call the OpenGL function glGenTextures() to populate this variable. Just remember you’ve defined it for now and we’ll cover glGenTextures() and this variable later on.

Down in the method prototypes, add the following method prototype:

- (void)loadTexture;

This is where we’re going to put the code to actually load the texture.

Add CoreGraphics Framework to Your Project
In order to load the texture and process it, we will use the CoreGraphics framework as it provides all the methods we need without needing to write all that low level code you see in Windows OpenGL tutorials.

In the Xcode “Groups & Files” side bar, right click on the “Frameworks” group and choose Add -> Existing Frameworks...

In the search box, enter “CoreGraphics.framework” and look for the folder in the results which matches your application target (iPhone SDK 2.2.1 in my case). Click on the folder, and add it to your project (the folder icon for the framework is fine.

Next, we need to add the texture image to our project so it is included in the application’s bundle. Download the texture checkerplate.png and save it to your project directory. Add the image to your project’s Resources group by right clicking on the Resources group and selecting Add -> Existing Files... Choose the image and it should appear in the resources group.

Loading the Texture into Our Application and OpenGL
Switch now to EAGLView.m and we’ll implement the loadTexture method.

- (void)loadTexture {


}

The following code all goes sequentially in this method so just keep adding each line after the other. The first thing we need to do is to get the image into our application by using the following code:

CGImageRef textureImage = [UIImage imageNamed:@"checkerplate.png"].CGImage;
if (textureImage == nil) {
   NSLog(@"Failed to load texture image");
   return;
}

A CGImageRef is a CoreGraphics data type which collects all the information about the image. To get this information all we do is use the UIImage class method imageNamed: which creates an autorelease’d UIImage finding the file by it’s name in our Application’s main bundle. UIImage automatically creates the CGImageRef and is accessible by the UIImage property CGImage.

Now, we just need to get the size of the image for later reference:


   NSInteger texWidth = CGImageGetWidth(textureImage);
   NSInteger texHeight = CGImageGetHeight(textureImage);

The CGImageRef data contains the image’s width and height but we can’t access it directly, we need to use the above two accessor functions.

The CGImageRef, just like the data type’s name suggests, does not hold the image data, only a reference to the image’s data. So we need to allocate some memory to hold the actual image data:


     GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);

The correct amount of data to allocate is the width multiplied by the height, multiplied by 4. Remember from the last tutorial that OpenGL only accepts RGBA values? Each pixel is 4 bytes in size, one byte for each of the RGBA values.

Now, we have some absolute mouthfuls of function calls:


   CGContextRef textureContext = CGBitmapContextCreate(
                   textureData,
                   texWidth,
                   texHeight,
                   8, texWidth * 4,
                   CGImageGetColorSpace(textureImage),
                   kCGImageAlphaPremultipliedLast);


       CGContextDrawImage(textureContext,
                  CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight),
                  textureImage);


       CGContextRelease(textureContext);

Firstly, as the function name suggests, this is a CoreGraphics function that returns a Quartz2D graphics context reference. Basically what we’re doing is pointing CoreGraphics at our texture data and telling it the format and size of our texture.

Then, we actually draw the image into our allocated data (textureData pointer) from the data pointed to context reference we created before. This context contains all the information it needs to copy the data into our malloc()’d space in the right format for OpenGL.

We’re really finished now with CoreGraphics and we can release the textureContext handle which we created.

I know I’ve sped through the above code, but we’re more interested in the OpenGL side of things. You can reuse that code for any PNG format graphics texture that you add to your project in this way.

Now, onto the OpenGL programming.

Now, remember that variable we declared originally in the header file? We are now going to use it. Have a look at the next line of code:


       glGenTextures(1, &textures[0]);

We are going to copy the texture data from our application into the OpenGL engine so we need to tell OpenGL to allocate memory for it (we can’t do it directly). Remember textures[] was defined as a GLuint? Once we call glGenTextures, OpenGL creates a “handle” or “pointer” which is a unique reference to each individual texture we load into OpenGL. The value that OpenGL returns to us isn’t important to us, just every time we want to refer to this checkerplate.png texture, we just need to refer to textures[0]. We know what we’re talking about and so does OpenGL.

We can allocate space for multiple textures at one time. For example, if we needed 10 textures for our application, we can do the following:


   GLuint textures[10];
   glGenTextures(10, &textures[0]);

For this example, we only need one texture so we’re allocating one.

Next we need to activate the texture which we just generated:


       glBindTexture(GL_TEXTURE_2D, textures[0]);

The second parameter is obvious, it’s the texture we just created. The first parameter is always GL_TEXTURE_2D because that’s all OpenGL ES accepts at this point. “Full” OpenGL allows for 1D and 3D textures but I’m sure this is still required in OpenGL ES for future compatibility.

Just remember to use it to activate textures.

Next, we send our texture data (pointed to by textureData) into OpenGL. OpenGL manages the texture data over on “it’s” side (the server side) so the data is converted in the required format for the hardware implementation, and copied into OpenGL’s space. It’s a bit of a mouthful but most parameters will always be the same due to the limitations of OpenGL ES:


   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);

Going through the parameters, they are:


  1.
     •target - basically, this is always GL_TEXTURE_2D
  2.
     •level - specifies the level of detail of the texture. 0 means the full detail 
the image allows, higher numbers goes into nth level mipmap image reduction
  3.
     •internal_format - the internal format and format listed below must be the same. Hence GL_RGBA for both.
  4.
     •width - width of the image
  5.
     •height - height of the image
  6.
     •border - must always be set to 0 as OpenGL ES does not support texture borders.
  7.
     •format - must be the same as internal_format
  8.
     •type - the type of each pixel. Remember there were four bytes to a pixel? 
Therefore each pixel is made of 1 unsigned byte (RGBA remember).
  9.
     •pixels - point to the actual image data

So, while there are quite a few parameters, most are either common sense, always the same, or just require you to type in the variables you defined previously (textureData, texWidth, & texHeight). And just remember all you’re doing is handing control of you’re texture data over to OpenGL.

Now that you’ve passed the data to OpenGL, you can free the textureData that we allocated earlier:


      free(textureData);

There are only three more function calls to make:


   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glEnable(GL_TEXTURE_2D);

These three calls just make final settings to OpenGL and then puts OpenGL in the texture mapping “state”.

The first two calls tell OpenGL how to process the textures when magnifying (up close - GL_TEXTURE_MAG_FILTER) and minimising (far away - GL_TEXTURE_MIN_FILTER). You do need to specify at least one of these for texture mapping to work and the GL_LINEAR option has been set for both.

Finally, we just call glEnable() to ask OpenGL to use textures when you tell it to in the drawing code.

Finally, we need to add a call to this method within the initWithCoder initialiser.


       [self setupView];
       [self loadTexture];// Add this line

Just add the second line after the call to the setupView method.

Adjustments to drawView
That’s the hard work done. Changes to drawView method are no harder than colouring a the square from the previous tutorial. First, comment out the squareColours[] array as we won’t use it.

Now, remember when we were colouring the square, for each vertex of the square, we provided a colour value. When it comes to texture mapping, we need to do exactly the same thing but instead of telling OpenGL the colour for each vertex, we tell OpenGL what co-ordinate of the texture corresponds to that vertex.

Before we can do that, we need to know what are the co-ordinates of the texture. OpenGL locates the origin of a texture (0, 0) at the lower left, with increasing values from 0 -> 1 along each axis. Have a look at the following image of our texture:

5_627_bbe0d7e04c0c9b9.png

Refer this back to our squareVertices[].

const GLfloat squareVertices[] = {
       -1.0, 1.0, 0.0,               // Top left
       -1.0, -1.0, 0.0,              // Bottom left
       1.0, -1.0, 0.0,               // Bottom right
       1.0, 1.0, 0.0                 // Top right
   };

Can you see that the first texture co-ordinate we need to specify is for the top left of the texture? That would be texture co-ordinate (0, 1). Our second vertex is the bottom left of the square, therefore it is texture co-ordinate (0, 0). We then go to the bottom right and that’s texture co-ordinate (1, 0), finally ending on the top right we end on texture co-ordinate (1, 1). Thus, we specify the squareTextureCoords[] as follows:


   const GLshort squareTextureCoords[] = {
       0, 1,       // top left
       0, 0,       // bottom left
       1, 0,       // bottom right
       1, 1        // top right
   };

Note we have used GLshort instead of GLfloat for this. Add the above code to your project.

Can you see how this is similar to what we did with the colour array?

Right, now we need to modify the drawing code. Leave the triangle drawing code as is and start from the glLoadIdentity() before the square drawing code. The square drawing code now looks like the following:


   glLoadIdentity();
   glColor4f(1.0, 1.0, 1.0, 1.0);      // NEW
   glTranslatef(1.5, 0.0, -6.0);
   glRotatef(rota, 0.0, 0.0, 1.0);
   glVertexPointer(3, GL_FLOAT, 0, squareVertices);
   glEnableClientState(GL_VERTEX_ARRAY);


   glTexCoordPointer(2, GL_SHORT, 0, squareTextureCoords);     // NEW
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);                // NEW


   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);               // NEW

OK, there are four new lines of code, and I’ve deleted the code for colouring the square from the previous tutorial. The first line is a call to glColor4f() which I’ll cover in detail below.

The next three should be quite familiar to you by now. Instead of referring to object vertices or colours, we are just referring to textures instead.


   glTexCoordPointer(2, GL_SHORT, 0, squareTextureCoords);     // NEW
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);                // NEW

The first call is to tell OpenGL where our texture co-ordinate array is stored and what format it is in. The difference is that we say there are 2 values for each co-ordinate (it’s a 2D texture of course), the data type we used was a GLushort which translates to GL_SHORT here, there is no stride (0), and the pointer to our co-ordinates.

Next we just tell OpenGL to enable the client state for texture mapping with the co-ordinate array we’ve just specified.

Next the unchanged glDrawArrays() is called before:


   glDisableClientState(GL_TEXTURE_COORD_ARRAY);               // NEW

Remember when we were colouring the square differently to the triangle we turned off the colour array? Again, we need to do this for texture mapping otherwise OpenGL will use the texture for the triangle.

Make the changes to the code and hit “Build and Go”, you should get the following:

5_627_57e9a43a66fec3b.jpg

Our checkerplate texture in now mapped onto the square and the triangle is as per normal.

Further Experimentation
First of all, let me talk about the new glColor4f() line which we added to the square drawing code:


  glColor4f(1.0, 1.0, 1.0, 1.0);      // NEW

This of course changes the drawing colour to white, fully opaque. Can you guess why I added this line? OpenGL is of course a “state” machine so once we set something, it stays in that state until we tell it otherwise. So the colour was set as the blue until we made it white.

OK, now when texture mapping, OpenGL performs a multiplication between the current colour set (the blue) and the current texture pixel. That is:
                          R    G     B    A
   Colour Set:           0.0, 0.0, 0.8, 1.0
   Texture Pixel Colour: 1.0, 1.0, 1.0, 1.0

So, when OpenGL draws that pixel, it multiples


       Colour_Red * Pixel_Colour_Red = Rendered_colour
      0.0      *     1.0              = 0.0
   Colour_Green * Pixel_Colour_Green
      0.0      *     0.0              = 0.0
    Colour_Blue * Pixel_Colour_Blue
      0.8      *     1.0              = 0.8

Comment out that glColor4f() before the square drawing code, you should get something like this:

5_627_1b956c5df9c5994.jpg

When we had white, the multiplation would have been:

Set Colour : 1.0, 1.0, 1.0, 1.0
                 is mulitplied by
Pixel Colour : 0.8, 0.8, 0.8, 1.0


        Result: 0.8, 0.8, 0.8, 1.0

So that’s why we need to set the colour as white.

OK, That’s It!
That will do for this tutorial, I know I’ve covered a lot but I hope you can see that the actual texture mapping code is not really significant, it’s more the loading and setting up the texture that really takes the time. Next time, we’re off into texture mapped 3D objects, blending and other fun stuff.

As usual, here’s the code and you can email me with any questions.

AppleCoder-OpenGLES-05.zip

The home of the tutorials is in the “Tutorials” section of the iphonedevsdk.com forums. Check out the thread there.

Until next time, hooroo!
Simon Maurice

Copyright 2009 Simon Maurice. All Rights Reserved.
The code provided in these pages are for educational purposes only and may not be used for commercial purposes without Simon Maurice’s expressed permission in writing. Information contained within this site cannot be duplicated in any form without Simon Maurice’s expressed permission in writing; this includes, but is not limited to, publishing in printed format, reproduced on web pages, or other forms of electronic distribution.

Linking to these pages on other websites is permitted.