A rendering context has a variety of parameters that you can set to suit the needs of your OpenGL drawing. Some of the most useful, and often overlooked, context parameters are discussed in this section: swap interval, surface opacity, surface drawing order, and back-buffer size control.
Each of the Apple-specific OpenGL APIs provides a routine for setting and getting rendering context parameters:
The setValues:forParameter: method of the NSOpenGLContext class takes as arguments a list of values and a list of parameters.
The aglSetInteger function takes as parameters a rendering context, a constant that specifies an option, and a value for that option.
The CGLSetParameter function takes as parameters a rendering context, a constant that specifies an option, and a value for that option.
Some parameters need to be enabled for their values to take effect. The reference documentation for a parameter indicates whether a parameter needs to be enabled. See NSOpenGLContext Class Reference, AGL Reference, and CGL Reference.
Swap Interval
Surface Opacity
Surface Drawing Order
Vertex and Fragment Processing
Back Buffer Size Control
The swap interval parameter synchronizes the vertical retrace. If the swap interval is set to 0 (the default), buffers are swapped as soon as possible, without regard to the vertical refresh rate of the monitor. If the swap interval is set to any other value, the buffers are swapped only during the vertical retrace of the monitor. For more information, see “Draw Only When Necessary.”
You can use the following constants to specify that you are setting the swap interval value:
For Cocoa, use NSOpenGLCPSwapInterval.
For Carbon, use AGL_SWAP_INTERVAL.
If you are using the CGL API, use kCGLCPSwapInterval. See Listing 6-1.
Listing 6-1 Using CGL to set up synchronization
long sync = 1; |
// ctx must be a valid context |
CGLSetParameter (ctx, kCGLCPSwapInterval, &sync); |
OpenGL surfaces are typically rendered as opaque. Thus the background color for pixels with alpha values of 0.0 is the surface background color. If you set the value of the surface opacity parameter to 0, then the contents of the surface are blended with the contents of surfaces behind the OpenGL surface. This operation is equivalent to OpenGL blending with a source contribution proportional to the source alpha and a background contribution proportional to 1 minus the source alpha. A value of 1 means the surface is opaque (the default); 0 means completely transparent.
You can use the following constants to specify that you are setting the surface opacity value:
For Cocoa, use NSOpenGLCPSurfaceOpacity.
For Carbon, use AGL_SURFACE_OPACITY.
If you are using the CGL API, use kCGLCPSurfaceOpacity. See Listing 6-2.
Listing 6-2 Using CGL to set surface opacity
long opaque = 0; |
// ctx must be a valid context |
CGLSetParameter (ctx, kCGLCPSurfaceOpacity, &opaque); |
The surface drawing order parameter specifies the position of the OpenGL surface relative to the window. A value of 1 means that the position is above the window; a value of –1 specifies a position that is below the window. When you have overlapping views, setting the order to -1 causes OpenGL to draw underneath, 1 causes OpGL to draw on top. This parameter is useful for drawing user interface controls on top of an OpenGL view.
You can use the following constants to specify that you are setting the surface drawing order value:
For Cocoa, use NSOpenGLCPSurfaceOrder.
For Carbon, use AGL_SURFACE_ORDER.
If you are using the CGL API, use kCGLCPSurfaceOrder. See Listing 6-3.
Listing 6-3 Using CGL to set surface drawing order
long order = –1; // below window |
// ctx must be a valid context |
CGLSetParameter (ctx, kCGLCPSurfaceOrder, &order); |
CGL provides two parameters for checking whether the system is using the GPU for processing: kCGLCPGPUVertexProcessing and kCGLCPGPUFragmentProcessing. To check vertex processing, pass the vertex constant to the CGLGetParameter function. To check fragment processing, pass the fragment constant to CGLGetParameter.
Important: Although you can perform these queries at any time, keep in mind that such queries force an internal state validation, which can impact performance. For best performance, do not use these queries inside your drawing loop. Instead, perform the queries once at initialization or context setup time to determine whether OpenGL is using the CPU or the GPU for processing, and then act appropriately in your drawing loop.
Listing 6-4 Using CGL to check whether the GPU is processing vertices and fragments
BOOL gpuProcessing; |
GLint fragmentGPUProcessing, vertexGPUProcessing; |
CGLGetParameter (CGLGetCurrentContext(), kCGLCPGPUFragmentProcessing, |
&fragmentGPUProcessing); |
CGLGetParameter(CGLGetCurrentContext(), kCGLCPGPUVertexProcessing, |
&vertexGPUProcessing); |
gpuProcessing = (fragmentGPUProcessing && vertexGPUProcessing) ? YES : NO; |
Normally, the back buffer is the same size as the window or view that it's drawn into, and it changes size when the window or view changes size. For a window whose size is 720 by 480 pixels, the OpenGL back buffer is sized to match. If the window grows to 1024 by 768 pixels, for example, then the back buffer tracks this growth. If you do not want this behavior, use the back buffer size control parameter.
Using this parameter fixes the size of the back buffer and lets the system scale the image automatically when it moves the data to a variable size buffer (see Figure 6-1). The size of the back buffer remains fixed at the size that you set up regardless of whether the image is resized to display larger onscreen.
You can use the following constants to specify that you are setting the surface drawing order value:
If you are using the CGL API, use kCGLCPSurfaceBackingSize, as shown in Listing 6-5.
For Carbon, use AGL_SURFACE_BACKING_SIZE.
Listing 6-5 Using CGL to set up back buffer size control
long dim[2] = {720, 480}; |
// ctx must be a valid context |
CGLSetParameter(ctx, kCGLCPSurfaceBackingSize, dim); |
CGLEnable (ctx, kCGLCESurfaceBackingSize); |
Last updated: 2008-06-09