In a previous entry I said I would show how to setup an OpenGL application using Cocoa. This guide will be slightly more thorough than the one written on the Apple Developer Site. The version of XCode I’m using is 3.1.3, but I’ve included lots of pictures, which will hopefully work around problems with changes in versions.
First off, this is an extremely basic program, single buffer which is only redrawn when the window’s rectangle is dirty. To start off, open up a copy of XCode and create a new “Cocoa Application” and give it a name. I named mine “CocoaGL“.
Once created you should have something that looks kinda like the image on the right.
Now you have setup a basic Cocoa application, if you click “Build and Go” you will have a Cocoa window being displayed, however if you click the Red button to close the window, the debugger is still running because the application is still active.
But we’ll get around to fixing that later. Now for using OpenGL, we’ll need the OpenGL framework (a framework is a special folder that contains headers, resources, libraries, etc for a particular third party library).
To add a framework to an application, right click on any folder in the project (I use an already created one), select “Add” and then “Existing Frameworks…“. Now to find the OpenGL framework, navigate to “/System/Library/Frameworks/“. Now search through the folder and select “OpenGL.framework“, and select “Add“, and “Add” again.
With the OpenGL library now linked to the application, we need an Objective-C class for our OpenGL window to be associated with. To do this, we’ll need to inherit off NSView or NSOpenGLView (with NSView we’ll need setup OpenGL ourselves, so for now we’ll use NSOpenGLView). Right click on a folder in the project again, but this time select “Add” and then “New File…“.
Select “Objective-C class” from the list. You can also “Objective-C NSView subclass“, which will create a class with the functions “initWithFrame” and “drawRect“, as well as inheriting off NSView. But I’ll be providing the code for the class so any Objective-C class will be fine.
Upon clicking “Next” you’ll be presented with a screen similar to the one on the left. Choose a filename, for my code I used the name “OpenGLView” (this will also determine the class name. Make sure a header is created with this source file, one nice thing about XCode compared to Visual Studio is that it gives you this option.
Click “Finish” and your source and header files will be created for you, opening the header for you to view straight away. I’ve shown what is given by default, this can be used for normal window associated stuff, but it lacks an OpenGL context as well as setting up the pixel format information, that will allow us to use OpenGL.
Change the inherited class to NSOpenGLView (this does all the default stuff for us). Now add two addition functions, “prepareOpenGL” and “drawRect“, check the header for NSOpenGLView or the Cocoa documentation for more information. The image to the left shows what parameters and return value the functions use.
Now open the source file (Objective-C uses the extension .m, while Objective-C++ uses .mm). Within the “prepareOpenGL” function, this is where we setup our OpenGL context, I’ve set the clear color and I’ve set the swap interval to be synchronized with the vertical refresh (vblSynch value needs to be set to 1, 0 is as immediate).
And the “drawRect” function is used for, as you may have guessed, redrawing our screen. For now I’ve added code to clear the screen, draw a yellow triangle and flush the buffer (glFlush is used for a single buffer, rather than double).
With that done we need to link a window to the class we’ve just created. So find the XIB file within the project, and double-click it to open it up Interface Builder.
Within the Library window of Interface Builder, do a search for “Custom View“, then drag and drop the found object onto the window, and resize it if you want to be the same size as the window. There is also an “OpenGL View” object that gives you more control over the default settings, however I find it more restrictive to use.
Now open the “Size Inspector” window for the object we’ve just created, if it isn’t already open, goto the “Tools” menu and select “Size Inspector“. Click all arrows within “Autosizing” so that the object will automatically resize when the parent window is resized. See the image to the left for more information.
Now open up the “Identity Inspector“, if it isn’t open already you can access it from the “Tools” menu as well. Within the “Class Identity” section, set the “Class” to the name of the OpenGL view class we created, the auto-complete will help you find it. Once this is done, goto the “File” menu and select “Build and Go in XCode” – this will exit Interface Builder, build the project and then start it running.
If all has gone well, you’ll see a window like the one on the left image. However, if you try to resize it, it will remain in the same place (this is because we didn’t change the viewport size when the window is resized, this will be covered in the next part of this guide to using OpenGL in Cocoa).
One other thing you’ll notice is that if you close the window the application will still be running as mentioned earlier.
To fix this, we need to setup an object to handle delegations from the application, one of which is whether the application should end if a window is closed. So as before when we created our “OpenGLView” class, create a new class, I’ve called mine “AppDelegate“.
When it is created, add the function “applicationShouldTerminateAfterLastWindowClosed“.
Now add the function to the source file as well, returning “YES” so that the application will end when a window is closed.
Now find the XIB file again and double-click to open it up with Interface Builder again.
Now search for “Object“, and drag and drop the NSObject (the blue cube on its own, not the blue cube within the green circle) into the XIB window. Open up the “Identity Inspector” for the Object just created and then set the Class to the application delegate class we just created.
Now we just need to link the application delegate to this newly created Object associated with our delegate class. To do this, select “Application” from the XIB window, then open the “Connections Inspector“, available from the “Tools” menu.
Now drag from the “delegate” selection circle, to the delegate object. If done successfully, “delegate” will have a shaded box around it and the name of your delegate class you created on the right.
Go to the “File” menu and select “Build and Go in XCode“, you should now have a basic OpenGL application made in Cocoa, with a window that will shutdown the application if the window is closed.
The next guide will cover rendering with a double buffer, handling resizing, and a render loop of 60 frames per second. CocoaGL Source (Part 1) (531 downloads)