This section describes the steps for setting up onscreen drawing to a Carbon window. To get an idea of how these steps fit into an full application, you should look at the sample application GLCarbonAGLWindow.
Follow these steps to use the AGL API to set up onscreen drawing to a Carbon window:
Set up an array of attributes that describes the buffer characteristics and renderer capabilities that you want. You can supply any of the pixel format attributes or extended attributes defined in AGL Constants in AGL Reference.
This example in Listing 2-10 sets up attributes for RGBA, double buffering, and a pixel depth of 24 bits. Your code would set up whatever attributes are appropriate. In later chapters in this book, you'll see how to choose attributes for specific purposes. (See “Techniques for Choosing Attributes.”)
Obtain a pixel format object by passing the attributes array to the function aglChoosePixelFormat.
The pixel format object contains a list of all appropriate renderer-display combinations. In the example shown here, it's likely that the list will contain at least two items—one that uses a hardware renderer and another that uses a software renderer.
Bind the pixel format object to a rendering context by passing the pixel format object to the function aglCreateContext.
If the pixel format object has more than one pixel format (renderer-display combination) in it, AGL uses the first in the list. You can call the function aglNextPixelFormat if you want to use the next pixel format in the list.
Release the pixel format object by calling the function aglDestroyPixelFormat.
Get the port associated with the Carbon window that you want to draw into by calling the Window Manager function GetWindowPort. After you attach a rendering context to the Carbon window, its viewport is set to the full size of the window.
Note: The AGL API for drawing to a Carbon window was developed prior to Mac OS X. Because of this heritage, the AGLDrawable data type is a CGrafPtr data type under the hood. That's why you must call GetWindowPort to obtain the associated graphics port from the WindowRef data type passed to MySetWindowAsDrawableObject.
Bind the window to the rendering context by passing the port to the function aglSetDrawable.
Make the rendering context the current context by calling function aglSetCurrentContext.
Listing 2-10 shows how to implement these steps and how to check for errors along the way by calling the application-defined function MySetWindowAsDrawableObject. It's recommended that your application provides a similar error-checking function. In the case of an error you'll either want to notify the user and abort the program or take some sort of fallback action that ensures you application can draw OpenGL content. (See “Ensuring a Valid Pixel Format Object” for an example of backing out of attributes. See “Retrieve Error Information Only When Debugging” for guidelines on error checking and performance.)
Note that the example passes the pixel format object returned from the aglChoosePixelFormat function to the function aglCreateContext. By default, AGL uses the first pixel format in the pixel format object regardless of how many pixel formats are actually in the object. You can iterate through the pixel format object using the functionaglNextPixelFormat.
Listing 2-10 Setting a Carbon window as a drawable object
OSStatus MySetWindowAsDrawableObject (WindowRef window) |
{ |
OSStatus err = noErr; |
Rect rectPort; |
GLint attributes[] = { AGL_RGBA, |
AGL_DOUBLEBUFFER, |
AGL_DEPTH_SIZE, 24, |
AGL_NONE }; |
AGLContext myAGLContext = NULL; |
AGLPixelFormat myAGLPixelFormat; |
myAGLPixelFormat = aglChoosePixelFormat (NULL, 0, attributes); |
err = MyAGLReportError (); |
if (myAGLPixelFormat) { |
myAGLContext = aglCreateContext (myAGLPixelFormat, NULL); |
err = MyAGLReportError (); |
} |
if (! aglSetDrawable (myAGLContext, GetWindowPort (window))) |
err = MyAGLReportError (); |
if (!aglSetCurrentContext (myAGLContext)) |
err = MyAGLReportError (); |
return err; |
} |
OSStatus MyAGLReportError (void) |
{ |
GLenum err = aglGetError(); |
if (AGL_NO_ERROR != err) { |
char errStr[256]; |
sprintf (errStr, "AGL: %s",(char *) aglErrorString(err)); |
reportError (errStr); |
} |
if (err == AGL_NO_ERROR) |
return noErr; |
else |
return (OSStatus) err; |
} |
Note: Although this example shows how to draw OpenGL content to an entire Carbon window, it is possible for Carbon applications to draw to a part of a window. Carbon developers can find additional information on using windows by reading Handling Carbon Windows and Controls.
Last updated: 2008-06-09