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
_______________________________________________
[email protected]: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg