How To Export Blender Models to OpenGL ES: Part 1/3

Learn how to export blender models to OpenGL ES in this three part tutorial series! By Ricardo Rendon Cepeda.

Leave a rating/review
Save for later
Share
You are currently viewing page 5 of 6 of this article. Click here to view the first page.

Building the Model Viewer iOS App

And now, the moment you’ve been waiting for... the app!

Project Setup

Open Xcode and go to File\New\Project.... Select iOS\Application\Empty Application and click Next. Name your project GLBlender1, choose iPhone for device family, make sure Use Automatic Reference Counting is selected and click Next. Save your project inside the folder /Code/ and click Create.

You want this app to run in portrait orientation only, so click on your GLBlender1 project in the Project Navigator and select GLBlender1 under TARGETS. In the Summary tab, under Supported Interface Orientations, make sure only the Portrait option is selected, as shown below (in Xcode 5.0, the setting is a checkbox under General/Deployment Info):

s_PortraitOrientation

This tutorial uses OpenGL ES and GLKit, so you need to add both frameworks to your project. With the TARGETS inspector still visible, scroll down to the section titled Linked Frameworks and Libraries, click the + button, find OpenGLES.framework and click Add, as shown below:

s_Frameworks

Repeat the steps above, but this time for GLKit.framework. With the required frameworks in place, you’ll now set up your screen for OpenGL ES content.

Adding a GLKit View Controller

Go to File\New\File... and choose the iOS\Cocoa Touch\Objective-C class subclass template. Enter MainViewController for the class and GLKViewController for the subclass, click Next and then Create.

Open MainViewController.h and add the following #import to remove the warning:

#import <GLKit/GLKit.h>

Now go to File\New\File..., choose the iOS\User Interface\Storyboard template and name it MainStoryboard.storyboard. Open MainStoryboard.storyboard and drag a GLKit View Controller onto the storyboard—Xcode will automatically make this your initial view controller. Select the GLKit View Controller and find the Custom Class section in the Identity Inspector. Set the Class to MainViewController, as shown below:

s_Storyboard

Using Your Storyboard

Now you need to configure your project to use MainStoryboard.storyboard on launch.

In the Project Navigator, click on your GLBlender1 project and select GLBlender1 under TARGETS. In the Summary tab, find the section iPhone/iPod Deployment Info and set the Main Storyboard to MainStoryboard.

Next, open AppDelegate.m and replace application:didFinishLaunchingWithOptions: with the following code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    return YES;
}

Your app will now load the user interface from your storyboard instead of creating an empty window.

Drawing a Gray Screen

Almost ready! There’s just a little bit of setup code left for your GLKit View Controller.

Open MainViewController.m and replace its contents with the following code:

#import "MainViewController.h"

@implementation MainViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // Set up context
    EAGLContext* context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    [EAGLContext setCurrentContext:context];
    
    // Set up view
    GLKView* glkview = (GLKView *)self.view;
    glkview.context = context;
    
    // OpenGL ES Settings
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClear(GL_COLOR_BUFFER_BIT);
}

@end

In this very simple implementation, you create an OpenGL ES 2.0 context and associate it with the glkview. You assign a gray background color with glClearColor() and implement the GLKView delegate with glkView:drawInRect:. That’s all you need to get GLKit going!

Build and run your app to reveal an exciting gray screen:

s_Run1

Creating a GLKBaseEffect

First things first—add your newly created resources to your project: cube.h, cube.c and cube.png (you may also add cube.obj, but it’s not necessary).

Add the following #import at the top of MainViewController.m:

#import "cube.h"

Now in a few easy steps, you'll create a GLKBaseEffect to handle your 3D scene. First, add the following lines to the top of MainViewController.m:

@interface MainViewController ()
{
}

@property (strong, nonatomic) GLKBaseEffect* effect;

@end

Second, initialize your effect inside a new function, just below viewDidLoad:

- (void)createEffect
{
    // Initialize
    self.effect = [[GLKBaseEffect alloc] init];
}

Next, call this new function from inside viewDidLoad by adding the following lines:

// Create effect
[self createEffect];

Finally, prepare your effect for rendering by adding the following lines to the end of glkView:drawInRect::

// Prepare effect
[self.effect prepareToDraw];

Build your project to check for warnings/errors. That was easy enough!

Rendering Your Model: Geometry

Onto your cube! You need to get those positions in place so you can see your cube’s geometry. But first, you’ll define the 3D environment with ModelView and Projection matrices (MVP). If you don’t know what those are or can’t remember, sit tight.

Add the following function to MainViewController.m, before the @end statement at the bottom of your file:

- (void)setMatrices
{
    // Projection Matrix
    const GLfloat aspectRatio = (GLfloat)(self.view.bounds.size.width) / (GLfloat)(self.view.bounds.size.height);
    const GLfloat fieldView = GLKMathDegreesToRadians(90.0f);
    const GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(fieldView, aspectRatio, 0.1f, 10.0f);
    self.effect.transform.projectionMatrix = projectionMatrix;
    
    // ModelView Matrix
    GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
    modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 0.0f, 0.0f, -5.0f);
    modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, GLKMathDegreesToRadians(45.0f));
    self.effect.transform.modelviewMatrix = modelViewMatrix;
}

Here’s a quick refresher on these matrices, straight from the docs:

  • Projection Matrix: The matrix used to transform position coordinates from eye space to projection space. In this instance, aspectRatio fits the projection to the iPhone’s screen aspect ratio and fieldView is set at a focused 90-degree field of view. The near and far planes are set at 0.1 and 10.0, respectively.
  • ModelView Matrix: The matrix used to transform position coordinates from world space to eye space. In this instance, the cube is translated by 5.0 units into the screen and rotated by 45.0 degrees about its x-axis.

Now that your 3D environment is set, it’s time to actually draw your position vertices. Add the following lines to the end of glkView:drawInRect::

// Set matrices
[self setMatrices];
    
// 1
// Positions
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, cubePositions);
    
// 2
// Draw Model
glDrawArrays(GL_TRIANGLES, 0, cubeVertices);

I hope this looks familiar to you, but here’s a quick breakdown of what’s happening:

  1. You provide an index for position data to OpenGL ES as a bound attribute array, in the form of three floats (XYZ) per vertex found in the sequential array cubePositions[].
  2. OpenGL ES will draw your model as a set of triangles using the number of vertices specified by cubeVertices, starting from the beginning of the bound attribute array.

There’s one more step. Add the following line to viewDidLoad, under the OpenGL ES settings:

glEnable(GL_CULL_FACE);

This is a very important command that tells OpenGL ES to draw only front-facing triangles—that is, the outside of the cube.

Build and run. Now you’ve got, um, something...

s_Run2

Believe it or not, this is your cube! Your geometry is in place, but it’s very difficult to appreciate it—so you should probably add at least a texture and some light to make it look nice. :]

Ricardo Rendon Cepeda

Contributors

Ricardo Rendon Cepeda

Author

Over 300 content creators. Join our team.