LablGLES: OpenGL ES from OCaml
Posted by Jeffrey
OpenGL ES is a reduced version of the OpenGL graphics standard, suitable for use on small devices like mobile phones. My OCaml interface is provided as a set of patches to LablGL, an OCaml OpenGL interface by Jacques Garrigue and others.
You can use LablGLES to build OpenGL applications in OCaml for the iPhone and other iOS devices using OCamlXARM, a cross compiler for iOS. You can also use LablGLES to build OpenGL applications for the iOS Simulator using OcamlXSim.
As of LablGLES 1.1.4, there is also support for compiling and linking under Android. (Android patches were contributed by Paul Snively, psnively@mac.com.)
The current version of LablGLES is 1.1.14, which is based on LablGL version 1.04. It supports OpenGL ES Version 1.1, including a few extensions necessary for iOS. If you want to use it to build iOS apps, you need an installation of Xcode, Apple’s development environment. See Apple’s developer website for details.
The build shown on this page was tested with Xcode 4.3.2 under OS X 10.7 (Lion), but should also work with any more recent version of Xcode. A previous version of LablGLES, for earlier versions of OS X and Xcode, can be found in the OCaml Programming Archives.
The LablGLES library has been used in production on iOS. In fact the Psellos Cassino and Master Schnapsen/66 apps currently available in the iTunes store are LablGLES apps, and there is at least one other commercial iOS app by another software outfit that uses LablGLES.
Overview
The LablGL release contains three interfaces: to OpenGL, to Tcl/Tk, and to GLUT. Only OpenGL is readily applicable in an embedded environment; I do not build the other parts (and they are not affected by any of the patches).
To a fairly good approximation, OpenGL ES is a subset of OpenGL. Roughly speaking, then, the patches just remove the parts of LablGL that aren’t in OpenGL ES. In addition, I added support for framebuffer objects, an extension required for OpenGL ES applications on iOS devices. I also added support for PVRTC compressed textures, which again are very useful on iOS devices.
Get LablGLES Sources
Download the sources for LablGLES from Psellos:
You can also fetch LablGLES as a set of patches to the LablGL 1.04 release, as described below. For simplicity I’ll assume you’ve fetched this pre-patched worktree.
Now look in your Downloads folder (where your browser places downloaded
files). You should see a file named lablgles-1.1.14.zip
. Your
browser may have opened it for you automatically. If not, double-click
on it. This creates a project folder, named lablgles-1.1.14
. You may
want to move it out of the Downloads folder to a more convenient place.
Build with Xcode
If you’re working under OS X, the project folder contains two Xcode
project descriptions for building LablGLES. LablGLES.xcodeproj
builds
LablGLES for use on an iOS device (i.e., it builds an ARM library).
LablGLESSim.xcodeproj
builds LablGLES for use in the iOS Simulator (it
builds an i386 library).
To build for an iOS device, double-click on LablGLES.xcodeproj
to
start up Xcode. You can also open it from Xcode’s File -> Open
menu.
Make sure Xcode is building for an iOS device (not the iOS Simulator):
- Click at the left side of the Scheme selector at the left end of the toolbar. A menu drops down. Select LablGLES -> iOS Device. If a device is attached, the name of the device will appear instead of “iOS Device.”
The file Makefile.config.ios
contains definitions for building
LablGLES for an iOS device. You may need to change some of the
definitions in this file. Make sure you are in the Project Navigator,
which shows the files of the project. If necessary, click the triangle
next to LablGLES to reveal them. Click on Makefile.config.ios
in the
left pane, and the file appears in the center. You’ll see lines like
this near the top of the file:
OCAMLBINDIR=/usr/local/ocamlxarm/bin
SDK=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Develloper/SDKs/iPhoneOS5.1.sdk
INSTALLDIR = `pwd`/release
Change OCAMLBINDIR
to the location of your OCaml-to-iOS cross
compiler. (The initial setting is for OCamlXARM, which we
put together at Psellos.) Change SDK
to the iOS SDK you wish to use.
Probably you want to set it to the most recent SDK that you have
installed. Change INSTALLDIR
to the folder where you want LablGLES to
be installed. The above setting installs LablGLES inside the worktree
itself, which is how I configure my personal worktrees. Another
possible setting is :
INSTALLDIR = `$(OCAMLBINDIR)/ocamlc -where`/lablGLES
This asks for installation in the standard place associated with your cross compiler.
To build the library, click on the Product -> Build menu item.
If things go right, the LablGLES libary will be built and installed. If
you haven’t changed the INSTALLDIR
setting, it will be installed in a
folder named release
inside the project folder.
Building for the iOS Simulator is very similar. Start Xcode by
double-clicking on LablGLESSim.xcodeproj
. Make sure Xcode is building
for the iOS Simulator (not an iOS Device):
- Click at the left side of the Scheme selector at the left end of the toolbar. A menu drops down. Select LablGLESSim -> iPhone 5.1 Simulator.
The file Makefile.config.iossim
contains definitions for building
LablGLES for the iOS Simulator. You’ll see lines like this near the top
of the file:
OCAMLBINDIR=/usr/local/ocamlxsim/bin
SDK=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk
INSTALLDIR = `pwd`/release
Change OCAMLBINDIR
to the location of your OCaml-to-iOS-Simulator
cross compiler. (The initial setting is for OCamlXSim,
which I put together.) Change SDK
to the iOS Simulator SDK you wish
to use. Probably you want to set it to the most recent Simulator SDK
that you have installed. If desired, change INSTALLDIR
as suggested
above.
Click on the Product -> Build menu item. The LablGLES libary will be built and installed.
Build from Command Lne
Naturally, the Xcode projects work only on OS X. Building for other systems will depend a great deal on your host and target systems. For concreteness, examples below will use OS X as the host system and iOS as the target system, but you should be able to build LablGLES on any system that supports LablGL.
The build of LablGL (and thus LablGLES) is controlled by a main
Makefile
that is the same for all environments. Details for a
particular environment are defined in a file named Makefile.config
,
which is included by the main Makefile
. The LablGL release includes
several examples for different environments, named Makefile.config.ex
,
Makefile.config.osx
, and so on. The LablGLES patches create new
example files for iOS, iOS Simulator, and Android named
Makefile.config.ios
, Makefile.config.iossim
, and
Makefile.config.android
.
The first step in building LablGLES, then, is to create a
Makefile.config
file that defines the details of your environment.
Make sure you specify the location of your OCaml cross compiler (and
other utilities), and the locations of the header files and libraries
you want to use. Also specify INSTALLDIR
, which controls where the
library will be installed. Changes to make for iOS are described above,
and changes for other systems should be similar.
Once you have your configuration file, copy it into place and compile the library. For iOS, this looks as follows:
$ cd lablgles-1.1.14
$ cp Makefile.config.ios Makefile.config
$ make lib libopt
cd src && make all LIBDIR="`ocamlc -where`"
/usr/local/ocamlxarm/bin/ocamlc -pp /usr/local/ocamlxarm/bin/camlp4o var2def.ml -o var2def
/usr/local/ocamlxarm/bin/ocamlc -pp /usr/local/ocamlxarm/bin/camlp4o var2switch.ml -o var2switch
/usr/local/ocamlxarm/bin/ocamlrun ../src/var2def < gl_tags.var > gl_tags.h
/usr/local/ocamlxarm/bin/ocamlrun ../src/var2switch -table GL_ < gl_tags.var > gl_tags.c
/usr/local/ocamlxarm/bin/ocamlc -c -w s -ccopt "-c -O -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.2.sdk" ml_gl.c
. . .
/usr/local/ocamlxarm/bin/ocamlc -c -w s -I +labltk raw.mli
/usr/local/ocamlxarm/bin/ocamlc -c -w s -I +labltk raw.ml
/usr/local/ocamlxarm/bin/ocamlc -c -w s -I +labltk gl.mli
/usr/local/ocamlxarm/bin/ocamlc -c -w s -I +labltk gl.ml
. . .
/usr/local/ocamlxarm/bin/ocamlopt -c -ccopt -isysroot -ccopt /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -cclib -Wl,-syslibroot,/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -I +labltk glFramebuffer.ml
/usr/local/ocamlxarm/bin/ocamlmklib -ldopt -Wl,-syslibroot,/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -o lablgles ml_gl.o ml_raw.o ml_glarray.o ml_glframe.o raw.cmx gl.cmx glLight.cmx glMat.cmx glMisc.cmx glPix.cmx glClear.cmx glTex.cmx glDraw.cmx glFunc.cmx glArray.cmx glFramebuffer.cmx -framework OpenGLES
The compilation produces around 50 lines of output, some of them quite long.
To create the installation, type make install
:
$ make install
cd src && make install
. . .
The installation process produces around 15 lines of output. The contents of the installation folder should look something like this:
$ ls -l release
total 712
-rw-r--r-- 1 psellos staff 4492 Jun 2 15:47 build.ml
-rwxr-xr-x 1 psellos staff 33028 Jun 2 15:47 dlllablgles.so
-rw-r--r-- 1 psellos staff 3065 Jun 2 15:47 gl.cmi
-rw-r--r-- 1 psellos staff 707 Jun 2 15:47 gl.cmx
-rw-r--r-- 1 psellos staff 2719 Jun 2 15:47 gl.ml
-rw-r--r-- 1 psellos staff 1874 Jun 2 15:47 gl.mli
. . .
-rw-r--r-- 1 psellos staff 53872 Jun 2 15:47 lablgles.a
-rw-r--r-- 1 psellos staff 18325 Jun 2 15:47 lablgles.cma
-rw-r--r-- 1 psellos staff 2564 Jun 2 15:47 lablgles.cmxa
-rw-r--r-- 1 psellos staff 36384 Jun 2 15:47 liblablgles.a
-rw-r--r-- 1 psellos staff 6258 Jun 2 15:47 raw.cmi
-rw-r--r-- 1 psellos staff 1313 Jun 2 15:47 raw.cmx
-rw-r--r-- 1 psellos staff 3179 Jun 2 15:47 raw.ml
-rw-r--r-- 1 psellos staff 3716 Jun 2 15:47 raw.mli
Get LablGLES Patches
If you’d like to examine the LablGLES patches or apply them to LablGL 1.04 yourself, you can download them separately:
To use the patches, first untar the LablGL work tree. Then use the following commands:
$ cd LablGL-1.04
$ patch -p0 -E < lablgles-1.1.14.diff
Because OpenGL ES is a subset of OpenGL, around 20 of the LablGL source
files are not applicable to LablGLES. The patch causes all their
content to disappear, and the -E
option asks for these empty files to
be deleted.
After patching, you can follow the above command-line instructions to build LablGLES.
Test
To verify that the library works for building under OS X, you can compile and link a small test program from the command line.
$ cat glestest.ml
let main () =
begin
GlPix.store (`unpack_alignment 1);
GlFunc.blend_func `one `one_minus_src_alpha;
Gl.enable `blend;
GlTex.env (`mode `modulate);
GlDraw.viewport ~x: 0 ~y: 0 ~w: 320 ~h: 460;
GlMat.mode `projection;
GlMat.load_identity ();
GlMat.ortho ~x: (0.0, 320.0) ~y: (0.0, 460.0)
~z: (-100.0, 100.0);
GlClear.color ~alpha: 1.0 (0.8, 0.333, 0.0);
GlClear.clear [`color];
end
let () = main ()
Now compile and link with the cross compiler. This example is for compilation to iOS (with OCamlXARM).
$ PLAT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
$ SDK=$PLAT/Developer/SDKs/iPhoneOS5.1.sdk
$ CCLIB="-cclib -Wl,-syslibroot,$SDK -cclib -Wl,-no_pie"
$ /usr/local/ocamlxarm/bin/ocamlopt $CCLIB -I release -o glestest lablgles.cmxa glestest.ml
$ file glestest
glestest: Mach-O executable arm
The extra options tell ocamlopt where to find libraries for linking the app against the iOS SDK. As described in Compile OCaml for iOS, this is hard to avoid due to Apple’s steady release of new versions of iOS and SDKs for them. Although they’re painful to specify, you’re generally not going to be typing them in by hand. You just need to set up your build system (Makefile, Xcode, etc.) once, and it will take care of it.
If the compiler produces an executable, LablGLES very likely has been built correctly.
You may, instead, see an error like the following:
$ /usr/local/ocamlxarm/bin/ocamlopt $CCLIB -I release -o glestest lablgles.cmxa glestest.ml
ld: library not found for -lcrt1.o
collect2: ld returned 1 exit status
Error during linking
This most likely means that you have specified a version of the iOS SDK
that doesn’t exist on your system. Check that you’ve specified the
PLAT
and SDK
values correctly.
The corresponding test for the iOS Simulator looks as follows:
$ PLAT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform
$ SDK=$PLAT/Developer/SDKs/iPhoneSimulator5.1.sdk
$ CCLIB="-cclib -Wl,-syslibroot,$SDK -cclib -Wl,-no_pie"
$ /usr/local/ocamlxsim/bin/ocamlopt $CCLIB -I release -o glestest lablgles.cmxa glestest.ml
$ file glestest
glestest: Mach-O executable i386
Here you may see an error like the following:
$ /usr/local/ocamlxsim/bin/ocamlopt $CCLIB -I release -o glestest lablgles.cmxa glestest.ml
ld: framework not found OpenGLES
collect2: ld returned 1 exit status
File "caml_startup", line 1, characters 0-1:
Error: Error during linking
Again, check that you’ve specified the PLAT
and SDK
values correctly.
Note: These compiles of
glestest.ml
only test that the LablGLES library has been created
correctly. A program that actually displays graphical content requires
a little more setup (described next).
Further Information
To show how to use OpenGL ES under iOS, I’ve put together an example LablGLES app named IcosaBlue. The app itself is quite simple, but it demonstrates the extra Cocoa Touch classes and setup required to embed OpenGL ES graphics in an iOS app. To make it as useful as possible, I packaged it both for the iOS Simulator and for the iPhone device. See IcosaBlue: OpenGL ES App for iOS for a description of how to build and run it, and how it works.
Instructions for compiling OCaml for iOS are given in Compile OCaml for iOS. For compiling OCaml for the iOS Simulator, see Compile OCaml for iOS Simulator. Many other resources for OCaml programmers, including more example apps for both iOS and the iOS Simulator, are listed on our OCaml Programming page.
I’m happy to get any comments, corrections, or questions. Please leave them below or email me at jeffsco@psellos.com.