Getting Started

Create a new project in Xcode and select the iOS\Application\Empty Application Template.
We’re selecting the Empty Application template (not the OpenGL Game template!) so you can put everything together from scratch and get a better idea how everything fits together.
Set the Product Name to HelloGLKit,
add QuartzCore, OpenGLES, GLKit frameworks to projects

and at the top of the AppDelegate.h file import the <GLKit/GLKit.h> header file for GLKit

Next switch to AppDelegate.m, modify the application:didFinishLaunchingWithOptions to add a GLKView as a subview of the main window

The lines marked with comments are the new lines – so let’s go over them one by one.

1. Create a OpenGL context.
To do anything with OpenGL, you need to create a EAGLContext.

An EAGLContext manages all of the information iOS needs to draw with OpenGL. It’s similar to how you need a Core Graphics context to do anything with Core Graphics.

When you create a context, you specify what version of the API you want to use. Here, you specify that you want to use OpenGL ES 2.0. If it is not available (such as if the program were run on an iPhone 3G), the app would terminate.

2. Create a GLKView.
This creates a new instance of a GLKView, and makes it as large as the entire window.

3. Set the GLKView’s context.
When you create a GLKView, you need to tell it the OpenGL context to use, so we specify the one we already created.

4. Set the GLKView’s delegate.
This sets the current class (AppDelegate) as the GLKView’s delegate.
This means whenever the view needs to be redrawn, it will call a method named glkView:drawInRect on whatever class you specify here. We will implement this inside the App Delegate shortly to contain some basic OpenGL commands to paint the screen red.

5. Add the GLKView as a subview.
This line adds the GLKView as a subview of the main window.
Since we marked the App Delegate as GLKView’d delegate, we need to mark it as implementing the GLKViewDelegate protocol.
So switch to AppDelegate.h and modify the @interface line

One step left! Switch back to AppDelegate.m, add the code right before the @end

The first line calls glClearColor to specify the RGB and alpha (transparency) values to use when clearing the screen. We set it to red here.

The second line calls glClear to actually perform the clearing.
Remember that there can be different types of buffers, such as the render/color buffer we’re displaying, and others we’re not using yet such as depth or stencil buffers. Here we use the GL_COLOR_BUFFER_BIT to specify what exactly to clear – in this case, the current render/color buffer.
Updating the GLKView, to update our GLKView periodically, we make the screen pulse from red to black, kind of like a “Red Alert” effect!

top of AppDelegate.m, modify the @implementation line to add two private variables

And initialize variables in application:didFinishLaunchingWithOptions

Then go to the glkView:drawInRect method and update it

Every time drawInRect is called, it updates the _curRed value a little bit based on whether it’s increasing or decreasing.

Note that this code isn’t perfect, because it doesn’t take into effect how long it takes between calls to drawInRect. This means that the animation might be faster or slower based on how quickly drawInRect is called.
synchronize the time we render with OpenGL to the rate at which the screen refreshes.

By default, the GLKView only updates itself on an as-needed basis – i.e. when views are first shown, the size changes, or the like. However for game programming, you often need to redraw every frame!

We can disable this default behavior of GLKView by setting enableSetNeedsDisplay to false. Then, we can control when the redrawing occurs by calling the display method on GLKView whenever we want to update the screen.

Ideally we would like to synchronize the time we render with OpenGL to the rate at which the screen refreshes.

Luckily, Apple provides an easy way for us to do this with CADisplayLink! It’s really easy to use so let’s just dive in.

First add the QuartzCore.h import to the top of AppDelegate.m

Then add CADisplayLink to application:didFinishLaunchingWithOptions

Then add a new render function
remove meaningless annotate
Try out GLKViewController

Modify application:didFinishLaunchingWithOptions

1. Create a GLKViewController. This creates a new instance of a GLKViewController programatically. In this case, it has no XIB associated.

2. Set the GLKViewController’s view. The root view of a GLKViewController should be a GLKView, so we set it to the one we already created.

3. Set the GLKViewController’s delegate. We set the current class (AppDelegate) as the delegate of the GLKViewController.
This means that the GLKViewController will notify us each frame so we can run game logic, or when the game pauses (a nice built-in feature of GLKViewController we’ll demonstrate later).

4. Set the preferred FPS. The GLKViewController will call your draw method a certain number of times per second. This number gives a hint to the GLKViewController how often you’d like to be called. Of course, if your game takes a long time to render frames, the actual number may be lower than this.

The default value is 30 FPS. Apple’s guidelines are to set this to whatever your app can reliably support to the frame rate is consistent and doesn’t seem to stutter. This app is very simple so can easily run at 60 FPS, so we set it to that.

Also as an FYI, if you want to see the actual number of times the OS will attempt to call your update/draw methods, check the read-only framesPerSecond property.

5. Set the rootViewController. We want this view controller to be the first thing that shows up, so we add it as the rootViewController of the window. Note that we no longer need to add the view as a subview of the window manually, because it’s the root view of the GLKViewController.

Notice that we no longer need the code to run the render loop and tell the GLView to refresh each frame – GLKViewController does that for us in the background! So go ahead and comment out the render method as well.
Also remember that we set the GLKViewController’s delegate to the current class (AppDelegate), so let’s mark it as implementing GLKViewControllerDelegate.
Switch to AppDelegate.h and replace the @implementation with the following line
@interface AppDelegate : UIResponder <UIApplicationDelegate, GLKViewDelegate, GLKViewControllerDelegate>

The final step is to update the glkView:drawInRect method, and add the implementation for GLKViewController’s glkViewControllerUpdate callback

Note that we moved the code to change the current color from the draw method (where it didn’t really belong) to the update method (intended for game/app logic).

Also notice that we changed the amount the red color increments from a hardcoded value to a calculated value, based on the amount of time since the last update. This is nice because it guarantees the animation will always proceed at the same speed, regardless of the frame rate.

This is another of those convenient things GLKViewController does for you! We didn’t have to write special code to store the time since the last update – it did it for us!
GLKViewController and Storyboards

it’s much better to leverage the power of Storyboards, so you can include this view controller anywhere you want in your app hierarchy!

So let’s do a little refactoring to accomplish that. First, let’s create a subclass of GLKViewController that we can use to contain our app’s logic. So create a new file with the iOS\Cocoa Touch\GLKViewController subclass template, name the class HelloGLKitViewController, as a subclass of GLKViewController.

Open up HelloGLKitViewController.m, and start by adding a private category on the class to contain the instance variables we need, and a new property to store the context

Then implement viewDidLoad and viewDidUnload

In viewDidLoad, we create an OpenGL ES 2.0 context (same as we did last time in the App Delegate) and squirrel it away. Our root view is a GLKView (we know this because we set it up this way in the Storyboard editor), so we cast it as one. We then set its context to the OpenGL context we just created.

Note that we don’t have to set the view controller as the view’s delegate – GLKViewController does this automatically behind the scenes.

In viewDidUnload, we just do the opposite to clean up. We have to make sure there’s no references left to our context, so we check to see if the current context is our context, and set it to nil if so. We also clear out or reference to it.
At the bottom of the HelloGLKitViewController.m, add the implementations of the glkView:drawInRect and update callbacks, similar to before

Note that the update method is called plain “update”, because now that we’re inside the GLKViewCotroller we can just override this method instead of having to set a delegate. Also the timeSinceLastUpdate is access via “self”, not a passed in view controller.
create the Storyboard

Create a new file with the iOS\User Interface\Storyboard template, choose iPhone for the device family, and save it as MainStoryboard.storyboard.
Open MainStoryboard.storyboard, and from the Objects panel drag a View Controller into the grid area. Select the View Controller, and in the Identity Inspector set the class to HelloGLKitViewController
Also, select the View inside the View Controller, and in the Identity Inspector set the Class to GLKView.

To make this Storyboard run on startup, open HelloGLKit-Info.plist, control-click in the blank area, and select Add Row. From the dropdown select Main storyboard file base name, and enter MainStoryboard
Clean up old code

we still have some old code in AppDelegate that we need to clean up. Start by deleting the _curRed and _increasing instance variables from AppDelegate.m. Also delete the glkView:drawInRect and glkViewControllerUpdate methods.
And delete pretty much everything from application:didFinishLaunchingWithOptions so it looks like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    return YES;
}

And modify the AppDelegate @interface to strip out the two GLKit delegates since we aren’t using those anymore:
@interface AppDelegate : UIResponder <UIApplicationDelegate>
GLKViewController and Pausing

add the pausing feature to the bottom of HelloGLKitViewController.m

Compile and run the app, and now whenever you tap the animation stops! Behind the scenes, GLKViewController stops calling your update method and your draw method. This is a really handy way to implement a pause button in your game.

In addition to that, GLKViewController has a pauseOnWillResignActive property that is by default set to YES. This means when the user hits the home button or receives an interruption such as a phone call, your game will be automatically paused! Similarly, it has a resumeOnDidBecomeActive property that is by default set to YES, which means when the user comes back to your app, it will automatically unpause. Handy, that!

timeSinceLastDraw gives you the elapsed time since the last call to the draw method. Note this might be different than timeSinceLastUpdate, since your update method takes time!
timeSinceFirstResume gives you the elapsed time since the first time GLKViewController resumed sending updates. This often means the time since your app launched, if your GLKViewController is the first thing that shows up.
timeSinceLastResume gives you the elapsed time since the last time GLKViewController resumed sending updates. This often means the last time your game was unpaused.

Let’s add some code to try these out, Add the following code to the top of touchesBegan
NSLog(@"timeSinceLastUpdate: %f", self.timeSinceLastUpdate);
NSLog(@"timeSinceLastDraw: %f", self.timeSinceLastDraw);
NSLog(@"timeSinceFirstResume: %f", self.timeSinceFirstResume);
NSLog(@"timeSinceLastResume: %f", self.timeSinceLastResume);
Creating Vertex Data for a Simple Square

When you render geometry with OpenGL, keep in mind that it can’t render squares – it can only render triangles.
However we can create a square with two triangles, one triangle with vertices (0, 1, 2), and one triangle with vertices (2, 3, 0).

One of the nice things about OpenGL ES 2.0 is you can keep your vertex data organized in whatever manner you like. Open up HelloGLKitViewController.m and create a plain old C-structure and a few arrays to keep track of our square information

So basically we create:
a structure to keep track of all our per-vertex information (currently just color and position)
an array with all the info for each vertex
an array that gives a list of triangles to create, by specifying the 3 vertices that make up each triangle
Creating Vertex Buffer Objects

The best way to send data to OpenGL is through something called Vertex Buffer Objects.

Basically these are OpenGL objects that store buffers of vertex data for you. You use a few function calls to send your data over to OpenGL-land.

There are two types of vertex buffer objects – one to keep track of the per-vertex data (like we have in the Vertices array), and one to keep track of the indices that make up triangles (like we have in the Indices array).

So first add the instance variables to private HelloGLKitViewController category

Then add a method above viewDidLoad to create the setupGL function

That it’s pretty simple. The first thing it does is set the current OpenGL context to the current context. This is important in case some other code has changed the global context.

It then calls glGenBuffers to create a new Vertex Buffer object, glBindBuffer to tell OpenGL “hey when I say GL_ARRAY_BUFFER, I really mean vertexBuffer”, and glBufferData to send the data over to OpenGL-land.

Also add a new method tearDownGL to delete the vertex and index buffers:

Then add [self setupGL] to the bottom of viewDidLoad

And add [self tearDownGL] inside viewDidUnload, right after the call to [super viewDidUnload]
Create a GLKBaseEffect

Usually you create one of these when you create your OpenGL context. You can (and should) re-use the same GLKBaseEffect for different geometry, and just reset the properties. Behind the scenes, GLKBaseEffect will only propagate the properties that have changed to its shaders.

Up in private HelloGLKitViewController category, add a property for a GLKBaseEffect

And synthesize it after the @implementation below

Then in setupGL, initialize it right after calling [EAGLContext setCurrentContext:...]

And set it to nil at the bottom of tearDownGL
Set GLKBaseEffect properties

The first property we need to set is the projection matrix.

GLKit provides you with some handy functions to set up a projection matrix. The one we’re going to use allows you to specify the field of view along the y-axis, the aspect ratio, and the near and far planes

The field of view is similar to camera lenses. A small field of view (for example 10) is like a telephoto lens – it magnifies images by “pulling” them closer to you. A large field of view (for example 100) is like a wide angle lens – it makes everything seem farther away. A typical value to use for this is around 65-75.

The aspect ratio is the aspect ratio you want to render to (i.e. the aspect ratio of the view). It uses this in combination with the field of view (which is for the y-axis) to determine the field of view along the x-axis.

The near and far planes are the bounding boxes for the “viewable” volume in the scene. So if something is closer to the eye than the near plane or further away than the far plane, it won’t be rendered. This is a common problem to run into – you try and render something and it doesn’t show up. One thing to check is that it’s actually between the near and far planes.

Let’s try this out – add the code to the bottom of update

In the first line, we get the aspect ratio of the GLKView.

In the second line, we use a built in helper function in the GLKit math library to easily create a perspective matrix for us – all we have to do is pass in the parameters discussed above. We set the near plane to 4 units away from the eye, and the far plane to 10 units away.

In the third line, we just set the projection matrix on the effect’s transform property!

We need to set one more property now – the modelViewMatrix. The modelViewMatrix is the transform that is applied to any geometry that the effect renders.

The GLKit math library once again comes to the rescue here with some really handy functions that make performing translations, rotations, and scales easy,

Back to where we set up the vertices for the square, remember that the z-coordinate for each vertex was 0. If we tried to render it with this perspective matrix, it wouldn’t show up because it’s closer to the eye than the near plane!

In second section, so the first thing we need to do is to move this backwards.
So in the first line, we use the GLKMatrix4MakeTranslation function to create a matrix for us that translates 6 units backwards.

Next, we want to make the cube rotate for fun. So we increment an instance variable that keeps track of the current rotation , and use the GLKMatrix4Rotate method to modify the current transformation by rotating it as well. It takes radians, so we use the GLKMathDegreesToRadians method to that conversion. Yes, this math library has just about every matrix and vector math routine you’ll need!

Finally, we set the model view matrix on the effect’s transform property.

Add the rotation instance variable to HelloGLKitViewController’s private category
Call prepareToDraw on the GLKBaseEffect

Just remember that you need to call this after any time you change properties on a GLKBaseEffect, before you draw with it.
Enable pre-defined attributes, passing on the position and color data to the GLKBaseEffect

If you’ve programmed with OpenGL ES 2.0 before this will look familiar to you, but if not let me explain.

Every time before you draw, you have to tell OpenGL which vertex buffer objects you should use. So here we bind the vertex and index buffers we created earlier.
Strictly, we didn’t have to do this for this app (because they’re already still bound from before) but usually you have to do this because in most games you use many different vertex buffer objects.

Next, we have to enable the pre-defined vertex attributes we want the GLKBaseEffect to use. We use the glEnableVertexAttribArray to enable two attributes here
– one for the vertex position, and one for the vertex color. GLKit has predefined constants we need to use for these – GLKVertexAttribPosition adn GLKVertexAttribColor.

Next, we call glVertexAttribPointer to feed the correct values to these two input variables for the vertex shader.
This is a particularly important function so let’s go over how it works carefully.

The first parameter specifies the attribute name to set. We just use the predefined constants GLKit set up.

The second parameter specifies how many values are present for each vertex. If you look back up at the Vertex struct, you’ll see that for the position there are three floats (x,y,z) and for the color there are four floats (r,g,b,a).

The third parameter specifies the type of each value – which is float for both Position and Color.

The fourth parameter is always set to false.

The fifth parameter is the size of the stride, which is a fancy way of saying “the size of the data structure containing the per-vertex data”. So we can simply pass in sizeof(Vertex) here to get the compiler to compute it for us.

The final parameter is the offset within the structure to find this data. We can use the handy offsetof operator to find the offset of a particular field within a structure.
Draw your geometry

The first parameter specifies the manner of drawing the vertices. There are different options you may come across in other tutorials like GL_LINE_STRIP or GL_TRIANGLE_FAN, but GL_TRIANGLES is the most generically useful (especially when combined with VBOs) so it’s what we cover here.

The second parameter is the count of vertices to render. We use a C trick to compute the number of elements in an array here by dividing the sizeof(Indices) (which gives us the size of the array in bytes) by sizeof(Indices[0]) (which gives us the size of the first element in the arary).

The third parameter is the data type of each individual index in the Indices array. We’re using an unsigned byte for that so we specify that here.

From the documentation, it appears that the final parameter should be a pointer to the indices. But since we’re using VBOs it’s a special case – it will use the indices array we already passed to OpenGL-land in the GL_ELEMENT_ARRAY_BUFFER.