This project is a translation from C++ to OCaml of the breakout tutorial at learnopengl.com. The tutorial is a creation of Joey de Vries. All the textures and audio are directly copied from the tutorial and belong to Joey de Vries, I only collected them here so that the code can be executed without having to look for them in their various locations. The resulting game should be (almost) identical to what one would obtain at the end of the Render Text chapter.
I tried to reproduce as faithfully as possible the general architecture of the original C++ code, and to use more or less the same implementations for the various game features. This would allow someone who is interested in going through the tutorial with OCaml not to be lost when comparing both versions. Of course it was necessary to make some changes here and there, firstly in order to accomodate discrepancies between OCaml and C++ and maintain a reasonably functional style, secondly because all the dependencies were not necessarily available in the OCaml ecosystem.
Wherever external C libraries were used in the original, I replaced them with an existing OCaml binding to the same or an equivalent library if availabe. When I was not able to find something simple enough, I included homemade restricted bindings wrapped into a small library that mimics as closely as possible what was used in the tutorial. (See the sections below for more details.)
The windowing library GLFW is replaced by SDL2, because I already used SDL for the audio anyway. The SDL interface is accessed through the tsdl OCaml bindings.
The OpenGL functions are accessed through the tgls OCaml bindings.
The textures are loaded with stb_image (which is what SOIL is based on).
It is accessed with a homemade binding to the stbi_load
and stbi_image_free
functions.
The audio loading and playback is performed with SDL_mixer, using a homemade
binding to the necessary functions.
The sound files, unlike in the tutorial, are handled by the resource manager, just like the shaders and the textures.
The high-level playback function is located in the Resource_manager
module as well.
The FreeType library is replaced by stb_truetype, again with a homemade binding to the necessary functions. The functionality provided is slightly different from that of FreeType, so the text rendering part of the tutorial has some variations. Most notably, the space character is treated as a special case.
The GLM library is not used. Instead, the Util
module contains (very naive) implementations of the basic vector and
matrix operations used in the tutorial, including the computation of the orthographic projection matrix. The Util
module also
contains some other unrelated convenience functions.
All the objects are replaced by record types, or sometimes by modules in the case of singletons. The inheritance relationship between the ball and the basic game object is implemented by including a game object field as part of the ball record. As a result, the collision checking cannot be overloaded, and instead the different implementations have been divided up into the corresponding objects' modules.
Several objects that were global in the C++ version become fields of the game type. This seemed like a good way to keep things functional without rearranging the structure of the code too much.
- dune: build system
- base: OCaml standard library replacement
- stdio: I/O library (complement to base)
- tgls: OpenGL binding for OCaml
- SDL2: windowing, input, etc.
- SDL_mixer: audio loading and playback
- tsdl: SDL2 binding for OCaml
- ctypes: tools to generate C bindings
- stb_image: image loading (copy included)
- stb_truetype: font loading (copy included)
The stb_image and stb_truetype headers are already included in the source code. After having installed SDL2 and SDL_mixer, install the OCaml dependencies with opam:
opam install dune base stdio tgls tsdl ctypes
Then build with
dune build
From the root of the project, run the executable that was generated in the _build
directory, for instance with
dune exec ./src/main.exe