2D antialiased graphics using OpenGL

Keith Packard keithp@keithp.com
Thu, 11 Dec 2003 10:55:18 -0800


Around 12 o'clock on Dec 11, "Martijn Sipkema" wrote:

> I've taken a quick look at cairo at if I understand correctly it draws
> back-to-front

cairo is an immediate mode library, so it draws in whatever order the 
application requests it to.  It exposes the GL_SRC_ALPHA_SATURATE operator 
so that applications may use it if they so choose.  Note that cairo 
doesn't dictate what destination format is used, so applications would 
have to find something suitable before using this operator.  The Render 
extension can use external alpha buffers so that a 16 bit screen can still 
use destination alpha operators.

> Handling gamma correction in the framebuffer is a pain. Can't we just
> assume that the framebuffer is gamma corrected?

Heh.  Linear frame buffers need to be 10 to 12 bits per component to avoid 
visible banding in continuous tone images.  Turns out that the weird 
exponential behaviour of the classic CRT matches the intensity response 
curve of the eye well enough that 8 bits per component is usable in that 
space.  A happy coincedence, but it does mean significantly more 
computation to take advantage of it.

As usual, Jim Blinn has a pretty good exposition of this behaviour in an 
article called 'Dirty Pixels', published in a book of the same name.

> Sure, but relatively simple antiasliased graphics shouldn't require
> programmability.

Render provides for arbitrary filters when sampling data.  I'm hoping to 
take advantage of programmable pixel and fragment shaders to do 
convolution in the hardware so that I can have hardware accelerated 
correct gaussian blurred shadows under my windows.  The software 
implementation is "usable", but far from ideal.

> One way to draw antialiased fonts is to have the font coverage as an alpha
> channel for a texture. This will produce high quality and fast font
> rendering I think, but it doesn't take into account the location of the
> pixel components on an TFT screen.

Render exposes glyphs with precomputed opacity values for all three 
components of the screen.  As glyph hinting (at least today) requires that 
glyphs be pixel aligned, we can easily precompute the three locations of 
the glyph corresponding to the three visible components and select the 
appropriate one on the fly.  I've experimented with shifting glyphs by a 
sub pixel and the results are quite encouraging:

	http://keithp.com/~keithp/subpixel/

This was just a hack job (I rotated the PNM files by one byte), but it 
looks worth implementing for cairo to improve text spacing.  Moving from 
100dpi to 300dpi will really help match the screen with printed output.  
Of course, performance will suffer as few of the pixels are opaque or 
transparent.  But, I think I've demonstrated that really bad text 
performance doesn't really seem to bother people (current per-component 
text is drawn in software at around 50000 glyphs/sec)

> Using a high resolution bitmap alpha channel texture for the font and using
> multisample rendering for antialiasing might work also, but I doubt this
> would be of the same quality as having the font rasterizer do this.

That depends to a great extent on the desired output.  For displaying 
static text on the screen, you want to use the full hinting available in 
the font and align stems to the sub-pixel grid.  However, when animating 
text, it's important to *avoid* sub-pixel grid alignment as you get 
horrible motion artifacts.  The multi-sample technique is probably close 
to what you want, especially if you can use a gaussian filter rather than 
a box.

-keith