GTKGL - OpenGL Hooks for GTK GTKGL allows you to draw OpenGL graphics on any drawable GTK widget. GTKGL itself has a very small API that lets you establish a GTK widget as the current OpenGL drawing destination. Then you can insert pure OpenGL code into expose-event callback functions to do the actual drawing. You can also add methods on button-press-event and key-press-event callbacks, for example, just as you would for any other GTK widget, except adding OpenGL code to them for rotating the image and so on. The GTKGL code is written on top of the GLX facility for doing OpenGL in X Windows, so you shouldn't need to call GLX functions directly. And the file opengl.cl (included with GTKGL) defines foreign functions for the entire OpenGL API, so you can call OpenGL functions as lisp functions directly. To load GTKGL, simply load the file load.cl into ACL 6.2 or 7.0. This will load GTK if needed, followed by GTKGL. Two examples are included (and are loaded by load.cl). gtkgltest.cl contains a very basic example that draws a multicolored triangle; this provides a small code example to point out what the various pieces of code are that you need to write. gtkteapot.cl is a much fancier example that draws a three-dimensional teapot that rotates when you press the arrow keys on the keyboard. You can run these examples with the forms (color-triangle) and (red-teapot). The rest of this document describes the several exported GTKGL symbols. The symbols are in the gtkgl package, and the user package will use the gtkgl package when GTKGL is loaded. If you find the GTKGL API to be insufficient, you can modify the GTKGL source code in gtkgl.cl yourself; it's rather small and fairly well documented internally. We do not supply any documentation for OpenGL itself. Of the GTKGL symbols below, you likely will need only the functions (setf current-gtkgl-widget) and swap-buffers. ------------------------------------------------------------ current-gtkgl-widget () [function] Returns the GTK widget that is the current OpenGL drawing destination, or nil if no destination has been set or the current destination is something other than a GTK widget. ------------------------------------------------------------ (setf current-gtkgl-widget)(value) [function] Call this function to specify that a particular GTK widget should start receiving all OpenGL output. Typically you would call this at the top of any expose-event callback function that calls OpenGL functions. (This function does nothing if the stream is already the current OpenGL destination.) Example: (setf (current-gtkgl-widget) my-gtk-widget) ------------------------------------------------------------ swap-buffers (gtk-widget) When using the GTK_DOUBLE_BUFFERED option (included by default), call this at the end of your OpenGL code (in your expose-event callback function) to copy the image from GLX's memory bitmap for the widget to the visible GTK widget. ------------------------------------------------------------ exit-gtkgl () [function] Call this function if desired to clean up all OpenGL resources that have been used in GTK widgets that were created in the current process. We expect that it's not necessary to call this function. ------------------------------------------------------------ *use-direct-x-connection* [global variable] This variable could be set to true if your X server is on the host computer, which may achieve much faster drawing. The default value is nil for the more typical case of a remote X server. Setting this to true has not been tested. ------------------------------------------------------------ *gtkgl-visual-attributes* [global variable] GTKGL internally calls the GLX function glXChooseVisual, passing a set of attributes for the X visual to use for OpenGL drawing. The attributes that are passed are the ones in a list that is the value of the global variable *gtkgl-visual-attributes*. By default this list contains GLX_RGBA to request true color, and GLX_DOUBLEBUFFER to request double-buffering. This list is likely adequate for most applications, but if you need to specify different attributes, then you can modify this list to contain other constants as they would be passed in the attributes vector that is passed to glXChooseVisual. Here is the definition of this variable with its default value: (defparameter *gtkgl-visual-attributes* ;; Modify this variable if needed to specify the desired ;; attributes for the X visual to be used by OpenGL. (list ;; Ask for a true-color visual rather than using palettes. GLX_RGBA ;; Specify double-buffering to eliminate flashing during ;; animation updates by first drawing on a memory bitmap. ;; (On my machine, glxChooseVisual fails without this.) GLX_DOUBLEBUFFER)) With the GXL_DOUBLEBUFFER attribute, any GTK widget that is visible on the screen will use GLX's double-buffering option. This eliminates flashing by drawing all content on a memory bitmap (the "second buffer") and then copying to the visible GTK widget at the end. This could be overridden by removing GLX_DOUBLEBUFFER from *gtkgl-visual-attributes*. When using the GLX_DOUBLEBUFFER option, you will need to turn off GTK's double-buffering for any GTK widget that is used for OpenGL. GTK does its own double-buffering by default, and that gets confused if used along with GLX's double-buffering in the same GTK widget. You can turn off GTK's double-buffering with a form like this one: (gtk_widget_set_double_buffered gtk-widget FALSE) ------------------------------------------------------------ glx-extension () [function] If this returns NIL, then the X server does not support the GLX extensions. Otherwise it returns two values indicating the error-base and the event-base, whatever those are. ------------------------------------------------------------ glx-version () [function] If this returns NIL, then the X server does not support the GLX extensions. Otherwise it returns the major and minor versions of the X server's GLX support as two multiple values. ------------------------------------------------------------ gtk-widget-size (gtk-widget) [function] A GTK convenience function that returns the current width and height of a GTK widget. Two values are returned, the first being the width and the second the height. These values could be passed to the OpenGL function glViewport to make the drawing fill the GTK widget. ------------------------------------------------------------ invalidate-whole-gtk-widget (gtk-widget) [function] A GTK convenience function that invalidates the entire area in a GTK widget. This could be called to cause an OpenGL GTK widget to be redrawn after you have (for example) changed the current drawing angle. See gtkteapot.cl for an example. ------------------------------------------------------------ gdk-window-of-gtk-widget (gtk-widget) [function] A GTK convenience function that returns the GdkWindow of a GtkWidget, or nil if it has no GdkWindow. This could be used, for example, to find the object that you need to pass to GDK drawing functions. See gtkgltest.cl for an example. ------------------------------------------------------------ That's it! Refer to the examples in gtkgltest.cl and gtkteapot.cl to see how to integrate calls to the above functions with OpenGL code in a CG application. ------------------------------------------------------------