OpenGL Threading in Cinder

While creating a Cinder app that loads FBX Models I found that when I am baking animations into DisplayLists, and loading textures, the application stalls. Immediately most will note that this is an ideal case for using threads. Cinder has some really great Boost thread wrappers; but the problem in this case is that it that a purely C++ solution will not cut it as OpenGL functionality is required to load textures and DisplayLists to the video card. Fortunately there is a surprisingly easy solution!

Some research in the cloud lead me to here:

Some very rough pseudo-code would be as follows. In all my tests heavy loading and parsing of FBX models does not noticeably interrupt framerate.

NOTE: the following code is for OS X 4.7 and above. For Windows check the second link above …

//main app's thread
//get current render context Object
//create Cinder thread and pass context ( along with any variables to store data such as Displaylists created or the like )
CGLContextObj ctx = CGLGetCurrentContext();
newCinThread = thread(threadedFunction, ctx, someMutex, someVectorToHoldData );

insideCinderThread(threadedFunction, ctx, &someMutex, &someVectorToHoldData )
{
      someMutex->try_lock();
      
      //create new context
      CGLContextObj newCtx 
      CGLCreateContext( pixStuff, ctx, &newCtx );   //second parameter is important as it allows this context's resources to share with original renderer where I will use created data to display/draw etc.
     
      CGLLockContext( newCtx ); //not sure if this is necessary but Apple's docs seem to suggest it
      CGLSetCurrentContext( newCtx );  //also important as it now sets newly created context for use in this thread
      CGLEnable( newCtx, kCGLCEMPEngine ); //Apple's magic sauce that allows this OpenGL context  to run in a thread

     //do your openGL stuff here - includes texture creation using gl::Texture, VBO's, DisplayLists ... ( some caveats but none I came across yet )

      //close it all down - not sure but newCtx may also have to be deleted ...
      CGLDisable( newCtx, kCGLCEMPEngine );
      CGLUnlockContext( newCtx );
      CGLDestroyContext( newCtx ); //clean up this openGL context as not required anymore

      someMutex->unlock();

      //TADA now try accessing the stuff you created in this thread within your main Cinder App and like magic it works!
}

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