OpenGL Introduction

By Nicholas Duchon.

These notes are based on the OpenGL Game template in Xcode 5.

Graphics frameworks

Framework
Link to reference
Comments.
UIKit
UIKit Framework Reference Draw images, animate along paths
Core Graphics
Core Graphics Framework Reference
Quartz 2D Programming Guide: Introduction
Path-based animation,
drawing and image rendering
Core Animation
Core Animation Programming Guide:
Core Animation Reference Collection
The animation part of Quartz 2D
Core Image
Core Image Reference Collection Image processing and feature detection
OpenGL ES
OpenGL ES Programming Guide for iOS:
OpenGL ES Framework Reference
3D graphics pipeline configuration
GL Kit
GLKit Framework Reference Objective-C interface to OpenGL (partial)
Text Kit
Text Programming Guide for iOS:
Display, select and edit text
Core Text
Core Text Programming Guide:
Core Text Reference Collection
Text layout and fonts - low level
Image I/O
Image I/O Reference Collection Image I/O, like it says
Assets
Assets Library Framework Reference Access pictures and video from Photos app
Spite Kit
Sprite Kit Programming Guide:
code:Explained Adventure: Introduction
Basic elements of creating a animated game
Cool example.

When you run the template project, you see the following:



The original vertex data array:

I will experiment with object definition for a while, starting with the following code - the cube specification from viewController.m file, lines 30-75.
(You can turn on line numbers in Xcode by going to Xcode --> Preferences --> Text Editing --> Show: Line Numbers.)

You can use the following code to compute the number of vertices and the size of the array, AFTER you have declared the array without a size specification:

    int sB = sizeof (gCubeVertexData);   // size of array in bytes
    int se = sizeof(gCubeVertexData[0]);
// size of an entry in bytes, float is typically 4 bytes
   
    int pointsInCube = sB / se / 6;      // divide by 6 since 6 values per vertex, xyz location, xyz normals

GLfloat gCubeVertexData[] = // ND: I removed the 216 here - the compiler will infer the size, which is better than declaring it
{
    // Data layout for each line below is:
    // positionX, positionY, positionZ,     normalX, normalY, normalZ,
    .5f, -0.5f, -0.5f,        1.0f, 0.0f, 0.0f,
    .5f, 0.5f, -0.5f,         1.0f, 0.0f, 0.0f,
    .5f, -0.5f, 0.5f,         1.0f, 0.0f, 0.0f,

    .5f, -0.5f, 0.5f,         1.0f, 0.0f, 0.0f,
    .5f, 0.5f, -0.5f,          1.0f, 0.0f, 0.0f,
    .5f, 0.5f, 0.5f,         1.0f, 0.0f, 0.0f,
   
    0.5f, 0.5f, -0.5f,         0.0f, 1.0f, 0.0f,
    -0.5f, 0.5f, -0.5f,        0.0f, 1.0f, 0.0f,
    0.5f, 0.5f, 0.5f,          0.0f, 1.0f, 0.0f,

    0.5f, 0.5f, 0.5f,          0.0f, 1.0f, 0.0f,
    -0.5f, 0.5f, -0.5f,        0.0f, 1.0f, 0.0f,
    -0.5f, 0.5f, 0.5f,         0.0f, 1.0f, 0.0f,
   
    -0.5f, 0.5f, -0.5f,        -1.0f, 0.0f, 0.0f,
    -0.5f, -0.5f, -0.5f,       -1.0f, 0.0f, 0.0f,
    -0.5f, 0.5f, 0.5f,         -1.0f, 0.0f, 0.0f,

    -0.5f, 0.5f, 0.5f,         -1.0f, 0.0f, 0.0f,
    -0.5f, -0.5f, -0.5f,       -1.0f, 0.0f, 0.0f,
    -0.5f, -0.5f, 0.5f,        -1.0f, 0.0f, 0.0f,
   
    -0.5f, -0.5f, -0.5f,       0.0f, -1.0f, 0.0f,
    0.5f, -0.5f, -0.5f,        0.0f, -1.0f, 0.0f,
    -0.5f, -0.5f, 0.5f,        0.0f, -1.0f, 0.0f,

    -0.5f, -0.5f, 0.5f,        0.0f, -1.0f, 0.0f,
    0.5f, -0.5f, -0.5f,        0.0f, -1.0f, 0.0f,
    0.5f, -0.5f, 0.5f,         0.0f, -1.0f, 0.0f,
   
    0.5f, 0.5f, 0.5f,          0.0f, 0.0f, 1.0f,
    -0.5f, 0.5f, 0.5f,         0.0f, 0.0f, 1.0f,
    0.5f, -0.5f, 0.5f,         0.0f, 0.0f, 1.0f,

    0.5f, -0.5f, 0.5f,         0.0f, 0.0f, 1.0f,
    -0.5f, 0.5f, 0.5f,         0.0f, 0.0f, 1.0f,
    -0.5f, -0.5f, 0.5f,        0.0f, 0.0f, 1.0f,
   
    0.5f, -0.5f, -0.5f,        0.0f, 0.0f, -1.0f,
    -0.5f, -0.5f, -0.5f,       0.0f, 0.0f, -1.0f,
    0.5f, 0.5f, -0.5f,         0.0f, 0.0f, -1.0f,

    0.5f, 0.5f, -0.5f,         0.0f, 0.0f, -1.0f,
    -0.5f, -0.5f, -0.5f,       0.0f, 0.0f, -1.0f,
    -0.5f, 0.5f, -0.5f,        0.0f, 0.0f, -1.0f
};

Structure and meaning:

Experimenting

Just one triangle

GLfloat gCubeVertexData[] =
{
    // Data layout for each line below is:
    // positionX, positionY, positionZ,     normalX, normalY, normalZ,
//  x   y   x  nx ny nz
    1,  1,  1,  1, 0, 0,
    1,  1, -1,  1, 0, 0,
    1, -1,  1,  1, 0, 0
};



To change the magnification, change the location of the viewer as follows:
In the "update" method, 
Change 65 to some other number. The number I used to make the video is 125. Bigger numbers put the camera viewpoint further away, making the figures smaller, while smaller numbers bring the camer closer.
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(125), aspect, 0.1f, 100.0f);

For some fun, what does the following set of points specify?

GLfloat gCubeVertexData[] =
{
    // Data layout for each line below is:
    // positionX, positionY, positionZ,     normalX, normalY, normalZ,
//  x   y   x  nx ny nz
    1, -1, -1,  1, 0, 0,
    1,  1, -1,  1, 0, 0,
    1, -1,  1,  1, 0, 0,

    1, -1,  1,  1, 0, 0,
    1,  1, -1,  1, 0, 0,
    1,  1,  1,  1, 0, 0,
};

Animation

The system can be configured using the property preferredFramesPerSecond in the GLKViewController class. Default is 30, but the actual frame rate depends on the capabilties of the device.

If your class extends GLKViewController, as does the class ViewController in the template, you can just say:
self.preferredFramesPerSecond = 20; // or something similar.

Once that is set, the system will generate events at that rate. The next question is how to handle the events.

The documentation is not easy to find, and I am still not clear how the compiler actually finds the key method, but the recommended method name in a class that extends GLKViewController is
-(void) update
.
You can see an example of this method in the ViewController.m file.

For documentation of the update method, you can look in the GLKViewController.h file (in the GLKit.Framework folder of an Xcode project), lines 86-90 as comments:
/*
 Required method for implementing GLKViewControllerDelegate. This update method variant should be used
 when not subclassing GLKViewController. This method will not be called if the GLKViewController object
 has been subclassed and implements -(void)update.
 */
- (void)glkViewControllerUpdate:(GLKViewController *)controller;

You can also find a reference to the update method in the reference page for the class GLKViewController - Subclassing Notes.