My first OpenGL tests under OSX 10.8
These last months I worked (and I still work) on my new 3d lib that will be used in all my new tools. This lib is cross-platform and supports Windows, Linux and now OS X.
I could enter in Mac’s world thanks to a MacBook Pro (with a 15-inch Retina display). I code with this laptop for some weeks now and I thought it was time to write a bit about the first contact with OpenGL under OSX from the point of view of a Windows developer…
One of the first things I do when I arrive on a new OS is to look at the OpenGL support and extensions. I did it for Linux (see Linux: Mesa, Gallium3D, Nouveau…) and now I do it for OSX.
The MacBook Pro Retina 15-inch offers three kinds of OpenGL renderers: two hardware renderers and one software renderer (first time I play with an OpenGL software renderer). The graphics hardware of the MacBook Pro Retina includes the integraded Intel Graphics HD 4000 GPU (part of the Ivy Bridge Core i7 processor) and a discrete NVIDIA GeForce GT 650M with 1GB of dedicated memory.
OSX 10.8 supports OpenGL 2.1 and OpenGL 3.2 core profile. The compatibility profile for OpenGL 3.2 is not available on OSX. Once my 3d lib started to run on OSX, I checked the OpenGL extensions available on my rMBP and they were exactly the same than those listed on Apple OpenGL capabilities tables for OSX 10.8, 10.7 and 10.6:
- OSX 10.8 OpenGL Core Caps (GL 3.2)
- OSX 10.8 OpenGL Lagacy Caps (GL 2.1)
- OSX 10.7 OpenGL Core Caps (GL 3.2)
- OSX 10.7 OpenGL Legacy Caps (GL 2.1)
- OSX 10.6 OpenGL Caps (GL 1.4, GL 2.1)
With an OpenGL 3.2 core context, 15 extensions are exposed for the software renderer (a highly optimized floating point CPU-based renderer), 16 extensions for the GT 650M and 13 for the HD 4000. It’s useless to list them here, just check the capabilities tables. So if you plan to add OpenGL 3.2 support for your software under OSX 10.6 (Snow Leopard), check the tables before: it’s not possible, OpenGL 3.2 being only available on OSX 10.7 (Lion) and OSX 10.8 (Mountain Lion). And how many extensions are exposed for the HD 4000 with an OpenGL 2.1 context under OSX 10.8? Check the table the right table and I bet you’ll find 123. This is one of the first surprises: OpenGL features are strictly defined on OSX while this is not the case in Windows or Linux worlds. This is nice because you can know in advance if your soft will work fine on a particular OSX version, but at the same time, latest features of the GPU can’t be exploited (OpenGL 4 for example). This under-control situation looks like D3D one, we lose the ability of OpenGL extensions to expose new features. NVIDIA has added a cool feature in GTX 600 called bindless textures. On Windows and Linux, bindless textures were quikly available thanks to OpenGL extensions while that was not the case for D3D. Actually I’m a bit too sever because some beyond GL3.2 extensions are exposed but you can count them with one hand 😉
The first time I checked the extensions exposed for the GT 650M with the OpenGL 3.2 context, I saw only 16 extensions. I thought the GL 3.2 support was far from complete. I was wrong. On Windows, when you ask for a GL 3 core profile, you retrieve all OpenGL extensions because they are not part of the OpenGL core libraries (GL 1.1 is the core on Windows). With latest R310.33, no less than 311 OpenGL extensions (I don’t count the WGL ones) are exposed. On OSX, OpenGL is fully integrated in the system and is the foundation for hardware-accelerated graphics (Quartz Extreme, the GPU layer of Quartz). That explains why there are only 16 extensions on OSX compared to the hundred ones on Windows: all extensions of OpenGL 3.2 are part of the OpenGL core libraries on OSX. Then, once a GL 3.2 context is created and made current, you can directly call glCreateShader() for example. That was another surprise fro me. On Windows (and Linux), you have to fetch entry points (function pointers) before calling OpenGL functions. You can do this yourself or by using OpenGL extensions loaders such as GLEW. On OSX, extensions loaders are somewhat useless to load OpenGL 3.2 functions but you can still use them (the extensions loaders), they will give you all function pointers so you can use the same code to initialize OpenGL in your cross-platform app. And for an OpenGL 2.1 context, extensions loaders are useful to get an access to all non-GL2.1 features.
Now the question: what are those 16 extensions? They are related to functionalities that are not included in OpenGL 3.2 spec, like GL_APPLE_xxxx extensions or new GL_ARB_xxx. By the way, all GL_ARB_xxx extensions exposed (GL_ARB_instanced_arrays, GL_ARB_occlusion_query2, GL_ARB_shader_bit_encoding and GL_ARB_timer_query) are part of the OpenGL 3.3 specifications, that means that a subset of OpenGL 3.3 is supported on OSX.
Now let’s see what APIs are available to make the link between OpenGL and the windowing system, also called the render window. On Windows, there is only one API called WGL. WGL makes the connection between OpenGL and the Win32 API. On Linux, same thing, one API this time called GLX that links OpenGL to the X11 windowing system. On OSX there are… four APIs: CGL, AGL, NSOpenGL and GLX.
1 – CGL (Core OpenGL) is the lowest API available in the GL-windowing API stack. All other APIs rely on it. CGL is not related to a particular windowing interface and alone, CGL can be used only in fullscreen applications. Used alone is important, because and that’s the strength of CGL, you can use it with other interfaces like GLX or NSOpenGL.
2 – AGL is the Carbon interface related API. Carbon is a 32-bit only windowing system and is no longer supported by Apple. Of course a Carbon app can still run on OSX and you can still code an AGL-based demo, but this API is clearly deprecated.
3 – GLX… the Linux one? Yes, man! OSX is based on a Unix core (Mach + BSD) and supports X11 via the XQuartz project. XQuartz is a version of the X.Org X Window System that runs on OSX. On OSX 10.8, X11 is not available by default and you have to install XQuartz to compile and run X11-based applications. The nice news, is that the compilation of a Linux / X11 app under OSX is straightforward. I successfully compiled a the Linux version of the successor of GeeXLab under OSX without problem, nor headache! But it seems that GLX/X11 is limited to OpenGL 2.1 on OSX. I didn’t manage to create an OpenGL 3.2 core profile (if someone knows the tip…). The support of X11 / GLX is a nice thing for those who need to quickly port a Linux app on OSX.
The following screenshot shows the app I’m working on: GLSL Hacker, a cross-platform version of GeeXLab that runs on Windows, Linux and OSX. The screenshot shows the X11 version compiled under OSX (for the screenshot, I used a shader from GLSL Sandbox) :
The OSX/X11 version of GLSL Hacker running a GLSL Sandbox demo.
Thanks to the X11 support in OSX, I could quickly compile and test the Linux version under OSX. Great!
4 – NSOpenGL from the Cocoa framework. Cocoa is the API of choice for buidling modern OpenGL applications under OSX. Cocoa is the successor of Carbon and is a full 64-bit windowing system. Combined with CGL, you can create and customize your OpenGL contexts: vsync, gl 3.2 core, fullscreen software renderer, etc… More on Cocoa later 😉 Now I spend my time on updating my apps for Cocoa and here is the first application that will be released soon:
GpuTest: a Cocoa / OpenGL app
This screenshot shows GpuTest with a furry torus burning the GT 650M of the MacBook Pro (really noisy 😀 ). GPU Test is a small cross-platform OpenGL based benchmark tool that packs in the first version tests based on FurMark and TesssMark. There is also a geometry instancing test… The 3D engine used by GpuTest is the same than the one used by GLSL Hacker in the OSX/X11 test but this time in a Cocoa window. Next big job: a Cocoa version of GLSL Hacker!
I found the creation of OpenGL contexts easier than on Windows, especially when you need stuff like MSAA. And the fullscreen management… or transparent OpenGL windows (look at the first header image of this post)… so simple!
GpuTest – FurMark in fullscreen on the second monitor on OSX
Another thing I really appreciated is the window resizing. My GPU tools usually work with two threads: one main thread for the app GUI and one thread for the rendering. On Windows and Linux, I didn’t manage to get a proper resizing: when the window is resized, we see tearing, flashing and other undesirable effects (I did all possible tests on Windows, playing with window messages and notifications such as WM_PAINT, WM_ERASEBKGND (with and without Aero), but nothing to do. On OSX, the window resizing was perfect at the first time. No flashing nor tearing, only a smooth resizing.
In conclusion, I would say that my first contact with OpenGL on OSX is rather positive. And once that Objective-C basics are assimilated it’s quite easy to start coding OpenGL in a Cocoa window. I tested my apps on several GPUs (Intel HD 4000, GeForce GT 650M, GeForce 320M, Radeon HD 4870, Radeon HD 6750M) under OSX 10.7 and OSX 10.8 and all my GLSL shaders have worked fine immediatly (on Windows and Linux, there are still surprises when you code a shader on GeForce and test it on Radeon). The thing I found not very handy was the glext.h file, part of the OpenGL framework. My code relies on the official glext.h you can download from OpenGL.org and I couldn’t compile my code with Apple’s glext.h because all function pointers defines are not present… Actually they are present but you have to uncomment the define GL_EXT_FUNCTION_POINTERS in glext.h (I must say I didnt see this define the first time). The last thing: I want to see my tessellation code running on OSX! I need OpenGL 4! Come on Apple, give us OpenGL 4 to justify all these GL4 GPUs on latest Mac systems!
I hope I didn’t write too many mistaken things about OSX and OpenGL, so do not hesitate to point them out and fix them with a comment.
Now it’s time to release the first version of GpuTest…
17 thoughts on “Overview of OpenGL Support on OS X”
You can not get OpenGL 3.2 on OSX because its not there. X11 do not have api for it yet.
Apple froze specific X.org version for their X server.
So there is usually some lag, between X11 on Linux and X11 on OSX.
And X11 can not be used to create OGL 3.2 Core on Linux EITHER. On linux X11 development is pushed by MESA project. Right now they are working on OpenGL 3.2 / GLES 3.0. ETA spring of 2013. (And since OpenGL 3.3 is “almost” ready, it will be released too at the same time).
And since Apple is a bit behind, there will not be OpenGL 3.2 on X11 on OSX until Apple decide to fetch new upstream X11.
That is for X11 on OSX. However you have forgotten to add EGL as API for using OpenGL.
So Linux have two apis now! GLX (which is almost dead, only Nvidia now develop it for their own driver stack), and EGL (which is present both in MESA, and AMD Catalyst).
On Windows EGL is also present! In AMD Catalyst, and its preferred way for using GLES on Catalyst drivers.
X11/MESA crowd is swaying for deprecating GLX (as in present? yes, extended with new features? NO). And focusing solely on EGL. Also limited human resources probably will mean that MESA will choose to support only 2.1-3.1 and 3.2 Core Profile. As compatibility profile is a mess to implement 😉
PS can you check if EGL is also present in X11 in OSX?
Thanks for the EGL detail. I will look at this API support asap for Linux and OSX.
Here is some nice talk from XDC, where EGL/X11, Linux OGL ABI are topics. And we even get some input from Nvidia engineer.
Nice overview, thanks. Some comments:
If you want 64bit and more than OpenGL 2.1 there is no way around Cocoa. I don’t expect this to change. For beginners this means, that GLFW is a good choice as it is based on Cocoa on Macs, let’s you chose the GL context and is cross platform. GLUT on the other hand is outdated, FreeGLUT on Macs don’t play well with 3.2 as well. GLEW has some problems with the Core profile, you want to define glewExperimental = true; but also have to hack a bit inside of GLEW where it looks for the extensions available as this has changed in Core (I have an ungly hack if you’re interested, but it’s not clean enough to put it on my website. On the other hand, if you have a clean, core compatible version I can others point to, tell me).
Regarding the GL version: since 10.7 the hasn’t been much advances, even though all new macs have GPUs that could support GL 4. There have been some hints that Apple is working on newer GL support but I don’t expect this for 10.8 (maybe 10.9 not before late 2013)…
Do you plan to make your 3d lib available?
I was about to give Cinder a go but it already feels too huge for my needs (playing with effects)
If someone wants some small source code to start working with OpenGL 3.2 GLSL on Mac OSX and Windows you can use my github repository:
Under Windows click build/vs2010.bat
On Mac OSX run ./build/premake_osx xcode4 to generate XCode projects.
It can open a window using Cocoa or Win32, perform fast instanced or non-instanced rendering using GLSL and bitmap and vector/TrueType font rendering and window management using gwen and it has an OpenCL GPU rigid body and collision detection pipeline.
It would be great if you made your 3d lib available, or at least some template code for cocoa/opengl (e.g. MSAA) to help other people transition from Windows to OSX. Which resources did you find helpful in learning the OSX environment?
This is a good summary.
The G3D Innovation Engine (http://g3d.sf.net) has cross-platform support for OpenGL for those looking for a relatively slim cross-platform OpenGL 3D library.
We used to use our own hand-written Carbon API and are now switching to using the (unreleased) GLFW 3.0 Cocoa interface on OS X.
just a note that OpenGL 4.1 forward context support is coming to an update for Mountain Lion.
it would be nice if you also added java:OGL as part of your 3D overview!
(And, in particular, a look at java3D on osx — which has been going thru a long transition period to reach parity with mac/windows)
On Linux using GLEW is not necessary. On Linux libGL.so contain all functions pointers which are implemented in underlying implementation. So you can link against libGL.so from catalyst and you get functions pointers for free. You just need define GL_GLEXT_PROTOTYPES.
I’ve just finished porting my D3D9c code to OpenGL/MacOSX. A lot of fun, and a really work. Let’s say there is no doubt, with SDL, porting stuffs is easy. I give the source of my works but I would hope tablets with full support of opengl will arrive because vertex program and fragment program is really usefull even if GLSL allows to do the same thing it’s lighter to write. GLES 2.0 is a limitation to mind even for those who code since years because portability imply Android and iOS and more MacOSX.
Just curious, how does performance compare between CGL, AGL, NSOpenGL and GLX?
I regards to why GLSL shaders have good compatibility between AMD, Intel, and nVidia, I believe that’s because Apple writes and controls the front-end GLSL parser. Vendor GPU drivers are then back-end plug-ins. With only a single GLSL parser, GLSL code is broadly compatible, but it means that even if vendors add new extensions/functions in their GPU drivers, they aren’t exposed until Apple chooses to add them to the front-end. Apple also writes the software renderer which they like to keep on par with GPUs in feature support. That means the pace of OpenGL feature updates in OS X is determined by the speed Apple can update the graphics pipeline front-end and update the software renderer to keep pace.
Thanks for a great post.
One question – How did you make that second OpenGL window transparent?
thanks for writing it up, it’s nice!
just let you know objective c is not needed for core profile if using glfw http://www.glfw.org/, but still need Cocoa framework.
How did you get tessellation shaders working on OSX? There are no defines in the headers for GL_TESS_CONTROL_SHADER or GL_TESS_EVALUATION_SHADER what process do you use to load them? Really interested as want to add this support to my library (works on linux / windows but not mac yet)
Comments are closed.