Thomas Denney

OpenGL.swift

It is a little bit of a pain to use OpenGL with Swift as GLKit is barely compatible. This is because GLKit’s math functions and types are all based off of unions, which Swift doesn’t support because they are designed to be unsafe. You are left with two choices: roll your own matrix library in Swift (which may miss out on the ARM NEON or Intel SSE performance enhancements) or hide GLKit behind some Objective-C.

I decided to go for the latter, and the product is OpenGL.swift. Instead of using unions I have used structs which contain one member:

typedef struct {
    GLfloat m[16];
} TDMatrix4;

I then wrapped all of GLKit’s math functions and I internally cast my matrix and vector types to the GLKit types in Objective-C code. As all of my functions and all of the GLKit functions get inlined there is no performance cost to this. My code was all generated by a Ruby script directly from the GLKit headers.

Once I had wrapped all of the GLKit math functions and types I then wrapped all of the uses of matrices and vectors in GLKit classes, so you can actually use them from Swift:

let aspect = GLfloat(CGRectGetWidth(self.view.bounds) / CGRectGetHeight(self.view.bounds))
let projectionMatrix = TDMatrix4MakePerspective(GLKMathDegreesToRadians(65.0), aspect, 0.1, 100.0)
self.effect?.transform.td_projectionMatrix = projectionMatrix

At this point I then added operator overloading using all of the standard methods, so in Swift you can concisely do matrix math:

let mvpMatrix = projectionMatrix * modelViewMatrix

As well as this I also added wrappers around the standard uniform functions so it is much simpler to submit matrix and vertex data to the GPU:

//Submitting vertex data
glBufferData(GLenum(GL_ARRAY_BUFFER), vertexData, GLenum(GL_STATIC_DRAW))
//Setting uniform data
glUniformMatrix4fx(mvpMatrixSlot, TDFalse, mvpMatrix)

You can get the source for OpenGL.swift on GitHub (there are instructions for dropping it into your project there as well).