GTK and OpenGL without GTKGLExt

Carlos Pereira jose.carlos.pereira at ist.utl.pt
Tue Apr 6 15:55:19 PDT 2010


In my previous message, one of the links was wrong (/src/ missing):

A big, under test, application can be found here (or in Download page):
http://www.gamgi.org/src/gamgi-all-0.14.7-exp.tar.gz

Sorry, sorry...
Carlos
> Hi,
>
> I wrote some code to build GTK / OpenGL applications that doesn't need 
> GTKGLExt or GTKGLArea libraries. The whole thing comes down to about 
> 30-40 lines of C code.
>
> I am posting this here because I would like very much to hear your 
> comments and suggestions: what mistakes am I doing? are there mem 
> leaks? how to make it more robust? how to make it even more simple? is 
> this a good ideia at all?
>
> I tested this code on Ubuntu 9.10 x86 (GTK 2.18.3), with more than 30 
> windows open simultaneously, each one with a drawing area, sharing 
> more than 200 pre-compiled OpenGL lists, with more than 30 lights, 
> creating and removing windows on the fly, and everything seems to work 
> fine.
>
> A very simple working example can be found here: (I deliberately 
> removed all error checks, to make this example as simple and clear as 
> possible. For comparison, I included also the corresponding version 
> with GTKGLExt):
> http://www.gamgi.org/gtk_opengl.tar.gz
>
> A big, under test, application can be found here:
> http://www.gamgi.org/gamgi-all-0.14.7-exp.tar.gz
>
> Essentially everything comes down to this: disable GTK double 
> buffering for drawing area and create a new OpenGL context:
>
> #include <GL/glx.h>
> #include <gdk/gdkx.h>
>
> GtkWidget *area;
> GdkVisual* visual;
> GdkColormap *colormap;
> GdkScreen *screen;
> XVisualInfo *xvisual;
> Colormap xcolormap;
> Display *display;
> Window root;
> int xscreen;
> int attributes[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
> GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, True, GLX_DEPTH_SIZE, 12, None };
>
> area = gtk_drawing_area_new ();
> gtk_widget_set_double_buffered (area, FALSE);
>
> display = gdk_x11_get_default_xdisplay ();
> xscreen = DefaultScreen (display);
> screen = gdk_screen_get_default ();
> xvisual = glXChooseVisual (display, xscreen, attributes);
> visual = gdk_x11_screen_lookup_visual (screen, xvisual->visualid);
> root = RootWindow (display, xscreen);
> xcolormap = XCreateColormap (display, root, xvisual->visual, AllocNone);
> colormap = gdk_x11_colormap_foreign_new (visual, xcolormap);
> gtk_widget_set_colormap (area, colormap);
> context = glXCreateContext (display, xvisual, NULL or previous 
> context, TRUE);
>
> To set the context in GTK callbacks, use this:
>
> GdkWindow *window = gtk_widget_get_window (area);
> Display *display = gdk_x11_drawable_get_xdisplay (window);
> int id = gdk_x11_drawable_get_xid (window);
>
> if (glXMakeCurrent (display, id, context) == TRUE)
>  {
>  ... OpenGL here ...
>
>  glXSwapBuffers (display, id);
>  }
>
> My main question is, to create a GL context, I have to allocate 
> resources, that must be freed later. Which resources shall I free 
> myself, and when?
>
> Currently I do this:
>
> 1) free XVisualInfo immediately after creating each GL context:
> XFree (xvisual);
>
> 2) free XColormap and GdkColormap when the corresponding drawing area 
> is removed:
>
> glXDestroyContext (display, context);
> XFreeColormap (display, xcolormap);
> g_object_unref (G_OBJECT (colormap));
>
> 3) question: shall I free the X and GDK visuals in the end, when 
> removing the last GL context (before closing the application)?
>
> XFree (xvisual);
> g_object_unref (G_OBJECT (visual));
>
> I am not a X or GTK expert, so I would like to hear your comments on 
> this... if this is not the right place to ask, then my apologies...
>
> Thank you very much!
> Carlos
>




More information about the xorg mailing list