Ocaml bindings for OpenGL and SDL
UPDATE: This project has moved to glcaml.sourceforge.net.
In the interests of reinventing the wheel where possible, I wrote OCaml bindings for the SDL libraries and OpenGL libraries over a couple of weekends.
The (automatically generated) OpenGL bindings cover OpenGL 1.1, 1.2, 1.3, 1.4, 1.5, 2.0 and most current non-platform-specific extensions. There are no dependencies whatsoever: the system opengl shared library is loaded dynamically, and the functions are called dynamically, so there is no need to link against import libraries.
The SDL bindings are fairly but not wholly complete; they are hand-written and functions are bound on an as-needed-by me basis. They are only dependent on the SDL main library and not on the mixer, ttf or image libraries. Because I wanted to have basic sound capabilities, the SDL_Audio modules are implemented, along with extra functions for panning and pitch shifting audio buffers.
- The source code, in a tar gzipped file, along with around 20 examples
- The documentation, fairly complete for SDL
This has been tested and works on Windows 2000, Windows XP, and Ubuntu Linux running on AMD64.
On Windows I use the mingw Ocaml compiler suite along with the msys shell; the source tarball contains makefiles that work as-is on the Windows mingw/msys port and under Linux. It will probably work as-is for the cygwin port of Ocaml, and will definitely need some tweaking to work under the Visual-C port.
SDLCaml is an Objective Caml interface for the Simple Direct media Layer. It consists of three files (sdl.ml, sdl.mli and sdl_stub.c), and was written out of the desire to have a small, compact set of bindings for SDL to function as drop-in files in other projects. I could not get the canonical binding, ocamlsdl to compile under Windows, so I took Jean-Christophe Filliatre’s old, similarly-named ocamlsdl bindings as a starting point.
I wanted as few files and as few dependencies as possible, because I simply want to be able to add a couple of files to an existing project and have instant SDL capability. So I combined everything into one set of ml, mli and c files, and since Jean-Christophe’s bindings are pretty old, filled in a number of missing functions.
I also want basic audio capability: to be able to mix and play WAV files, without requiring SDL_mixer. So I bound the basic SDL_Audio functions and added a couple of mixing functions for panning and pitch shifting. I’ve put four or five example files using SDL’s basic audio capabilities into the source tarball. This is the dodgiest part of the bindings and the most likely to cause a segfault if you do something wrong. I’m working to make it as stable as possible.
I added a couple of extras to SDLCaml, all written completely in OCaml:
- A TGA file reader, able to read 15,16,24 and 32 bit-per-pixel TGA files, both run-length encoded and uncompressed.
- Texture-map scaling functions, with a number of different scaling filters.
- A texture mipmap generator, using the scaling functions to generate mip-maps suitable for OpenGL
- A bitmapped font library, based on the SFONT specifications
In addition I’ve added four or five converted demos from Lazy Foo’ Productions’ SDL tutorials in the tarball.

Lazy Foo’ Productions’ “Hello World", ported to Objective CAML

Lazy Foo’ Productions’ “Color Keying” example, ported to Objective CAML

A test of the TGA file reader, written entirely in Objective CAML.
The text is printed using the port of SFONT bitmapped text.
GLCaml is an Objective Caml interface for OpenGL versions 1.1, 1.2, 1.3, 1.4, 1.5 and 2.0 plus extensions
The following extensions are supported:
- GL_ARB_imaging
- GL_ARB_matrix_palette
- GL_ARB_multitexture
- GL_ARB_vertex_blend
- GL_ATI_envmap_bumpmap
- GL_ATI_map_object_buffer
- GL_ATI_pn_triangles
- GL_ATI_separate_stencil
- GL_ATI_texture_compression_3dc
- GL_ATI_vertex_streams
- GL_ATIX_point_sprites
- GL_ATIX_texture_env_combine3
- GL_ATIX_texture_env_route
- GL_ATIX_vertex_shader_output_point_size
- GL_EXT_Cg_shader
- GL_EXT_depth_bounds_test
- GL_EXT_draw_range_elements
- GL_EXT_fog_coord
- GL_EXT_pixel_buffer_object
- GL_EXT_secondary_color
- GL_EXT_texture_cube_map
- GL_EXT_texture_edge_clamp
- GL_EXT_texture_rectangle
- GL_EXT_vertex_shader
- GL_KTX_buffer_region
- GL_NV_fragment_program2
- GL_NV_fragment_program_option
- GL_NV_vertex_program2_option
- GL_NV_vertex_program3
Like SDLCaml, it consists of three files: glcaml.ml, glcaml.mli and glcaml_stub.c, and is intended as a compact drop-in binding raher than a big standalone library.
The bindings are generated with the file convert.ml using cleaned up header files from the glext project on Sourceforge.
GLCaml is a direct, not particularly type-safe binding to OpenGL. It has the following features:
- Inspired by camlgl.sourceforge.net, GLCaml loads the OpenGL library dynamically ("OpenGL32.dll” on windows, “libGL.so.1″ on Linux)
- OpenGL functions are loaded dynamically and memoized, once loaded, to speed up future calls.
- Naming conventions are exactly the same as in the traditional ‘C’ OpenGL API.
- Enumerated constants (Glenums) are in GL_ALL_CAPS format.
- Where in C an OR-ed combination of Glenums is passed to a function, in OCaml a list of glenums is passed
- Function names have the exact same names in OCaml as in ‘C’
- Where OpenGL functions require an array for either input or output, a Bigarray of the appropriate type is used.
- To this end, types for Bigarrays of bytes, floats, ints, doubles etc have been defined.
-
set_failwith -> bool -> unitdetermines whether a failed GL call throws a [Failure] exception or fails silently. - This binding is wholly automatically generated and contains hundreds of function bindings, the vast majority of which have not been tested. Use at your own risk.
The lablgl OpenGL bindings are typesafe, elegant and portable. However, it only covers OpenGL 1.2, and I did not feel up to the task of extending it to OpenGL 2.0. In addition, it’s statically linked to the OpenGL import library, which would spell trouble for building on systems with OpenGL < 2.0.
Nickolay Kolchin-Semyonov’s camlgl bindings fit my needs pretty well, extending OpenGL support to 1.5 and loading all functions dynamically. It’s unmaintained at the moment, and I toyed with the idea of taking over maintenance. However the camlgl bindings are clearly generated by some kind of script, which I did not have. Since, to generate more bindings, I had to write a new script, I decided I might as well generate everything from scratch, exactly the way I want it.
The first nine Nehe OpenGL lessons have been added to the tarball.

NeHe example 7: a texture-mapped, lighted box with mip-mapping and filtering

NeHe example 9: texture-mapped, lighted particles
Comments
No comments yet.
RSS feed for comments on this post.
Leave a comment
Sorry, the comment form is closed at this time.
