Introduction
This article is about a simple but effective way to perform real-time antialiasing (yes, real-time) using just plain Windows GDI. There is no default method under GDI to do this directly. All GDI methods like LineTo()
, Ellipse()
etc. will perform their drawing but will take no antialiasing into consideration when there comes rendering pixels to memory or screen bitmaps. How to do this then? Well, here is the possible answer to this question.
Background
There are some (but not many) articles on The Code Project which speak about the antialiasing problem when performing drawing under Windows GDI. In fact, the antialiasing should produce a high quality rendering with no jagged-edges visible. It costs more CPU cycles to finish the drawing, but at the end it looks just great. For a detailed explanation of the aliasing problem and the possible solution, please read CT Graphics - Anti Alias C++ Drawing or Antialiasing - Wu Algorithm. One will find enough information to build her or his own antialiasing rendering method, no doubt.
Using the Code
There is no special class or method provided in this article, only the general algorithm which is very easy to implement and the demo project in the download section. Here is the pseudo-code:
//
// 1. Create original bitmap for drawing
// 2. Create temporary bitmap (2x, 4x or 8x) larger than the original bitmap
// 3. Render your graphics to this large temporary bitmap
// (use any GDI method, pen or brush you like)
// but scale the graphics appropriately
// 4. Draw this temporary bitmap on the original bitmap scaled
// (i.e. using StretchDIBits() method or any other you like),
// but call SetStretchBltMode(HALFTONE)
// before this last step for the original DC
// (which holds the original bitmap), and after scaling restore it back
//
After completing these four steps, you have done it. You'll get very nice graphics on the destination bitmap.
What About the Price
When it comes to the price of applying the described method, there are a few things that one must take into consideration:
- Since the Windows GDI is not a speed recorder, when it comes to rendering, the original bitmap must have some reasonable dimensions, say 640*480 pixels to use 4x4 antialiasing by supersampling, or 320*240 to use 8x8 antialiasing by supersampling. These settings will work in a real-time loop with almost no optimizations, but if you prefer larger high-quality rendered pictures then forget about the real-time rendering using GDI. It's just too slow for this situation. However, if you don't have a real-time project to deal with, you can render an image of any size you like. Only a free RAM available on your system can stop you then.
- Increasing the antialiasing grid from 2x2 to 4x4 increases the memory consumption 4 times, and that is 16 times more memory then you need to hold the original bitmap. This is the real price you pay for using this simple method.
- For animations, keep low antialiasing grid size, no more then 2x2. This gives quite good rendering results with a good frame rate too.
Points of Interest
I have found a simple way to perform antialiasing using just Windows GDI with no third party libraries, no GDI+ etc. It was very interesting to compare the final results with the commercial libraries.