Practical Blender with GLKit – Part 1 – Introducing GLKit
This is my first post for idevblogaday.com and I am quiet excited to be part of this community. The main reason to do this is so I do more constant iOS development. Hopefully I can keep up with the bi-weekly schedule.
With this post, I would like to start a series about the use of Blender for iOS game development. I will additionally base this series on the new iOS 5 framework GLKit. I will try to keep it rather practical and assume knowledge of OpenGL ES and Blender basics. If that is not the case for you, I will give reference to some literature for self-learning:
The general idea for the different parts of the series is at the moment as follows:
- Introduction: Basically set up a GLKit-based project from ground. This will be rather a beginners-type topic to get started. As GLKit is a just newly introduced API in iOS 5 I think that it makes sense to spend a whole post on it.
- Blender and Python: I will try to introduce the powerful python scripting engine underneath Blender. How to write own scripts that access the modeled object and modify them.
- Blender Exporting: We will use Blender’s python scripting engine to write our own export-function to a custom 3D model format and write the corresponding model-loader for our GLKit project of Part 1.
- Blender Animations: We will extend our model to contain skeletal animation and add the necessary adjustments to our Blender export-script and our GLKit project.
- We will see what I can come up with. I am not this far yet.
OpenGL ES Links
If you have followed this blog before, you might know that I expect you to read some external resource on your own to get the necessary concepts if you don’t know them yet. So here, some external literature for OpenGL ES, if you need to refresh your knowledge:
- Nehe: THE resource on OpenGL with alot of tutorials with sources for various platforms. Not specific for iOS, but you can find a port of the most projects on code.google.
- A great introduction into the concepts of OpenGL ES: Part 1, Part 2, Part 3.
- Jeff Lamarche has some nice tutorials for OpenGL ES 1 on iOS as well as some chapters on a planned OpenGL ES 2 book (Chapter 1, 2, 3, 4).
- Ray Wenderlich has also some iOS-specific tutorials on OpenGL ES.
- If you are like me and like to turn physical pages, this official guide on OpenGL ES 2 is worth it.
- You have to learn the shader language
- You have to write the code for loading, compiling and linking the shaders yourself (well, it is in the template; but anyway)
- You have to set up the different buffers (pixelbuffer, depthbuffer, stencilbuffer, …) yourself (again; in the template, but it just leaves a bad feel in your stomach)
- You loose a lot of the beloved APIs for manipulating the modelview and projection matrices.
Next, go to the autogenerated GLKitAndBlenderViewController.h header-file and give it the protocols, methods, and member as you see below:
We do four main things here:
- Define this controller as a subclass of GLKViewController. This controller plus the GLKView we will define in the next step in interface-builder save a lot of work in regard of automatically setting up a render-loop and managing the framebuffer.
- We make this controller its own delegate by implementing the GLKViewControllerDelegate protocol. This protocol defines the method glkViewControllerUpdate: that is called each time before a new frame will be render. You can use it for any kind of calculations that have to be performed prior to the actual rendering; so, the render-method itself is as lightweight as possible. In a game you might also use this method to update your game-physics and -state.
- We also implement the GLKViewDelegate that defines us our actual render-method glkView:drawInRect:.
- Also, don’t forget to import the GLKit header-files!
Reimplementing the Swinging Square
You might know the standard OpenGL ES template in XCode, that displays a swinging, multi-colored square. We will reimplement this with the help of GLKit and the GLKBaseEffect. Once you have that running, you have a minimal GLKit template and we have a good basis for the next part of the series.
Let’s first review the viewDidLoad-method:
First, we set up the OpenGL Context (EAGLContext) for OpenGL ES 2 and set it on the GLKView (line 9). We also define us as the delegate for the GLKView and set some properties on the view so it can set up the framebuffer correctly.
From line 15 one, we first set us as the delegate for ourself (always good if you know how to help yourself!) and set the prefered framerate the GLKViewController will try to manage for us.
Oh; and we create an instance of GLKBaseEffect. If we look into the implementation of the GLKViewController delegate-method, we see what we can do with this effect-class:
As OpenGL ES 2 is missing all the APIs to easily manipulate the modelview and projection matrix (except from within the vertex-shader), GLKit defines a rich set of methods to create and manipulate matrices. So, equivalent to the code
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslate3f(0, y, -5.0f);
we can do a GLKMatrixMakeTranslation() to create the translation-matrix and then set it on our GLKBaseEffect effect.transform.modelview-property. The internals will make sure to hand this over to the vertex-shader.
Same for defining our projection-matrix. Instead of glPerspective() in good ole OpenGL ES 1, we use GLKMatrix4MakePerspective() and set it on the effect-instance so these uniforms are internally passed to the shaders.
In fact, in the render-method, the first thing we have to do is call prepareToDraw on our GLKBaseEffect. Here the magic happends and the instance will bind uniforms/attributes that are internally defined and link the shaders. After that, it is rather standard OpenGL ES 2 code that defines verticies and colours for the vertecies and sticks them into the the standard glVertexAttribPointer-methods to feed them in the vertex-shader. Note though, that we have to use the GLKit constants GLKVertexAttribPosition and GLKVertexAttribColor so GLKit binds the attributes correctly to the variables in the shaders.
And, due to the glDrawArrays()-call we actually should see the swinging square when your run the project in the simulator. You can find the full project over at github.
So you see, GLKit is a quiet nice API that makes the transition to OpenGL ES 2 not so harsh. You get a great matrix-library and can also use the fixed-function pipeline from OpenGL ES 1 for some rendering where you are just fine with those capabilities.
And there is more: A class for easy texture-loading (GLKTextureLoader; no copying of Texture2D into your project as the first action), skybox-effects (GLKReflectionMapEffect) and Quaternions (GLKQuaternion). All stuff that you normally have to redo/reimport into your project to even get started.
What I was missing a bit at first was a base-class to derive and define your own effects. So, basically, get at least some help in loading and linking the shaders with a nice object-oriented API (there only is a protocol GLKNamedEffect you can implement to define your own effects). But this is only a minor point compared to all the other stuff you get for free. And, I assume we can look forward to some quiet nice additional effect in iOS 6+.
Blender Links & Hints
In the next part, we will start to use some advanced Blender scripting features. So, I will assume some basic blender knowledge up front. Here comes a list of what has helped me a lot to get started:
- The best resources can be found directly at blender.org in the Tutorials section. I basically did the introductory series and some advanced tutorials (1, 2) to model static objects. Once you have done the steps in the webcasts on your own, you should have a good overview of the basic blender features and check on advanced topics if you like. And don’t worry if you don’t get everything in the advanced tutorials; every part you get is great, the rest will come later.
- A great online-resource is the Blender 3D: Noob to Pro series.
- There is a great number of Blender video tutorials out there. Unfortunately, a lot are for older version. As the interface has been changed over time, be sure to look for the right tutorials; i.e. the interface in the webcasts should look the same as for your Blender version (presumable 2.5X) or you might not get the most out of it.
- Blender has a lot of keyboard shortcuts and mastering them is the key in becoming a Blender guru. This keyboard shortcut sheet helped me a lot in that regard.
- If you read this, chances are high that you work on a MacBook. Unfortunately, Blender makes good use of the numerical keypad and the third mouse-button for changing the viewport in the 3D view. So, I recommend using a three-button mouse for modeling. To at least emulate the 3-button mouse and the numerical keypad, there exist useful settings in the Preferences of Blender (File -> User Preferences): Check “Emulate 3-button mouse” to use Alt-left-mouse-button to rotate the 3D view and “Emulate numpad” to use the standard number-keys as a replacement for the num-pad. Don’t forget to press “Save as Default” if you want Blender to remember this until the next launch.