This tutorial aims to show how to quickly get started with Ogre3D 1.7 running on Mac OS X.

0. Getting Ogre3D

This is how I got up and running with a compiled and up-to-date version of Ogre.

1. If you don’t have Mercurial installed, get it and install it from http://mercurial.selenic.com/
2. Download the latest stable branch using `hg clone http://bitbucket.org/sinbad/ogre/ -u v1-7`
3. Ensure you have the latest build of freetype, boost and freeimage using:
`sudo port install freetype +universal boost +universal freeimage +universal`
5. Generate the XCode files using:
`cmake -G Xcode -D CMAKE_XCODE_ATTRIBUTE_GCC_VERSION=4.0 .`
This uses GCC 4.0 in order to work around a compiler issue.
6. Open the newly generated OGRE.xcodeproj and build it.

1. Getting started

The very bare bones basics to get OGRE running.

1. Open XCode and create a new Cocoa Application.
2. Once done drag the Ogre.framework and RenderSystem_GL.dylib into the project’s frameworks group.
3. To make the app self contained. Add a new Copy Files Build Phase that copies into Frameworks, and add the Ogre.framework to it.
4. Add a new Copy Files Build Phase that copies into Plugins, and add the RenderSystem_GL.dylib to it.
5. Remove the window from the nib file and references in the app delegate, we don’t need it for now.
6. Rename the default app delegate class to be a .mm file so that it compiles ObjC++.
7. Enter this basic code outline for initalising Ogre:

` `

lang=objc
#import “OgreTutorial1AppDelegate.h”
#import

using namespace Ogre;

@implementation OgreTutorial1AppDelegate

– (void)applicationDidFinishLaunching:(NSNotification *)notification
{
std::string mResourcePath = [[[NSBundle mainBundle] resourcePath]
cStringUsingEncoding:NSUTF8StringEncoding];

// Create a new root object with the correct paths
Root *mRoot = new Root(mResourcePath + “/plugins.cfg”, mResourcePath + “/ogre.cfg”,
mResourcePath + “/ogre.log”);
mRoot->setRenderSystem(mRoot->getAvailableRenderers().front());

// Show a configure box and exit if user clicked cancel
if(!mRoot->showConfigDialog())
return;

// Initialise
RenderWindow *mWindow = mRoot->initialise(true);
SceneManager *mSceneMgr = mRoot->createSceneManager(ST_GENERIC, “My scene manager”);

// Create the camera, node & attach camera
Camera *mCamera = mSceneMgr->createCamera(“My camera”);
SceneNode *camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
camNode->attachObject(mCamera);
mWindow->addViewport(mCamera);
}

@end

  1. Lastly create a new empty file called plugins.cfg. This is the configure file that tells OGRE what plugins to load. Enter “Plugin=RenderSystem_GL” in the blank file. And make sure it is included in the Copy Bundle Resources build phase.
  2. Enjoy the results:



  1. Download it here: OgreTutorial1.zip.

2. Adding resources and entities

A black screen is not very exciting. Ogre can do much more, we provide a start by adding some simple resources and creating something to look at.

1. First add the resources to the project for the knot: knot.material knot.mesh and MtlPlat2.jpg These are the material defenition file, the 3D mesh and the texture for the entity we will create. Make sure all three resources are included in the Copy Bundle Resources build phase. These are included in the download.
2. Next we add the code to load the resources, after initalising the Root object.

` `

lang=objc
// Add resource locations — looking at folders recursively
ResourceGroupManager::getSingleton().addResourceLocation(mResourcePath,
std::string(“FileSystem”), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false);
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

  1. Lastly we create a light and an Ogre entity out of the knot at (0,0,-500).

lang=objc
// Create a light
mSceneMgr->setAmbientLight(ColourValue(0, 0, 0));
mSceneMgr->createLight(“MainLight”);

// Add a object, give it it’s own node
SceneNode *objectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
Entity *knot = mSceneMgr->createEntity(“knot”, “knot.mesh”);
objectNode->attachObject(knot);
objectNode->setPosition(Vector3(0, 0, -500));

  1. Looking better:


  1. Download it here: OgreTutorial2.zip.

3. Animation

At the moment the 3D view only redraws as you resize the window. To make it move, we add a timer that causes some animation and updates the window.

1. Add a timer to fire calling renderFrame every 50th of a second:

` `

lang=objc
// create a timer that causes OGRE to render at 50fps
[NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(renderFrame)
userInfo:NULL repeats:YES];

  1. Add the method renderFrame that renders a single frame and updates the object.

lang=objc
– (void)renderFrame
{
Ogre::Root::getSingleton().renderOneFrame();
objectNode->rotate(Vector3(0, 1, 0), Radian(0.01));
}

  1. Download it here: OgreTutorial3.zip.

4. In your own nib file

Ogre can fit seamlessly in your own interface, inbetween all sorts of controls with multiple views. I needed to apply this patch to Ogre to make this work.

1. Open up the MainMenu.nib file again, and create a new window, filling it with a custom view that stretches with the window. Make sure the window is set to be visible on launch.
2. Create a new class OgreView by subclassing `NSView` and set the class of the new view you created to `OgreView`. Throw in some other interface bits for fun.

  1. Add an ogreView outlet to the `OgreController` class in Interface Builder connecting it up to the newly created view. Also add the outlet to the OgreController.h file.
  2. You will need to import the Ogre/OgreOSXView.h header file to reference the `OgreView` class.
  3. Replace this code that automatically creates windows

lang=objc
// Show a configure box and exit if user clicked cancel
if(!mRoot->showConfigDialog())
return;

// Initialise
RenderWindow* mWindow = mRoot->initialise(true);

…with this code that uses an OgreView we pass in ourselves.

lang=objc
// Initialise without an automatically created window
mRoot->initialise(false);

// Ask for a new window passing in the ogreView in our nib file
NameValuePairList misc;
misc[“externalWindowHandle”] = StringConverter::toString((size_t)ogreView);
mRoot->createRenderWindow(“ogre window”, 0, 0, false, &misc);
RenderWindow *mWindow = [ogreView ogreWindow];

  1. Have some fun with the interface. Hook up the components with bindings to control different aspects of the scene.
  2. Add the timer to other run loops to get animation whilst using controls.

lang=objc
NSTimer *renderTimer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self
selector:@selector(renderFrame) userInfo:NULL repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSEventTrackingRunLoopMode];

  1. Download it here: OgreTutorial4.zip.