Psellos
Contemporary Development With Functional Programming

LablGLES: OpenGL ES from OCaml

June 3, 2012

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.

Comments

blog comments powered by Disqus