ADC Home > Reference Library > Technical Q&As > Graphics & Imaging > OpenGL >

Sharpening Full Scene Anti-Aliasing Details


Q: How can I use OpenGL Full Scene Anti-Aliasing in my Application?

A: Full scene anti-aliasing (FSAA) on Mac OS X is supported via the ARB_multisample OpenGL extension. This is the OpenGL Architecture Review Board (ARB) standardized method of doing scene based anti-aliasing which takes multiple samples at a point and combines this with coverage values to arrive at a final fragment. For more general information on the OpenGL extensions see Technical Note TN2080 "OpenGL Functionality"

Note:
If a client application is looking for just point or line anti-aliasing they may want to use the built in OpenGL point and line aliasing functions. See Section 3.4.2 in the OpenGL Specification.

Clients should understand what the multi-sample extension does and does not do. The number of samples of a scene are increased, currently by either 2, 4 or 6 times, depending on supporting hardware and VRAM available. The position of each sample does not change from the standard case but a coverage value is added to aid in determining the final color contribution. This means the edges of polygons are smoothed but the textures are not super-sampled (i.e., sampled at a larger number of locations). The extension does require the creation of a multi-sample buffer which consumes memory equal to: (number of samples) x (current back buffer size) and the Depth buffer is increased in size to match the multi-sample buffer size thus consuming (number of samples) x (current depth buffer size in bytes) bytes of memory.

Set up of FSAA is fairly straight forward but does have a couple of pitfalls. There are 2 required steps and one optional one. First, some additional attributes are added to the pixel format request. Second multi-sample is enabled. Lastly, a client can optionally pass multi-sample filter hints to OpenGL which may allow the graphics card to better achieve the desired results.

First one must add the "samples" and "sample buffers" attributes to the pixel format request. The samples attribute controls the number of samples to be taken at a single point and thus the general quality of the anti-aliasing. The acceptable values for samples are 2, 4 or 6 currently with VRAM, performance and card capabilities limiting the clients choice. Sample buffers controls the actual number of multi-sample buffers and currently only one is supported. Additionally, almost all clients will want to also specify the "no recovery" attribute, which will eliminate the normal software fallback renderer that would prevent OpenGL from returning a valid pixel format since the software renderer currently does not support multi-sample. Lastly, not all hardware is capable of supporting the ARB multi-sample extension. This can be determined through standard extension checking techniques outlined in Technical Note TN2080 "OpenGL Functionality". If this is the case, clients can, if they choose, exclude unsupported hardware from the pixel format search by specifying only the hardware which supports the extension or they can leave unsupported hardware in the search. Excluding hardware is accomplished by specifying only the displays that support ARB_multisample to the choose pixel format function, either in the pixel format attributes, for CGL and NSGL, or directly in the aglChoosePixelFormat function call for AGL and will result in these displays not rendering anything when content is using this renderer for display. Including unsupported hardware in the pixel format selection will result in normal aliased rendering on unsupported displays rather than multi-sampled rendering. Table 1 lists the exact attribute names called out in this description. For more information on the different OpenGL interface API's see Technical Q&A QA1269 "Mac OS X OpenGL Interfaces"

Note:
Even if a multi-sample buffer with the requested number of samples can be created in available VRAM, it may be large enough to affect the ability of OpenGL to maintain a proper working texture set or it could use so much of the graphics cards' available fill rate that considerable performance degradation would occur. It is recommended that developers leave the option of doing FSAA with the user and give the user a simple control, possibly a slider, that controls the quality of the multi-sampling including number of samples and filter hints (see below).


Table 1. Pixel Format Constants.

 
CGL NSOpenGLPixelFormat AGL
Samples
kCGLPFASamples NSOpenGLPFASamples AGL_SAMPLES_ARB
Sample Buffers
kCGLPFASampleBuffers NSOpenGLPFASampleBuffers AGL_SAMPLE_BUFFERS_ARB
No Recovery
kCGLPFANoRecovery NSOpenGLPFANoRecovery AGL_NO_RECOVERY

The pixel format and context setup code looks very similar to what clients normally use. Listing 1 shows pixel format creation code for all three OpenGL interface API's. One sees the attribute handling is the same for all three listings, though with minor function and constant name differences. The context creation is slightly different for the API's thus the method of specifying capable screens is different. The outcome will be the same; a pixel format that contains the valid specified screens and represents the set of renderers on the screens without a software fallback.

Listing 1a. CGL Pixel Format and Context Setup for Anti-Aliasing.

#include <OpenGL/OpenGL.h>

CGLPixelFormatAttribute attribs[] = { kCGLPFADisplayMask, 0,
                                      kCGLPFAFullScreen,
                                      kCGLPFADoubleBuffer,
                                      kCGLPFASampleBuffers, 1,
                                      kCGLPFASamples, 2,
                                      kCGLPFANoRecovery,
                                      0 };
CGLPixelFormatObj pixelFormat = NULL;
CGLContextObj context = NULL;
long numPixelFormats = 0;
 
// use main display for demonstration purposes
// need to capture and set display mode (not shown in this code)
// set display mask in pixel format attributes
attribs[1] = CGDisplayIDToOpenGLDisplayMask (CGMainDisplayID ());

CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats));

// build context
if (pixelFormat) {
    CGLCreateContext (pixelFormat, NULL, &context);
    CGLDestroyPixelFormat (pixelFormat);
}

Listing 1b. NSOpenGL Pixel Format and Context Setup for Anti-Aliasing.

#import <Cocoa/Cocoa.h>

@implementation BasicOpenGLView

+ (NSOpenGLPixelFormat*)defaultPixelFormat
{
    NSOpenGLPixelFormatAttribute attributes [] = {
        NSOpenGLPFAWindow,
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFASampleBuffers, 1, 
        NSOpenGLPFASamples, 2,
        NSOpenGLPFANoRecovery,
        (NSOpenGLPixelFormatAttribute)nil
    };
    return [[[NSOpenGLPixelFormat alloc] 
                        initWithAttributes:attributes] autorelease];
}

-(id) initWithFrame: (NSRect) frameRect
{
    NSOpenGLPixelFormat *pixelFormat = [BasicOpenGLView defaultPixelFormat];

    self = [super initWithFrame: frameRect pixelFormat: pixelFormat];
    return self;
}

// other class methods defined here

@end

Listing 1c. AGL Pixel Format and Context Setup for Anti-Aliasing.

#include <AGL/agl.h>

GLint attribs[] = { AGL_RGBA, AGL_DOUBLEBUFFER, 
                    AGL_SAMPLE_BUFFERS_ARB, 1, 
                    AGL_SAMPLES_ARB, 2, 
                    AGL_NO_RECOVERY, 
                    AGL_NONE };
     
AGLPixelFormat pixelFormat = NULL;
AGLContext context = NULL;

// could provide a list of GDHandles for supported displays here
pixelFormat = aglChoosePixelFormat (NULL, 0, attribs);

// build context
if (pixelFormat) {
    context = aglCreateContext (pixelFormat, NULL);
    aglDestroyPixelFormat (pixelFormat);
}

After a multi-sample capable context has been created, multi-sampling is enabled with glEnable by specifying the GL_MULTISAMPLE_ARB capability. Regardless of the enabled state, rendering always goes through the multi-sample buffer, if one was created with the pixel format. When multi-sample is disabled, all coverage values will be set to one giving the appearance of non-multi-sample rendering. If the correct buffers have not been created in the pixel format, enabling multi-sample will do nothing.

Note:
Currently, ATI graphics hardware prior to the Radeon 9800 Pro and Radeon 9600 Pro do not support the enable flag for multi-sampling, leaving it enabled in all cases. It is recommended that client correctly set the enable flag for the context as needed but not expect glDisable to be respected for certain ATI hardware.

Rendering hints for multi-sampling are supported through the GL_MULTISAMPLE_FILTER_HINT_NV extension. Hints for either faster or nicer rendering can be added with the standard glHint API using GL_MULTISAMPLE_FILTER_HINT_NV as the target. A hint is optional and not all hardware will be able to comply with the hint but it gives OpenGL more information about what path the clients prefer thus clients should issue hints when able and appropriate. Specifically, clients can hint that OpenGL should either the GL_FASTEST or GL_NICEST rendering algorithm, allowing the hardware to optimized the output as it is able. There is no penalty for issuing a unsupported hint and no error will be returned. Listing 2 shows code for these final two steps to enable multi-sample and send a rendering hint to OpenGL.

Listing 2. Enabling multi-sampling and setting a rendering hint.

#include <OpenGL/gl.h>
#include <OpenGL/glext.h>

glEnable (GL_MULTISAMPLE_ARB);
glHint (GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);

This concludes the discussion of using the ARB_multisample OpenGL extension for full scene anti-aliasing on Mac OS X. Applications can easily provide a enhanced user experience by providing user control over FSAA in their OpenGL application. The set up and support is simple and allowing user interaction optimizes user experience for different system capabilities and user desires.


[Oct 10, 2003]


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.