RenderingPipeline

from geometry to pixels

Windowless OpenGL on MacOS X

As it turns out, windowless OpenGL applications are not only possible on Linux, but also on MacOS X – and it’s quite simple to set up.

But first a little bit of background about OpenGL on Apple: At the lowest layer, OpenGL is handled by CGL (Core OpenGL), based on top of that are AGL (Apple Graphics Library) and Cocoas OpenGL interface. AGL is deprecated and only supports 32 bit applications, Cocoa is Apples modern ObjC based API. Normally you don’t interact much with CGL but here we will set up the windowless OpenGL context just with low-level CGL calls.

First we need a variable to store the OpenGL context in and some attributes which will describe the desired context. Note that this will request a OpenGL 3.2 core profile, if you want a 2.1 context (or you’re working on pre 10.7), leave the marked attributes out.

CGLContextObj context;
 
CGLPixelFormatAttribute attributes[4] = {
  kCGLPFAAccelerated,   // no software rendering
  kCGLPFAOpenGLProfile, // core profile with the version stated below
  (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
  (CGLPixelFormatAttribute) 0
};

You will need to import <OpenGL/CGLTypes.h> and <OpenGL/CGLCurrent.h> as well as linking against the OpenGL framework.

Next we will try to create a context and making it current without a framebuffer 0 attached:

  CGLPixelFormatObj pix;
  CGLError errorCode;
  GLint num; // stores the number of possible pixel formats
  errorCode = CGLChoosePixelFormat( attributes, &pix, &num );
  // add error checking here
  errorCode = CGLCreateContext( pix, NULL, &ctx ); // second parameter can be another context for object sharing
  // add error checking here
  CGLDestroyPixelFormat( pix );
 
  errorCode = CGLSetCurrentContext( context );
  // add error checking here

We don’t get a framebuffer, so all rendering has to be done in a framebuffer object but apart from that everything should work. Don’t forget to free the context when you’re done:

  CGLSetCurrentContext( NULL );
  CGLDestroyContext( context );

But what about remote OpenGL (as windowless OpenGL can be useful for remote, automated testing)? Turns out to work quite well as long as the same user is logged in locally as well (same on Linux), but in contrast to Linux, other users can be working on that machine locally (just lock your screen and switch to another user).

In case the user is not logged in, the CGLChoosePixelFormat will return kCGLBadConnection, so always check your error codes!

, , , , ,

6 thoughts on “Windowless OpenGL on MacOS X
  • Chris Lundquist says:

    errorCode = CGLCreateContext( pix, NULL, &ctx ); // second parameter can be another context for object sharing

    The line should read:

    errorCode = CGLCreateContext( pix, NULL, &context );

  • Ed Preston says:

    In the paragraph about headers and frameworks, I’d recommend including only as described in the reference to get definitions for CGL types and functions. Surprisingly, this header does not include OpenGL function definitions but, everything required for CGL.

  • Ed Preston says:

    The filter removed “OpenGL/OpenGL.h” in the comment above.

  • Enhao Gong says:

    Hi how I can use FBO with the created context?
    I have done FBO offscreen rendering with GLUT but how to use the context created by CGL?
    Do you have an example or reference?

    Thanks a lot!

Leave a Reply

Your email address will not be published. Required fields are marked *

*