< Previous PageNext Page > Hide TOC

Techniques for Choosing Attributes

Renderer and buffer attributes determine the renderers that the system chooses for your application. Each of the Apple-specific OpenGL APIs provides constants that specify a variety of renderer and buffer attributes. You supply a list of attribute constants to one of the Apple OpenGL functions for choosing a pixel format object. The pixel format object maintains a list of appropriate renderers. In previous chapters, you saw how to set up an attributes array that contains a small set of attributes.

In a real-world application, selecting attributes is an art because you don't know the exact combination of hardware and software that your application will run on. An attribute list that is too restrictive could miss out on future capabilities or not be able to run on many systems. For example, if you specify a buffer of a specific depth, your application won't be able to take advantage of a larger buffer when more memory is available in the future. In this case, you might specify a required minimum and direct OpenGL to use the maximum available.

Although you might want to specify attributes that make your OpenGL content look and run its best, you also need to consider whether you'll allow your application to run on a less-capable system at the expense of speed or detail. If tradeoffs are acceptable, you'll need to set the attributes accordingly.

In this section:

Buffer Size Attribute Selection Tips
Attributes that are not Recommended
Ensuring that Back Buffer Contents Remain the Same
Ensuring a Valid Pixel Format Object
Ensuring a Specific Type of Renderer
Ensuring a Single Renderer for a Display
See Also


Buffer Size Attribute Selection Tips

Follow these guidelines to choose buffer attributes that specify buffer size:

Attributes that are not Recommended

There are several renderer and buffer attributes that are no longer recommended either because they are too narrowly focused or no longer useful:

Ensuring that Back Buffer Contents Remain the Same

A backing store attribute (NSOpenGLPFABackingStore, AGL_BACKING_STORE, or kCGLPFABackingStore) is required whenever an application depends on the back buffer contents remaining the same after a swap buffer call.

Ensuring a Valid Pixel Format Object

The pixel format routines (the initWithAttributes method of the NSOpenGLPixelFormat class, aglChoosePixelFormat, and CGLChoosePixelFormat) return a pixel format object to your application that you use to create a rendering context. The buffer and renderer attributes that you supply to the pixel format routine determine the characteristics of the OpenGL drawing sent to the rendering context. If the system can't find at least one pixel format that satisfies the constraints specified by the attribute array, it returns NULL for the pixel format object. In this case, your application should have an alternative that ensures it can obtain a valid object.

One alternative is to set up your attribute array with the least restrictive attribute first and the most restrictive attribute last. Then, it is fairly easy to adjust the attribute list and make another request for a pixel format object. The code in Listing 7-1 illustrates this technique using the CGL API, but you can just as easily use Cocoa or the AGL API. Notice that the initial attributes list is set up with the supersample attribute last in the list. If the function CGLChoosePixelFormat returns NULL the first time it's called, the code sets the supersample attribute to NULL and once again requests a pixel format object.

Listing 7-1  Using the CGL API to create a pixel format object

int last_attribute = 6;
CGLPixelFormatAttribute attribs[] =
{
    kCGLPFAAccelerated,
    kCGLPFAColorSize, 24
    kCGLPFADepthSize, 16,
    kCGLPFADoubleBuffer,
    kCGLPFASupersample,
    0
};
 
CGLPixelFormatObj pixelFormatObj;
long numPixelFormats;
long value;
 
CGLChoosePixelFormat (attribs, &pixelFormatObj, &numPixelFormats);
 
if( pixelFormatObj == NULL ) {
    attribs[last_attribute] = NULL;
    CGLChoosePixelFormat (attribs, &pixelFormatObj, &numPixelFormats);
}
 
if( pixelFormatObj == NULL ) {
    // Your code to notify the user and take action.
}

Ensuring a Specific Type of Renderer

There are times when you'll want to ensure that you obtain a pixel format that supports a specific renderer type, such as a hardware-accelerated renderer. Table 7-1 lists attributes that support specific types of renderers. The table reflects the following tips for setting up pixel formats:

Table 7-1  Renderer types and pixel format attributes

Renderer type

CGL

AGL

Cocoa

Hardware-accelerated onscreen

kCGLPFAAccelerated

kCGLPFANoRecovery

AGL_ACCELERATED

AGL_NO_RECOVERY

NSOpenGLPFAAccelerated

NSOpenGLPFANoRecovery

Software (floating-point)

kCGLPFARendererID

kCGLRendererGenericFloatID

AGL_RENDERER_ID

AGL_RENDERER_GENERIC_FLOAT_ID

NSOpenGLPFARendererID

kCGLRendererGenericFloatID

Software (deprecated on Intel-based Macs)

kCGLPFARendererID

kCGLRendererGenericID

AGL_RENDERER_ID

AGL_RENDERER_GENERIC_ID

NSOpenGLPFARendererID

kCGLRendererGenericID

System memory (not accelerated)

kCGLPFAOffScreen

AGL_OFFSCREEN

NSOpenGLPFAOffScreen

Hardware-accelerated offscreen

kCGLPFAPBuffer

AGL_PBUFFER

NSOpenGLPFAPixelBuffer

Ensuring a Single Renderer for a Display

In some cases you may want to use a specific hardware renderer and nothing else. Since the OpenGL framework normally provides a software renderer as a fallback in addition to whatever hardware renderer it chooses, you need to prevent OpenGL from choosing the software renderer as an option. You either need to specify the no recovery attribute for a windowed drawable object or use a full-screen drawable object. (The full-screen attribute always implies not to use the software renderer as an option.)

Limiting a context to use a specific display, and thus a single renderer, has its risks. If your application runs on a system that uses more than one display, then dragging a windowed drawable object from one display to the other will likely yield a less than satisfactory result. Either the rendering will fail, or OpenGL uses the specified renderer to copy the drawing to the second display. The same unsatisfactory result happens when attaching a full-screen context to another display. If you choose to use the hardware renderer associated with a specific display, you need to add code that detects and handles display changes.

The three code examples that follow show how to use each of the Apple-specific OpenGL APIs to set up a context that uses a single renderer. Listing 7-2 shows how to set up an NSOpenGLPixelFormat object that supports a single renderer. The attribute NSOpenGLPFANoRecovery specifies to OpenGL not to provide the fallback option of the software renderer.

Listing 7-2  Setting an NSOpenGLContext object to use a specific display

#import <Cocoa/Cocoa.h>
+ (NSOpenGLPixelFormat*)defaultPixelFormat
{
    NSOpenGLPixelFormatAttribute attributes [] = {
                        NSOpenGLPFAScreenMask, 0,
                        NSOpenGLPFANoRecovery,
                        NSOpenGLPFADoubleBuffer,
                        (NSOpenGLPixelFormatAttribute)nil };
CGDirectDisplayID display = CGMainDisplayID ();
// Adds the  display mask attrib for selected display
attributes[1] = (NSOpenGLPixelFormatAttribute)
                    CGDisplayIDToOpenGLDisplayMask (display);
return [[(NSOpenGLPixelFormat *)[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]
                                       autorelease];
}

Listing 7-3 shows how to use AGL to set up a context that uses a single renderer. The attribute AGL_NO_RECOVERY specifies to OpenGL not to provide the fallback option of the software renderer.

Listing 7-3  Setting an AGL context to use a specific display

#include <AGL/agl.h>
GLint attrib[] = {AGL_RGBA, AGL_DOUBLEBUFFER, AGL_NO_RECOVERY, AGL_NONE};
GDHandle display = GetMainDevice ();
AGLPixelFormat aglPixFmt = aglChoosePixelFormat (&display, 1, attrib);

Listing 7-4 shows how to use CGL to set up a context that uses a single renderer. The attribute kCGLPFAFullScreen ensures that OpenGL does not provide the fallback option of the software renderer.

Listing 7-4  Setting a CGL context to use a specific display

#include <OpenGL/OpenGL.h>
CGLPixelFormatAttribute attribs[] = { kCGLPFADisplayMask, 0,
                                 kCGLPFAFullScreen,
                                 kCGLPFADoubleBuffer,
                                  0 };
CGLPixelFormatObj pixelFormat = NULL;
long numPixelFormats = 0;
CGLContextObj cglContext = NULL;
CGDirectDisplayID display = CGMainDisplayID ();
// Adds the  display mask attrib for selected display
attribs[1] = CGDisplayIDToOpenGLDisplayMask (display);
CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats);

See Also

Reference documentation for buffer and renderer attributes in the Constants sections of:



< Previous PageNext Page > Hide TOC


© 2004, 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-06-09)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.