Anti-aliasing in OpenGL

hojusaram picture hojusaram · Nov 6, 2010 · Viewed 14.2k times · Source

I just started with OpenGL programming and I am building a clock application. I want it to look something simple like this: http://i.stack.imgur.com/E73ap.jpg

However, my application looks very "un-anti-aliased" : http://i.stack.imgur.com/LUx2v.png

I tried the GL_SMOOTH_POLYGON method mentioned in the Red Book. However that doesn't seem to do a thing.

I am working on a laptop with Intel integrated graphics. The card doesn't support things like GL_ARB_multisample.

What are my options at this point to my app look anti-aliased?

Answer

Stefan Monov picture Stefan Monov · Nov 6, 2010

Intel integrated videocards are notorious for their lack of support for OpenGL antialiasing. You can work around that, however.

First option: Manual supersampling
Make a texture 2x times as big as the screen. Render your scene to the texture via FBO, then render the texture at half size so it fills the screen, with bilinear interpolation. Can be very slow (in complex scenes) due to the 4x increase in pixels to draw.

Will result in weak antialiasing (so I don't recommend it for desktop software like your clock). See for yourself:
antialiasing vs supersampling

Second option: (advanced)
Use a shader to perform Morphological Antialiasing. This is a new technique and I don't know how easy it is to implement. It's used by some advanced games.

Third option:
Use textures and bilinear interpolation to your advantage by emulating OpenGL's primitives via textures. The technique is described here.

Fourth option: Use a separate texture for every element of your clock.

For example, for your hour-arrow, don't use a flat black GL_POLYGON shaped like your arrow. Instead, use a rotated GL_QUAD, textured with a hour-arrow image drawn in an image program. Then bilinear interpolation will take care of antialiasing it as you rotate it.

This option would take the least effort and looks very well.

Fifth option:
Use a library that supports software rendering -

  • Qt
  • Cairo
  • Windows GDI+
  • WPF
  • XRender
  • etc

Such libraries contain their own algorithms for antialiased rendering, so they don't depend on your videocard for antialiasing. The advantages are:

  • Will render the same on every platform. (this is not guaranteed with OpenGL in various cases - for example, the thick diagonal "tick" lines in your screenshot are rendered as parallelograms, rather than rectangles)
  • Has a big bunch of convenient drawing functions ("drawArc", "drawText", "drawConcavePolygon", and those will support gradients and borders. also you get things like an Image class.)
  • Some, like Qt, will provide much more desktop-app type functionality. This can be very useful even for a clock app. For example:
    • in an OpenGL app you'd probably loop every 20msec and re-render the clock, and not even think twice. This would hog unnecessary CPU cycles, and wake up the CPU on a laptop, depleting the battery. By contrast, Qt is very intelligent about when it must redraw parts of your clock (e.g., when the right half of the clock stops being covered by a window, or when your clock moves the minute-arrow one step).
    • once you get to implementing, e.g. a tray icon, or a settings dialog, for your clock, a library like Qt can make it a snap. It's nice to use the same library for everything.

The disadvantage is much worse performance, but that doesn't matter at all for a clock app, and it turns around when you take into account the intelligent-redrawing functionality I mentioned.

For something like a clock app, the fifth option is very much recommended. OpenGL is mainly useful for games, 3D software and intense graphical stuff like music visualizers. For desktop apps, it's too low-level and the implementations differ too much.