Renewed LambdaCube, Bullet bindings and Stunts example

After many long hours of labour, I’m happy to announce the new release of the LambdaCube 3D engine on Hackage! Almost two years passed since the previous one, and the project spent the majority of that time in dormancy. The most important changes are the following (mostly straight from the latest HCAR):
  • removed dependency on the high-level OpenGL bindings: from now on, the library only builds on OpenGLRaw, and the OpenGL specific code is limited to the GL render system module, which we plan to move into a separate package;
  • switched to the vect library (from Vec), which was created for 3D applications from the get-go;
  • dropped fgl dependency for scene graph handling, and switched to a simpler and much more efficient solution based on bytestring-trie;
  • simplified support for procedurally created content through vector vertex buffers, which subsumes user-supplied loaders for any format as a special case;
  • introduced the LCM (LambdaCube Monad) abstraction, which hides the management of the world state and generally simplifies the engine code;
  • more efficient scene management with frustum culling;
  • added support for light sources;
  • identified the public interface and documented it (the rest is only exposed for the sake of library implementers).

Besides the engine, we updated the bindings for the Bullet physics library as well, which covers a big portion of the existing functionality in its present state. This is a raw binding that exposes a C style interface.

We also set out to create a complex example that people can immediately start playing with. This is a modern remake of the classic racing game Stunts, available on Hackage under the same name. The example serves two primary purposes: it is a test case for the 3D engine and the physics binding as well as a starting point for future users of the library. We made sure that everything compiles and works fine on the three major platforms supported by GHC. The quickest way to see the example in action is to try the Windows executable, which is also handled fine by Wine. Fortunately, the compilation process is less painful than one would expect (even on Windows!), so those who want to start hacking on it right away should feel encouraged to do so; we provided a starter guide to make the first steps easier. For the even lazier ones, here’s a taste of the example:

Plans for the future

One of the original design goals was to create an engine that can handle Ogre3D content out of the box. Unfortunately, this proved to be a bad decision, since we ended up with a lot of fixed-function legacy right away, and the implementation in its current form is rather wasteful of resources due to its naivety, especially with respect to the choice of data structures.

The next version will definitely get rid of all the Ogre3D specific functionality. Our plan is to create a small and efficient core package that allows the programmer to easily set up the rendering pipeline and manage mesh hierarchies. We are targeting the OpenGL 3.3 core profile, so the engine will build exclusively on the programmable pipeline. The current idea is to define a simple DSL for describing pipelines that’s similar to GPipe in its basic philosophy, but not embedded in Haskell, which allows us to have full control over its structure. The engine would provide an API to build pipelines (allocating buffer objects and managing shader programs) out of these descriptions and to feed them with content (textures and primitive streams resulting from the flattening of the scene), while taking care of caching and optimising context switches. All this functionality would be wrapped in a declarative interface, naturally.

While it would be possible to create separate packages to support existing formats (e.g. Ogre3D or COLLADA), we have something much more exciting in mind: integration with Blender. Blender can load content in several formats and present it in a basic form, reducing everything to raw vertex and index buffers, and the data can be accessed from Haskell code through Thrift. It is also possible to wrap LambdaCube in a rendering plugin that would display content inside Blender, thereby giving us an integrated content authoring solution. Some of this actually works already, but it’s not ready yet for public consumption.

By the way, Csaba will be present on this year’s CamHac, so if you’re one of the attendants, feel free to bombard him with questions and ideas!