From: Richard Mann
Subject: Announce: OpenGL/Mesa bindings for GCL (Gnu Common Lisp)
Date: 
Message-ID: <MANN.96Dec12144405@orasis.vis.toronto.edu>
Dear Lisp Hackers,

I have created a set of bindings that allow calls to OpenGL/Mesa from Gnu
Common Lisp (GCL).

If anyone is interested, you can download the code at:
	ftp://ftp.cs.toronto.edu/pub/mann/Lisp/GCL-GL.tar.gz

This is only preliminary work, but since people have expressed interest, I
would like to release this as soon as possible.  Details of the distribution
are included at the end of this message.

Please send me Email if you have any questions or comments.

	Richard.

Encl: README file from distribution
-----------------------------------

		OPENGL/MESA Bindings for GCL (Gnu Common Lisp)

OpenGL is a 3d graphics package from Silicon Graphics, Inc.  Mesa is a (free)
OpenGL workalike available at:
    http://www.ssec.wisc.edu/~brianp/Mesa.html

These bindings allow calls to OPENGL/MESA functions from GCL.  The makefile
creates a new LISP image, xgcl, and installs GL functions in the package :GL.

In addition, I have created a set of bindings to XLIB (in the package :XLIB).
This package is similar to XGCL-2 shipped with gcl-2.2, except that I have put
all the definitions in one file, removed the dwdraw stuff, and cleaned up the
definitions a bit.

These bindings are specialized to GCL.  It should be possible to modify them,
but I have not tried.  In addition, these bindings have only been tested with
MESA and not with OPENGL.

This code is preliminary, incomplete, and largely untested.  Since people have
expressed interest, however, I want to distribute it as soon as possible.

If you have any suggestions, or find this interface useful, please let me
know.  In particular, I would like to know how many people are using GCL (or
any other LISP or Scheme implementation) for vision, graphics, and application
programming.  I don't want to use C or C++ just because the required libraries
(GL, XLIB) are in those languagues!

Thanks,

Richard Mann
····@cs.toronto.edu
14 November 1996


				   HISTORY

14 Nov 1996: Announcement to GCL mailing list (···@cli.com).
16 Nov 1996: Bug fixes to pnm.lsp (pnm image routines).
12 Dec 1996: Announcement to Comp.lang.lisp newsgroup.  Changes to this file.


                                    FILES

gl-bindings.lsp: Bindings to GL.  Contains bindings to all C functions and
macros in gl.h, glu.h, and glx.h.

xlib-bindings.lsp, xlib-bindings-c.c: Bindings for X stuff in Xlib.h and
Xutil.h.  The LISP part contains the bindings for functions, macros and
accessors while the C part contains accessors for all required structures.

misc-bindings.lsp, misc-bindings-c.c: Accessors for primitive C types (both
scalars and arrays).  May add other system stuff (such as stdio, file access,
etc.)  here later on.

foreign.lsp: Utility file to link foreign function definitions above into the
GCL system.  (See below for details.)

makefile: Edit this to conform to your system.  You need to say where to find
the GCL distribution, the OPENGL/MESA includes and libraries, and the XLIB
includes and libraries.

sysdef.lsp, sysinit.lsp: extra programs that are needed to build a LISP image
containing the above components.  (See the makefile for details.)

pnm.lsp: A set of accessors for PNM images (PBM images are bitmap; PGM images
are grey level; PPM images are color).  These functions allow reading and
writing of images.  Images are stored as "packed" byte arrays.  In addition,
this file provides accessors that give pointers to the pixel arrays to pass to
XLIB or GL functions requiring image data.

glxdemo.lsp, glspin.lsp, gltest0.lsp, glimage.lsp: Sample programs showing how
to use GL and XLIB functions.  Glxdemo shows a simple program that uses XLIB
to open a window and GLX to initialize GL.  Glimage shows how to put up images
with GL.  (This program shows how to use various Visual types in XLIB.)

sample.pgm, sample.ppm: sample images (for use by program glimage.lsp).


                                 INSTALLATION

0. You need to have a GCL 2.2 source distribution, and have write access to
   the installation directory.  You also need Mesa or OpenGL libraries.

1. Edit the makefile to conform to your system.

2. Type make.  It should create a file "xgcl" in the current directory.
   Note: ignore the compiler error messages:
        ;; Warning: The package operation (EXPORT '(....)) was in a bad place.
   (Each time, this dumps a huge mess of symbols to the screen.)

3. % xgcl
   > (load "glxdemo.lsp") ; load a demo program
   > (main)               ; run a demo program


		   NOTES ON THE FOREIGN FUNCTION INTERFACE

To interface to the GL and XLIB libraries I need to build a foreign function
interface to these functions in LISP.  The general philosophy is to write
"general" definitions for the C functions and macros (see the files
gl-bindings, xlib-bindings, and misc-bindings).  I then use the macros in
foreign.lsp to translate these definitions to the specific form needed by GCL
(ie., the "defentry", "defCfun", "clines", commands).  (It should be possible
to modify foreign.lsp (or write some small preprocessor program) that
translates the bindings into those needed for another LISP or Scheme
implementation.)

For most functions, LISP can call C functions directly.  (The conversion of
types is done automatically by GCL.)  This works when the arguments are
primitive types (char, int, float, ddouble) or strings.  Problems arise,
however, when we want a C function to return a value to one of its arguments
or when we need to pass a pointer to some "composite" data structure (ie., an
array or a structure).

The general philosophy adopted here is to treat "composite" values (pointers
to primitive objects, pointers to structs, pointers to arrays) as raw
pointers.  Pointers are represented by INTs in GCL and void* in C.

Typically, we allocate arrays in LISP and pass a pointer to any C function
that needs to access the array.  The main thing to watch out for is that in
the LISP arrays must be "contiguous" and of the correct type (such as byte,
fixnum, float or double).  We could also allocate the arrays on the C side,
but in most cases, we choose to allocate on the LISP side since we don't want
to build a whole new set of accessors for low-level C arrays.  (There are a
few accessors in misc-bindings-c.c, but these are only for one-dimensional
arrays, and there is no bounds checking for these functions.)

For structs, however, we generally allocate and access them on the C side.  It
is possible to allocate structs on the LISP side and pass pointers to C
functions, but we do not do this here.

For examples of how to use this FFI, see the sample programs described above.


			   NOTE ON GL, XLIB and GLX

GL provides functions to do rendering, but it doesn't provide any functions to
open windows and manage events.  In these programs I use XLIB to open windows
and manage events.  The GLX routines (in glx.h) are necessary to interface
between GL and XLIB.  In particular, the GLX routines are needed to: 1) bind
GL so that it outputs to an X window; 2) control when GL output is flushed to
the X window, when buffers are swapped, etc.

There are other ways to interface GL to the windowing system.  Examples
include GLAUX, GLUT, GLTK, etc.  I did not use any of these methods since they
all seem to require callbacks.  In each of these approaches the event loop is
automatically done for you, but you need to pass the redraw and resize 
code to a C function.  I don't know how to do this in GCL.


				 THINGS TO DO

1. Check compatability with OpenGL.  In particular, in SGI OpenGL, double
buffering doesn't seem to work and display updates seem to work differently
than in Mesa.

2. Make a proper makefile (ie., that doesn't waste time recompiling LISP
images).  I need to understand the building of the LISP image better (see
makefile and sysinit.lsp).  This code is taken from the distribution of XGCL-2
in GCL 2.2, but I don't understand it.

3. Understand LISP packages better.  In particular, I want to automatically
export all foreign symbols in each of the GL and XLIB packages.  Right now it
works, but gives a silly warning during compilation.  I don't know why!

4. Try to interface to GCL-TK.  Is there a way to either: get GL to output
to an existing GCL-TK window; or, use GCL-TK to control an X window that
GL/XLIB opened?

5. Improve the format of the foreign-function interface.  In particular,
definitions should appear in the same order as they do in the original include
(.h) files.  Also, I want to extend the foreign definition style.  In
particular, I intend to still allow generic "POINTER" and "(POINTER STRUCT)",
but also allow pointers to particular structs.  Eg., "(POINTER (STRUCT
DISPLAY))".  This would allow more sophisticated interface policies, such as
those that automatically declare structs and accessors on the LISP side.
Right now, however, it does not seem worth the bother.


                               ACKNOWLEDGEMENTS

Thanks to Brian Paul, for providing a free alternative to OpenGL!

The original bindings were generated using (a modified version of) FFIGEN from
Lars Thomas Hansen (···@cs.uoregon.edu).

The generation of GCL "defentry" syntax is based on foreign.lsp by Paul Viola.