Cairo+glitz/Setup glitz with glx

From Sidvind

Jump to: navigation, search

glitz is an OpenGL image compositing library partially designed to act as a cairo backend. Getting glitz to work can be a bit tricky especially due to the lack of documentation. Lack of good documentation and samples for Xlib/glx makes it even worse, but I find that common with anything related to Xlib. This will be a simple tutorial on how to get glitz to work. I assume you have a basic understanding of Xlib and glx before reading this.

[edit] Creating a window

First we open a X display as usual.

 Display* display = XOpenDisplay(NULL);
 unsigned int screen = DefaultScreen(display);

When creating the X window a XVisualInfo is needed. glitz requires a glitz_drawable_format_t which is related to the XVisualInfo. These two should match but I have seen cases where non matching similar formats has been used. I found it simpler to search for a suitable drawable format and extract the visual info from it than the other way around.

 // A template format is specified.
 glitz_drawable_format_t templ;
 templ.samples = 1;
 templ.depth_size = 24;
 templ.doublebuffer = 1;
 
 // Only the fields specified by this mask will be matched.
 unsigned long format_mask = GLITZ_FORMAT_SAMPLES_MASK | GLITZ_FORMAT_DOUBLEBUFFER_MASK | GLITZ_FORMAT_DEPTH_SIZE_MASK;
 
 // glitz_glx_find_window_format searches the available formats for one matching the template. The zero in the end specifies
 // which format to use, zero means the first matching. It is possible to iterate over the available formats by increasing
 // this value until NULL is returned.
 glitz_drawable_format_t* dformat = glitz_glx_find_window_format (display, screen, format_mask, &templ, 0);
 if (!dformat) {
 	fprintf (stderr, "Error: couldn't find window format\n");
 	return 1;
 }
 
 // As the name implies glitz_glx_get_visual_info_from_format extracts a XVisualInfo from a glitz_drawable_format_t.
 XVisualInfo* vinfo = glitz_glx_get_visual_info_from_format (display, screen, dformat);
 if (!vinfo) {
 	fprintf (stderr, "Error: no visual info from format\n");
 	return 1;
 }

Next up is actually creating the window.

 // Reference to the root-window.
 Window root = DefaultRootWindow(display);
 
 // Creates the colormap
 Colormap cmap = XCreateColormap(display, root, vinfo->visual, AllocNone);
 
 // Window attributes
 XSetWindowAttributes swa;
 swa.colormap = cmap;
 swa.event_mask = ExposureMask;
 unsigned long mask = CWColormap | CWEventMask;
 
 // Create a window using the earlier found XVisualInfo.
 Window window = XCreateWindow(display, root, 0, 0, 800, 600, 0, vinfo->depth, InputOutput, vinfo->visual, mask, &swa);
 XMapWindow(display, window);
 
 // Make it possible to "correctly" close the window.
 Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", 0);
 XSetWMProtocols(display, window, &wm_delete_window, 1);
 
 XSync(display, false);

[edit] Creating a drawable surface

After the window is created we create a glitz drawable which is used to create glitz surfaces. Behind the scenes this is kind of the OpenGL context and drawable usually created when using Xlib and OpenGL.

 // Create the glitz drawable. If this is the first time it is called it will create the opengl context and make it the current.
 glitz_drawable_t* drawable = glitz_glx_create_drawable_for_window (display, screen, dformat, window, 800, 600);
 
 // A glitz_format_t must be used when creating a surface. Not that this is not the same format as glitz_drawable_format_t used earlier.
 // Similar to before a template is created and a matching format is searched for.
 glitz_format_t *format, templ;
 glitz_drawable_buffer_t buffer;
 
 templ.color = dformat->color;
 format = glitz_find_format (drawable,
 	GLITZ_FORMAT_FOURCC_MASK     |
 	GLITZ_FORMAT_RED_SIZE_MASK   |
 	GLITZ_FORMAT_GREEN_SIZE_MASK |
 	GLITZ_FORMAT_BLUE_SIZE_MASK  |
 	GLITZ_FORMAT_ALPHA_SIZE_MASK,
 	&templ,
 	0
 );
 
 if (!format) {
 	fprintf (stderr, "Error: couldn't find surface format\n");
 	return NULL;
 }
 
 // Create a surface with above format.
 glitz_surface_t* surface = glitz_surface_create (drawable, format, 800, 600, 0, NULL);
 if (!surface) {
 	fprintf (stderr, "Error: couldn't create glitz surface\n");
 	return NULL;
 }
 
 // The surface buffer must be bound to the drawable. The surface buffer is the buffer which rendering
 // calls is made to. If a doublebuffered surface is selected the backbuffer will used.
 if (dformat->doublebuffer) {
 	buffer = GLITZ_DRAWABLE_BUFFER_BACK_COLOR;
 } else {
 	buffer = GLITZ_DRAWABLE_BUFFER_FRONT_COLOR;
 }
 
 // Bind the surface buffer to the drawable.
 glitz_surface_attach (surface, drawable, buffer);

Next part: cairo+glitz/Setup cairo.

-->
Views
Personal tools
Navigation
Toolbox