Using OpenGL with native OCaml Graphics
I’ve always thought it would be nice if it were possible to use OpenGL calls in a window created with the Ocaml Graphics module. This would prevent the need to require external toolkits such as SDL or GLUT.
The Ocaml Graphics module is quite limited compared to SDL or GLUT, and also fills a slightly different niche, but it does come with a number of useful functions for drawing text, various graphics primitives, and for polling mouse and keyboard events. Simple standalone programs or demos can be created and distributed without requiring that the SDL or GLUT shared library be present on those systems.
To get an Ocaml window working with OpenGL I wrote a stub file in C and a few lines of ML code. When the test program is compiled and linked (download a gzipped tar file containing all necessary files here) it results in a program that runs as seen in the screenshot below.
The file win_stub.c and the few lines of ML code in the prologue of win_test.ml is all that is needed to use OpenGL within an Ocaml application. For the actual OpenGL bindings either GLCaml or lablgl will suffice.
Compiling:
For the provided examples, extract the files contained in glgraphics.tar.gz, and run make. Edit the makefile if necessary, to ensure that the line CLIB=GL is uncommented on Linux, and the line CLIB=opengl32 gdi32 is uncommented if compiling on Windows with MinGW.
You need the file win_stub.c and the ML code contained in this section, specifically the function init_opengl () and the external functions init_gl’(), find_window() and swap_buffers (). Link the resultant executable with libGL.a on X11, opengl32.lib and gdi32.lib on Windows.
Usage:
- First set up your caml window with Graphics.open_graph ()
- Next, call the function init_gl ()
- After this you can (re)set the window title (if you set it previously it will be empty)
- Feel free to call any OpenGL calls you wish. lablgl, glcaml and camlgl may all be used.
- You may mix the Ocaml graphics functions with OpenGL.
- Call swap_buffers () any time you need to flip the contents of your back buffer to the screen.
How does it work?
The method used is similar, but not identical, on both Windows and X11. Ocaml does not expose the internals of the window (understandably, because they are highly platform-specific), so they have to be obtained via other means. On both X11 and Win32 you can obtain pointers to internal rendering surfaces of windows provided you can identify them by name. After opening the window with Graphics.open_graph (), the function init_opengl () has to be called. This function gives the current window a (hopefully) unique title Then C code is called which searches through all available windows for a window with that particular name, gets pointers to its internal structure (both Win32 and Xlib allow this) and sets it up for use as an OpenGL surface. This method works on Windows and X11; it may work on OS-X (with a little tweaking in the #defines) but I have not tested that.

Comments
No comments yet.
RSS feed for comments on this post.
Leave a comment
Sorry, the comment form is closed at this time.