Vala and Modern OpenGL

I’m really enthusiastic about Vala, and has been since its inception. I think it’s just about the “sexiest” language Linux has to offer right now, supporting writing native applications with no VM overhead and almost all the expressive power of C#.

I’d still prefer Qt to GTK as a GUI toolkit, and in my opinion, it’s a shame that there is currently no clear way to integrate Qt with Vala, other than through a C API bridge. I understand that GObject and QObject are two different OO systems and maintaining a bridge between them is a difficult and costly problem. However, while I absolutely adore the quality of Qt’s tools and documentation, and the effort put in its design, I’d rather claw my eyeballs out than write in C++ again. (C is fine, but only for small, performance-critical code fragments.)

I’ve been particularly interested in non-GNOME Vala projects. Indeed, there seems to be a preconception that because of Vala’s tight integration with the GNOME platform, it’s of little interest to non-GNOME project. In fact, I think Vala could well become the native-compiled language of choice for Linux developers, given time. I’m interested in those little projects that pop up from time to time, like the Ambition web framework, or autovala for a CMake-based build system. (Autotools? No, thanks.)

And of course, once again I ended up reinventing the wheel and only realizing it in hindsight.

Recently I’ve been playing around with modern OpenGL, namely the 3.x shader-based pipeline. I previously only knew legacy OpenGL 1.x, and was enthusiastic about forgetting the fixed pipeline and doing things the new way. (Especially considering that it is the only way in GLES2 and WebGL.) I also wanted to write my toy applications in Vala, rather than C++ like most tutorials were advocating.

However, I found that my chosen path (Vala, SDL and GLEW) was surprisingly fraught with problems:

  1. For one, I found no decent OpenGL VAPI binding. The file gl.vapi in External Bindings on turned out not to match the C source and gave me internal Vala compiler errors. (glGenBuffers wanted an out array — ew!) I ended up forking the binding generator, fixing build problems that accumulated with time (it seems unmaintained), and patching it to output more sane and vapigen-friendly GIR bindings (for example, passing GLchar arrays as strings, and correctly handling array return values and arrays of arrays).
  2. By dropping the fixed pipeline, OpenGL 3.x also drops all default matrix handling and glRotatef/glTranslatef and friends. Since the only libraries I could find to replace this functionality were written in C++ (GSL is not quite what I needed), I ended up reimplementing matrix algebra and transformations in pure Vala.
  3. SDL 1.2 fullscreen windows are problematic and have been so for years. This problem, as it turns out, affects even some commercial games published on Steam (Aquaria, for example). SDL grabs all keyboard input, including standard system shortcuts like Alt-Tab and Alt-F4. I ended up reimplementing these specific two, but obviously the application won’t pick up different key combinations from system settings if they are customized in the DE.

The net result:

  1. A fixed OpenGL GIR/VAPI binding generator, based on original work by Blaž Tomažič. The bindings are generated from the latest OpenGL specification wget’d from at build time. My version actually pulls GLEW, because that’s what I use in my sample application for GL 3.x API calls, but the resulting VAPI file can be simply edited by doing search-and-replace of GL/glew.h with GL/gl.h everywhere.
  2. Here is the OpenGL VAPI itself.
  3. A simple skeletal application using SDL, displaying a rotating cube. It is surprisingly big for a Hello World-level application, because it also includes…
  4. Reimplementation of GL-style matrix and vector algebra for 3 and 4 components, projections and model matrix transformations.

(For the matrix library, I was concerned about some warts of Vala code generation that cannot be disabled, such as automatic zero-initialization of everything in the generated C code, even when the entire contents of the vector or matrix are about to be overwritten in the constructor. Turned out GCC with -O2 is clever enough to optimize that away — even memsets! — but Clang isn’t. Yet.)

And then, just as I was about to publish it… I learned of Cogl, which can do all that and more, is object-oriented, well-tested and supported in the GNOME ecosystem, and has nice Vala bindings of its own. (Though I wonder how Cogl plays with raw OpenGL calls; can they be mixed in the same context?)

Typical me reinventing the wheel.

I would recommend Vala and possibly even C developers to use Cogl for new projects. My little sample application is of little value, but at least it has Valadoc. And hey, maybe at least the OpenGL binding will be useful to someone. (By the way, can someone explain to me why Valadoc, a tool made by Linux developers for Linux developers, uses Microsoft fonts in its generated HTML? It looks horrible.)

I’ll port it to SDL 2.0 whenever it gets an Ubuntu package. I also encourage game developers to do the same. SDL 2.0 is the future and has better integration with desktop systems — including support for native system cursors and system keyboard shortcuts for fullscreen windows.

3 thoughts on “Vala and Modern OpenGL

  1. I completely agree: Vala is a great language! Re-inventing the wheel is not always bad, it’s a also a good way to understand how it works under the covers. I bet doing that taught you a lot about OpenGL 3.x.

  2. Have you used Cogl with OpenGL 3 or 4? As far as I can tell, Cogl is stuck in pre-OpenGL 3 land.

    Thanks so much for the fixed vapi file! A few years ago I tried fixing it myself, but it was difficult and I got distracted somewhere along the way.

  3. Do you know wether it’s still such a trouble to get this working? I really like the readability of Vala over C++, but I have no idea how things like vapi’s work. Back when I still used Windows I only ever used C++, which just seems to work without much trouble.

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    Markdown is turned off in code blocks:
     [This is not a link](

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see