A rendering context does not own the drawing objects attached to it, which leaves open the option for sharing. Rendering contexts can share resources and can be attached to the same drawable object (see Figure 6-2) or to different drawable objects (see Figure 6-3). You set up context sharing—either with more than one drawable object or with another context—at the time you create a rendering context.
Contexts can share object resources and their associated object state by indicating a shared context at context creation time. Shared contexts share all texture objects, display lists, vertex programs, fragment programs, and buffer objects created before and after sharing is initiated. The state of the objects are also shared but not other context state, such as current color, texture coordinate settings, matrix and lighting settings, rasterization state, and texture environment settings. You need to duplicate context state changes as required, but you need to set up individual objects only once.
When you create an OpenGL context you can designate a second context to share object resources. All sharing is peer to peer. Shared resources are reference-counted and thus are maintained until explicitly released or when the last context sharing resource is released.
Not every context can be shared with every other context. Much depends on ensuring that the same set of renderers supports both contexts. You can meet this requirement by ensuring each context uses the same virtual screen list, using either of the following techniques:
Use the same pixel format object to create all the rendering contexts that you want to share.
Create pixel format objects using attributes that narrow down the choice to a single display. This practice ensures that the virtual screen is identical for each pixel format object.
Setting up shared rendering contexts is very straightforward. Each Apple-specific OpenGL API provides functions with an option to specify a context to share in its context creation routine.
Use the share argument for the initWithFormat:shareContext: method of the NSOpenGLContext class. See Listing 6-12.
Use the share parameter for the function aglCreateContext. See Listing 6-13.
Use the share parameter for the function CGLCreateContext. See Listing 6-14.
Listing 6-12 ensures the same virtual screen list by using the same pixel format object for each of the shared contexts.
Listing 6-12 Setting up an NSOpenGLContext object for sharing
#import <Cocoa/Cocoa.h> |
+ (NSOpenGLPixelFormat*)defaultPixelFormat |
{ |
NSOpenGLPixelFormatAttribute attributes [] = { |
NSOpenGLPFADoubleBuffer, |
(NSOpenGLPixelFormatAttribute)nil }; |
return [[(NSOpenGLPixelFormat *)[NSOpenGLPixelFormat alloc] |
initWithAttributes:attribs] autorelease]; |
} |
- (NSOpenGLContext*)openGLContextWithShareContext:(NSOpenGLContext*)context |
{ |
if (_openGLContext == NULL) { |
_openGLContext = [[NSOpenGLContext alloc] |
initWithFormat:[[self class] defaultPixelFormat] |
shareContext:context]; |
[_openGLContext makeCurrentContext]; |
[self prepareOpenGL]; |
} |
return _openGLContext; |
} |
- (void)prepareOpenGL |
{ |
// Your code here to initialize the OpenGL state |
} |
Listing 6-13 sets up two pixel formats objects—aglPixFmt and aglPixFmt2—that share the same display.
Listing 6-13 Getting the same virtual screen list with different attributes
GLint attrib[] = {AGL_RGBA, AGL_DOUBLEBUFFER, AGL_FULL_SCREEN, AGL_NONE}; |
GLint attrib2[] = {AGL_RGBA, AGL_DOUBLEBUFFER, AGL_NONE}; |
disp = GetMainDevice(); |
aglPixFmt = aglChoosePixelFormat(&disp, 1, attrib); |
aglContext = aglCreateContext(aglPixFmt, NULL); |
//Use same display |
aglPixFmt2 = aglChoosePixelFormat (&disp, 1, attrib2); |
aglContext2 = aglCreateContext(aglPixFmt2, aglContext); |
Listing 6-14 ensures the same virtual screen list by using the same pixel format object for each of the shared contexts.
Listing 6-14 Setting up a CGL context for sharing
#include <OpenGL/OpenGL.h> |
CGLPixelFormatAttribute attrib[] = {kCGLPFADoubleBuffer, 0}; |
CGLPixelFormatObj pixelFormat = NULL; |
long numPixelFormats = 0; |
CGLContextObj cglContext1 = NULL; |
CGLContextObj cglContext2 = NULL; |
CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats); |
CGLCreateContext(pixelFormat, NULL, &cglContext1); |
CGLCreateContext(pixelFormat, cglContext1, &cglContext2); |
Last updated: 2008-06-09