Aliasing is the bane of the digital domain. In the early days of the personal computer, jagged edges and blocky graphics were accepted by the user simply because not much could be done to correct them. Now that hardware is faster and displays are higher in resolution, there are several anti-aliasing techniques that can smooth edges to achieve a more realistic scene.
OpenGL supports anti-aliasing that operates at the level of lines and polygons as well as at the level of the full scene. This chapter discusses techniques for full scene anti-aliasing (FSAA). The three anti-aliasing techniques in use today are multisampling, supersampling, and alpha channel blending:
Multisampling defines a technique for sampling pixel content at multiple locations for each pixel. This is a good technique to use if you want to smooth polygon edges.
Supersampling renders at a much higher resolution than what's needed for the display. Prior to drawing the content to the display, OpenGL scales and filters the content to the appropriate resolution. This is a good technique to use when you want to smooth texture interiors in addition to polygon edges.
Alpha channel blending uses the alpha value of a fragment to control how to blend the fragment with the pixel values that are already in the framebuffer. It's a good technique to use when you want to ensure that foreground and background images are composited smoothly.
The ARB_multisample
extension defines a specification for full scene anti-aliasing. It describes multisampling and alpha channel sampling. The specification does not specifically mention supersampling but its wording doesn't preclude supersampling. The anti-aliasing methods that are available depend on the hardware and the actual implementation depends on the vendor. Some graphics cards support anti-aliasing using a mixture of multisampling and supersampling. The methodology used to select the samples can vary as well. Your best approach is to query the renderer to find out exactly what is supported. OpenGL lets you provide a hint to the renderer as to which anti-aliasing technique you prefer. Hints are available starting in Mac OS X v10.4 as renderer attributes that you supply when you create a pixel format object.
Guidelines
General Approach
Hinting for a Specific Anti-Aliasing Technique
Setting Up Full Scene Anti-Aliasing
See Also
You'll want to keep the following in mind when you set up full scene anti-aliasing:
Although a system may have enough VRAM to accommodate a multisample buffer, a large buffer can affect the ability of OpenGL to maintain a properly working texture set. Keep in mind that the buffers associated with the rendering context—depth and stencil—increase in size by a factor equal to number of samples per pixel.
The OpenGL driver allocates the memory needed for the multisample buffer; your application should not allocate this memory.
Any anti-aliasing algorithm that operates on the full scene requires a fair amount of computing resources. In some cases, there is a tradeoff between performance and quality. For that reason, developers sometimes provide a user interface element that allows the user to enable and disable FSAA, or to choose the level of quality for anti-aliasing.
The commands glEnable(GL_MULTISAMPLE)
and glDisable(GL_MULTISAMPLE)
are ignored on some hardware because some graphics cards have the feature enabled all the time. That doesn't mean that you should not call these commands because you'll certainly need them on hardware that doesn't ignore them.
A hint as to the variant of sampling you want is a suggestion, not a command. Not all hardware supports all types of anti-aliasing. Other hardware mixes multisampling with supersampling techniques. The driver dictates the type of anti-aliasing that's actually used in your application.
The best way to find out which sample modes are supported is to call the CGL function CGLDescribeRenderer
with the renderer property kCGLRPSampleModes
or kCGLRPSampleAlpha
.
The general approach to setting up full scene anti-aliasing is as follows:
Check to see what's supported. Not all hardware is capable of supporting the ARB multisample extension, so you need to check for this functionality (see “Detecting Functionality”).
To find out what type of anti-aliasing a specific renderer supports, call the function CGLDescribeRenderer
. Supply the renderer property kCGLRPSampleModes
to find out whether the renderer supports multisampling and supersampling. Supply kCGLRPSampleAlpha
to see whether the renderer supports alpha sampling.
You can choose to exclude unsupported hardware from the pixel format search by specifying only the hardware that supports multisample anti-aliasing. Keep in mind that if you exclude unsupported hardware, the unsupported displays will not render anything. If you instead choose to include unsupported hardware, OpenGL uses normal aliased rendering to the unsupported displays and multisampled rendering to supported displays.
Include these buffer attributes in the attributes array:
The appropriate sample buffer attribute constant (NSOpenGLPFASampleBuffers
, AGL_SAMPLE_BUFFERS_ARB
, or kCGLPFASampleBuffers
) along with the number of multisample buffers. At this time the specification allows only one multisample buffer.
The appropriate samples constant (,NSOpenGLPFASamples
, AGL_SAMPLES_ARB
, or kCGLPFASamples
) along with the number of samples per pixel. You can supply 2, 4, 6, or more depending on what the renderer supports and the amount of VRAM available. The value that you supply affects the quality, memory use, and speed of the multisampling operation. For fastest performance, and to use the least amount of video memory, specify 2 samples. When you need more quality, specify 4 or more.
The no recovery attribute ( NSOpenGLPFANoRecovery
, AGL_NO_RECOVERY
, or kCGLPFANoRecovery
). Although enabling this attribute is not mandatory, it's recommended to prevent OpenGL from using software fallback as a renderer. The software renderer does not support multisample antialiasing prior to Mac OS X v10.4. In versions that the software renderer does support multisampling (4, 9, or 16 samples), antialiasing performance is slow.
Optionally provide a hint for the type of anti-aliasing you want—multisampling, supersampling, or alpha sampling. See “Hinting for a Specific Anti-Aliasing Technique.”
Enable multisampling with the following command:
glEnable(GL_MULTISAMPLE)
;
Regardless of the enabled state, OpenGL always uses the multisample buffer if you supply the appropriate buffer attributes when you set up the pixel format object. If you haven't supplied the appropriate attributes, enabling multisampling has no effect.
When multisampling is disabled, all coverage values are set to 1
, which gives the appearance of rendering without multisampling.
Some graphics hardware leaves multisampling enabled all the time. However, don't rely on hardware to have multisampling enabled; use glEnable
to programmatically turn on this feature.
Optionally provide hints for the rendering algorithm. You perform this optional step only if you want OpenGL to compute coverage values by a method other than uniformly weighting samples and averaging them.
Some hardware supports a multisample filter hint through an OpenGL extension—GL_NV_multisample_filter_hint
. This hint allows an OpenGL implementation to use an alternative method of resolving the color of multisampled pixels.
You can specify that OpenGL uses faster or nicer rendering by calling the OpenGL function glHint
, passing the constant GL_MULTISAMPLE_FILTER_HINT_NV
as the target parameter and GL_FASTEST
or GL_NICEST
as the mode parameter. Hints allow the hardware to optimize the output if it can. There is no performance penalty or returned error for issuing a hint that's not supported.
For more information, see the OpenGL extension registry for NV_multisample_filter_hint.
“Setting Up Full Scene Anti-Aliasing” provides specific code examples.
In Mac OS X v10.4 and later, when you set up your renderer and buffer attributes for full scene antialiasing, you can specify a hint to prefer one anti-aliasing technique over the others. If the underlying renderer does not have sufficient resources to support what you request, OpenGL ignores the hint. If you do not supply the appropriate buffer attributes when you create a pixel format object, then the hint does nothing. Table 10-1 lists the hinting constants available for the NSOpenGLPixelFormat
class, AGL, and CGL.
Multisampling | Supersampling | Alpha blending |
---|---|---|
|
|
|
|
|
|
|
|
|
The code listings in this section show how to set up full scene anti-aliasing using the NSOpenGLPixelFormat
class, AGL, and CGL. You'll see that the code to set buffer and renderer attributes and to create a context looks similar to what you'd normally use to set up any rendering context. Regardless of the API that you use, you need to specify the appropriate attributes. Although you need to specify the context slightly differently for each of the APIs, the outcome is the same—a pixel format and context that supports full-scene anti-aliased rendering.
Listing 10-1 sets up full scene anti-aliasing using the NSOpenGLPixelFormat
class, but does not provide a hint, which is optional. A detailed explanation for each numbered line of code appears following the listing.
Listing 10-1 Using NSOpenGLPixelFormat
to set up full scene anti-aliasing
#import <Cocoa/Cocoa.h> |
@implementation BasicOpenGLView |
+ (NSOpenGLPixelFormat*)defaultPixelFormat |
{ |
NSOpenGLPixelFormatAttribute attributes [] = { // 1 |
NSOpenGLPFAWindow, |
NSOpenGLPFADoubleBuffer, |
NSOpenGLPFASampleBuffers, 1, |
NSOpenGLPFASamples, 2, |
NSOpenGLPFANoRecovery, |
(NSOpenGLPixelFormatAttribute)nil |
}; |
return [[[NSOpenGLPixelFormat alloc] |
initWithAttributes:attributes] autorelease]; // 2 |
} |
-(id) initWithFrame: (NSRect) frameRect |
{ |
NSOpenGLPixelFormat *pixelFormat = [BasicOpenGLView |
defaultPixelFormat]; // 3 |
self = [super initWithFrame: frameRect |
pixelFormat: pixelFormat]; // 4 |
return self; |
} |
// Define other class methods here. |
@end |
Here's what the code in Listing 10-1 does:
Sets up attributes for OpenGL to use for choosing the pixel format. The attributes include the two required for multisampling: NSOpenGLPFASampleBuffers
and NSOpenGLPFASamples
, along with those to support a Cocoa window, double buffering, and no recovery.
Allocates and initializes an NSOpenGLPixelFormat
object with the requested multisampling (and other) attributes.
Creates an NSOpenGLPixelFormat
object for a custom NSOpenGLView
class (BasicOpenGLView
) that was previously created by the application using Interface Builder but is not shown in this example.
Initializes the view with the newly created pixel format.
Listing 10-2 sets up full scene anti-aliasing in Carbon and provides a hint for supersampling. A detailed explanation for each numbered line of code appears following the listing.
Listing 10-2 Using AGL to set up full scene anti-aliasing with a hint for supersampling
#include <AGL/agl.h> |
GLint attribs[] = { AGL_RGBA, // 1 |
AGL_DOUBLEBUFFER, |
AGL_SAMPLE_BUFFERS_ARB, 1, |
AGL_SAMPLES_ARB, 2, |
AGL_SUPERSAMPLE, |
AGL_NO_RECOVERY, |
AGL_NONE }; |
AGLPixelFormat pixelFormat = NULL; |
AGLContext context = NULL; |
pixelFormat = aglChoosePixelFormat (NULL, 0, attribs); // 2 |
if (pixelFormat) { |
context = aglCreateContext (pixelFormat, NULL); // 3 |
aglDestroyPixelFormat (pixelFormat); |
} |
Here's what the code in Listing 10-2 does:
Sets up attributes for OpenGL to use for creating an AGL pixel format object. The attributes include the two required for multisampling (AGL_SAMPLE_BUFFERS_ARB
and AGL_SAMPLES_ARB
) along with those to support RGBA pixels, double buffering, and no recovery.
Creates a pixel format object. Prior to this call you can optionally provide a list of GDHandle
values that specify the supported displays.
Creates a rendering context based on the newly created pixel format object that is set up to support full scene antialiasing.
Listing 10-3 sets up full scene anti-aliasing using the CGL API and provides a hint for multisampling. A detailed explanation for each numbered line of code appears following the listing.
Listing 10-3 Using CGL to set up full scene anti-aliasing with a hint for multisampling
#include <OpenGL/OpenGL.h> |
CGLPixelFormatAttribute attribs[] = { kCGLPFADisplayMask, 0, // 1 |
kCGLPFAFullScreen, |
kCGLPFADoubleBuffer, |
kCGLPFASampleBuffers, 1, |
kCGLPFASamples, 2, |
kCGLPFAMultisample |
kCGLPFANoRecovery, |
0 }; |
CGLPixelFormatObj pixelFormat = NULL; |
CGLContextObj context = NULL; |
long numPixelFormats = 0; |
attribs[1] = CGDisplayIDToOpenGLDisplayMask (CGMainDisplayID ()); // 2 |
CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats)); // 3 |
if (pixelFormat) { |
CGLCreateContext (pixelFormat, NULL, &context); // 4 |
CGLDestroyPixelFormat (pixelFormat); |
} |
Here's what the code in Listing 10-3 does:
Sets up attributes for OpenGL to use for creating a CGL pixel format object. The attributes include the two multisampling attributes: kCGLPFASampleBuffers
and kCGLPFASamples
, along with those to support full-screen drawing, double buffering, and no recovery. The associated value for kCGLPFASamples
is the number of samples per multisample buffer, which in this case is 2
. The associated value for kCGLPFASampleBuffers
is a nonnegative integer that indicates the number of existing independent sample buffers, which in this case is 1
.
Sets the value of the display mask attribute to the main display. (Note that this code example does not capture the main display. See Listing 3-3.)
Creates a pixel format object with the requested attributes.
Creates a context for the pixel format that isn't shared.
You can find the complete specification for the GL_ARB_multisample
extension in the OpenGL extensions registry at http://oss.sgi.com/projects/ogl-sample/registry/.
If your application needs point or line anti-aliasing instead of full scene anti-aliasing, use the built in OpenGL point and line anti-aliasing functions. These are described in Section 3.4.2 in the OpenGL Specification.
© 2004, 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-06-09)