Using cairo with OpenGL

These are my humble beginnings of writing up a tutorial on using cairo with OpenGL. The general view-point of this document is that of a Linux-developer. Please feel free to add your examples and experience from other use-cases (preferably with sourcecode) gained on other platforms. This document assumes some familiarity with the APIs of cairo and OpenGL, the typical development tool-chain under Linux and some graphics-programming in general. Furthermore I want to point out, that I am not an native english speaker and cannot guarantee this text to be error-free.

Typical benefits

So why would you want to mix vector-graphics rendering, provided by cairo, with OpenGL in the first place? Well, there are a few obvious advantages that come to mind...

General approach

Which steps should one usually take in order to get cairo-drawn vector-graphics into an OpenGL-rendered scene...

Our version of "Hello, world!"

This example program tries to be as simple as possible, without being too boring. It is written in plain ANSI C and uses cairo, OpenGL and SDL. Thus it should "translate" to other platforms or languages without much effort. Download the sources with this command...

git clone git://people.freedesktop.org/~macslow/gl-cairo-simple

... or grab the automatically generated tarball gl-cairo-simple.tar.bz2 (SHA1SUM)

If you have all needed libraries and header-files in place a simple make will compile the program. The result will look something like this...

gl-cairo-simple screenshot

The above image is actually a link to an ogg/theora video, which is about 2 MBytes large. You can see that the graphics adapt to the window-size (due to the screen-capture a bit jerky in response) and during the demonstration the line-thickness is changed with the scroll-wheel of the mouse. The frame-dumps shown after each run are triggered with the d-key.

To avoid blowing up this tutorial, I did not copy&paste the whole sourcecode into this document. The sourcecode is thoroughly commented to help you understand what goes on. Should you have questions, suggestions or patches, feel free to send them to me (macslow@bangang.de).

Beef it up a little

Here is an example-program, that shows off a bit more than the previous "Hello, world!"-variant. It creates three cairo-surfaces (and contexts) and a corresponding OpenGL-texture-object for each of them. In the animation-loop each cairo-surface is refreshed with different contents, that is then copied to an OpenGL-texture and finally mapped on one side of a cube. It addition to cairo and OpenGL it makes use of GTK+ and GtkGlExt for the typical windowing-system boilerplate-code. You can grab the up-to-date version of this with...

git clone git://people.freedesktop.org/~macslow/gl-cairo-cube

... or grab the automatically generated tarball gl-cairo-cube.tar.bz2 (SHA1SUM)

Once successfully compiled it will look like this...

gl-cairo-cube screenshot

The above image is also a link to an ogg/theora video, which is about 2.9 MBytes in size, so you can see if it's worth trying out getting cairo and OpenGL do their stuff together. You can quit the program with the q- or esc-key, change the overall transparency with the mouse-wheel, rotate the object with LMB-drag and zoom it with RMB-drag. To move the object around on the desktop you'll have to setup your window-manager to trigger window-movement on Alt-LMB-drag. Again, if you have questions, suggestions or patches regarding this program, feel free to send them to me (macslow@bangang.de).

Something with a bit more glitz

This is an example demonstrating how to setup a glitz-backend and use that for rendering cairo via OpenGL. You can pass -n on the commandline to avoid using glitz and fallback to the image-backend, which should run nearly on every system. To throttle the framerate you can pass -r and the program will try to match that frame-rate. The default is to try to render with 30 Hz. Be sure to read the supplied README from the git-repository or tarball.

git clone git://people.freedesktop.org/~macslow/glitz-test

... or grab the automatically generated tarball glitz-test.tar.bz2 (SHA1SUM)

Once successfully compiled it will look like this (depending wether you have a composited environment or not)...

twirling farsi screenshot

composited twirling farsi screenshot

The above images are links to ogg/theora videos, which are 1.6 MBytes and 1.3 MBytes in size. You can quit the program with the q- or esc-key, change the demos with the F1..F4 keys, or mouse-wheel or cursor keys, or PageUp/PageDown keys. Space toggles between pause and animation. If you have questions, suggestions or patches regarding this program, feel free to send them to me (macslow@bangang.de).

Use cairo for an anti-aliasing trick

Here a clever method is demonstrated to get edge-anti-aliasing for textured single quads or rectangles. The computational costs are negligible compared to usual multi- or super-sample based anti-aliasing. The demonstrated technique needs OpenGL-hardware, which is capable of texture-mapping though. The main idea is to leverage the texture-filtering functions available on OpenGL-cards to do some filtering for us on a cleverly modified texture-image. The edges of an image have to be trimmed slightly for this to take effect. The cairo-API offers the right means to easily trim an image in advance before uploading it to the OpenGL-card as texture-object. Thanks to cairo it is also very simple to add nicely rounded corners to the texture image to further improve the smooth look of the final object on screen.

The visual improvement can be clearly seen in this screenshot...

You can check it out the sources via git, like this...

git clone git://people.freedesktop.org/~macslow/gl-cairo-aatrick

... or grab the automatically generated tarball gl-cairo-aatrick.tar.bz2 (SHA1SUM)

Once successfully compiled it will look like this when running...

The above image is a link to an ogg/theora video, which is 1.4 MBytes in size. You can quit the program with the q- or esc-key and space toggles between pause and animation. If you have questions, suggestions or patches regarding this program, feel free to send them to me (macslow@bangang.de).

Further reading