OpenGL on MacOSX

by Glenn Fiedler on January 19, 2009

So you want to get started coding OpenGL on the mac, but what API should you use?

Apple seems to hint pretty heavily towards Objective-C with Cocoa + NSOpenGLView, but what if all you really want is an OpenGL display to draw to and not much else? All the XCode project stuff and Cocoa framework can be a real pain in the ass. Surely there is something lower level?

It turns out there is – next you have AGL + Carbon. Carbon is a lower level C API, and AGL seems pretty straightforward (especially if you are used to WGL).

How about fullscreen? Well in this case, the best choice is CGL, the lowest OpenGL API on MacOSX, above which NSOpenGLView and AGL are both built. This is a really cool API, you can capture the entire screen so you get the full performance of the graphics card without other apps slowing you down when they render their UIs. This is a *big* performance gain if you have a shitty integrated graphics chip like I do on my Macbook Air :)

All of this is not really that hard to do, but the information on how to do all this is pretty spread out.

For example, how do you take a console program and make a .app file without using XCode? How do you create a carbon window? How to process events? How to make the application menu work properly (you have to do this manually…)

All of these things add up to a huge pain in the ass if you just want to get your OpenGL display ASAP, many folks just ended up using Cocoa for this exact reason, but no more!

Here is a little code snippet, it’s my OpenGL Display module I use at home.

It’s got three simple functions:

OpenDisplay
UpdateDisplay
CloseDisplay

You can choose between AGL windowed output and CGL fullscreen by flipping a #define, plus it handles window creation, basic window events, quit event handling and simple keyboard input for you.

Take a look at the source code for the display here:

Display.h

And download the full OpenGL example here:

OpenGL.zip

(to run it just go “make opengl”)

Once you have it up and running, here are some useful references so you can extend its functionality:

OpenGL Programming Guide for MacOSX
Quartz Display Services
Window Manager Reference
Carbon Event Manager

Enjoy!

{ 17 comments… read them below or add one }

Marc January 20, 2009 at 10:03 am

Carbon? Oh – thats not a good idea to use,
it is already deprecated and Apple wants to
remove it from future OS releases.

(Granted, they said that a few times afaik, but
for new code you shouldn’t use it.)

Marc

Btw: I’m really looking forward to your talks at GDC :)

Reply

sam January 20, 2009 at 5:34 pm

I took a Linux version of a simple little OpenGL app I had written and with a few minor makefile changes I was able to get it compiling on my girlfriend’s MacBook. I think I was just linking against gl, glu, and glut. I haven’t done any other OSX programming, but it seemed really easy to get an OpenGl app up and running if one doesn’t want to use any Mac-specific stuff.

Reply

Glenn Fiedler January 20, 2009 at 6:02 pm

GLUT blergh! :)

Reply

sam January 25, 2009 at 11:38 pm

Yeah, I agree, it is pretty arse :)

It was so cool to see that all these development tools were available without having to install anything, though.

Reply

herc January 30, 2009 at 2:13 am

no one mentioning http://www.libsdl.org ?

“SDL supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. The code contains support for AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS, and OS/2, but these are not officially supported.”

the upcoming sdl 1.3 also will support the iphone !!

i use it since years, and i am totally happy with it. an alternative would be http://www.fltk.org – with that you also can manage to setup an opengl screen very rapidly.

Reply

Jesse T. February 4, 2009 at 5:26 pm

The problem with using Carbon for window management is that it is not forwards compatible for running universal binaries in 64-bit mode. You can still use the non-window management Carbon APIs and get 64-bit compatibility.

If you don’t use Cocoa for the UI stuff, It’ll thunk your executable into 32-bit mode.

In our code base, we’ve implemented a custom NSRunLoop and we hide all of the cocoa stuff behind a C++ based abstraction layer.

Reply

Ferum February 4, 2009 at 6:27 pm

Yeah, I would recommend SDL. Carbon is on its way out.

Reply

Glenn Fiedler February 5, 2009 at 9:26 am

Carbon 64bit Guide
64bit Transition Guide

Reply

Jesse T. February 5, 2009 at 3:47 pm
Anthony April 11, 2009 at 4:54 am

Thanks. I was getting annoyed with sdl and cocoa and its nsviews and nstimers. I will try this now, but I will eventually use cocoa but I can’t be bothered, this looks so much simpler.

Reply

wogston October 7, 2009 at 11:25 am

Hey Gaffer! I started porting of my iFap application to OS X, the X11 version was up in minutes (had to update the makefile mostly), but the X11 was ugly and, heh, not everything was so peachy. Did search for Carbon + OGL, and your arse page popped up.. figures.. dude, you’re a life-saver.

Reply

Glenn Fiedler October 7, 2009 at 12:52 pm

awesome! :)

Reply

wogston October 8, 2009 at 4:50 am

Your example gives serious errorfest on “windowed mode”, seems Apple has started seriously deprecating things on their latest XCode for 10.6, I didn’t have much time to look what was the problem, but it seems that you need “MacWindows.h” (or similar), that might do the trick. Haven’t tried yet, but check it out you might see the same problem.

FWIW, I was hoping to upgrade the framework I use for OGL (www.liimatta.org/misc/glext++.zip) with AGL support but now I am getting some cold feet syndrome. The Carbon+AGL seems just the thing I would prefer, except all this deprecation nonsense. =(

The Objective-C seems like something I could use happily for UI’s but for something low/mid-level like contect creation and management it doesn’t seem the most attractive choise. If I can hide the ugly detail(s) behind the framework, then I suppose it doesn’t matter Carbon or Cocoa. ;)

Okay, so, if I choose Cocoa, it’s ironic in a way, that I use high-level object based framework to capture system messages, translate and dispatch them to another (C++) framework. It’s hard to see how they manage to get rid of the CGL if the NS(+Cocoa) and AGL both are written on top of it. To truly deprecate the AGL they need to really start adding features we can’t ive without into the CGL which don’t get any mechanism to access from the AGL. I just want to create a context, so should be covered.

Well, of course, I am assuming that something they will choose to do will make any sense. Usually not the most sound bet. ;-)

Reply

Glenn Fiedler October 8, 2009 at 2:16 pm

yeah, the chocolate brigade has arrived and they want to force you to drink cocoa. sorry about that. if you find a good update, or a quick way to do similar in cocoa without xcode fuckings about, let me know :)

Reply

Roger August 19, 2012 at 10:42 am

Bah!

make opengl
g++ OpenGL.cpp -o OpenGL -Wall -Iode -DDEBUG -framework Carbon -framework OpenGL -framework AGL
In file included from OpenGL.cpp:6:
Display.h: In function ‘bool OpenDisplay(const char*, int, int)’:
Display.h:319: warning: ‘CGLSetFullScreen’ is deprecated (declared at /System/Library/Frameworks/OpenGL.framework/Headers/OpenGL.h:70)
Display.h:319: warning: ‘CGLSetFullScreen’ is deprecated (declared at /System/Library/Frameworks/OpenGL.framework/Headers/OpenGL.h:70)
Display.h:325: error: invalid conversion from ‘OSErr (*)(const AppleEvent*, AppleEvent*, SInt32)’ to ‘OSErr (*)(const AppleEvent*, AppleEvent*, void*)’
Display.h:325: error: initializing argument 1 of ‘OSErr (* NewAEEventHandlerUPP(OSErr (*)(const AppleEvent*, AppleEvent*, void*)))(const AppleEvent*, AppleEvent*, void*)’
make: *** [OpenGL] Error 1

Reply

Glenn Fiedler August 19, 2012 at 4:57 pm

The difference three years makes!

Reply

Johannes Lundberg January 31, 2013 at 12:37 pm

You can get at least the windowed AGL code to run on recent Mountain Lion by adding “-arch i386″ when compiling. Change the flags row in the makefile to:

flags = -Wall -Iode -DDEBUG -arch i386

Reply

Leave a Comment

{ 1 trackback }

Previous post:

Next post: