iOS developers often don’t have an OpenGL background, and most of the ones I work with like the idea of OpenGL, but feel they don’t have the time to learn and master it. However, the combination of “new API (OpenGL ES 2)” with “Apple’s helper classes (GLKit)” makes OpenGL development on mobile suprisingly fast and easy.

iOS 5.0, iOS 6.0, and GLKit

iOS 7.0…

It’s not live yet, and I’d hoped Apple might update GLKit to fix some of the holes below. I don’t know what will be in the final iOS 7 release, but I get the impression GLKit hasn’t changed yet. If so, everything that follows applies equally to iOS 7.

Summary of Apple’s GLKit and where it helps/hinders

Porting GL ES 1.x code

Full

Apple provided a good, easy-to-use set of classes to make it trivial to port GL ES 1.x code. The documentation is very poor, though.

More importantly: it prevents you from using Shaders, which are one of the easiest and most powerful parts of OpenGL (once you get up and running). So, we’ll be ignoring GL ES 1.x

Classes: anything with the text “Effect” in the class name (GLKBaseEffect, GLKEffectProperty, GLKNamedEffect, etc)

Vector math

Full

Every desktop OpenGL implementation assumes you have access to a good Vector Math library.

Until GLKit, Apple’s iOS was the exception: you had to make your own “vector” classes, you had to write all the Dot Product code, etc. (e.g. c.f. Jeff LaMarche’s first tutorial). Not any more :). Apple’s design here is good, and closely follows the conventions of their other frameworks (works the same way as CGRect, CGPoint etc from Quartz/CoreGraphics)

Structs: GLKVector2, GLKVector3, GLKVector4

Quaternions

Full

Quaternions have a bad rep. Many people find them incomprehensibly hard to understand/code, and yet … they are essential once you start “rotating 3D objects”.

Apple’s implementation of Quaternions is excellent: you don’t need to understand the mathematics, just use the pre-built methods

Matrix math

Full

Like Vector-math, Matrix math is tricky and time consuming to build for yourself and debug.
Apple’s done all of it, with an good set of methods.

Structs: GLKMatrix4, GLKMatrix3

OpenGL Projection

Partial (almost full)

OpenGL uses 4-dimensions to deal with 3-dimensional rendering. That could get difficult, fast. Skipping the reasons for it, OpenGL used to be hardcoded to a set of special matries (M, V, and P – model, view, and projection).

GL ES 2 threw away the hard-coded matrices, and says “do it all yourself” (which, as we’ll see later, actually makes things easier in the long run). This is a pain … except Apple’s done it for us. Don’t go writing your own MVP stack code – use Apple’s.

Before GLKit, you had to write long and complex methods, using CoreAnimation and Quartz, to convert “file.png” and upload it to the graphics chip as an “OpenGL texture”.

That code was hard to debug, and most iOS programmers aren’t familiar with CA/Quartz. Apple wrote a proper Objective-C texturing system that does the work of Quartz and y-flipping for you. For most “simple” code, this is perfect.

…but: they screwed up in a few places, some major bugs. When it works, it’s fine – and it only needs two lines of code! – so we’ll use it in the early articles, but we’ll throw it away and write a “fixed” version for the later articles.

There’s a lot of FUD on the web that says this is “impossible” or “slow” or … etc.

Don’t believe it. There are bugs in Apple’s CALayer / Quartz / CoreAnimation classes that make them slow *independent* of whether you’re running OpenGL. It’s just that the things people want to do when using UIKit with OpenGL are usually the ones that show up the bugs in UIKit/Quartz.

We’ll cover the main gotchas, and look at how to avoid or improve them. But for the most part: it works automagically. (there’s a reason for this: UIKit is implemented on top of OpenGL, so it’s already integrated to a high standard. It’s just that Apple hid the integration points)

Although it’s not strictly part of GLKit, Apple has re-used their old EAGLContext class to provide access to all of this. This is probably because it worked fine in the first place. However, to be clear: if you’re used to EAGLContext, it’s still used EVERYWHERE by GLKit.

Next steps

NOTE: a *lot* of the detail in Jeffs’ posts is now unnecessary (or superceded). But it all helps with understanding the newer/cleaner GL ES 2 (and GLKit) versions. If you get stuck or struggle, skim that post and move on to the next. Each of his posts works well standalone.