[HOpenGL] How's it done?

Sven Panne Sven.Panne at aedion.de
Fri Sep 23 04:53:41 EDT 2005


Am Dienstag, 20. September 2005 23:56 schrieb Chris Campbell:
>[...]
> The web pages look a little out of date, but from what I can gather
> this is what I think happens.  First, the spec files are parsed and
> the types and functions are noted.  Next a flat C and Haskell file are
> generated from the info from the previous stage.  The C file
> interfaces with haskell runtime.  Conversion from Haskell types to the
> numerical values of enumerations is done in the Haskell layer.  The
> functions in the haskell file are then called by a set of hierachical
> modules which have been manually created and turn the flat GL
> namespace into a hierachical one.  Is that about right or am I missing
> something/way off on a tangent? [...]

Well, first of all I have to admit that the web pages are really out of 
date. :-( I think that I should raise the priority of updating them on my 
ToDo list...

Regarding the actual way of generating the binding: Long, long ago I started 
writing the first basic OpenGL binding for Haskell and did it by hand. Then I 
found the .spec files in the OpenGL SI and thought it was a good idea to 
generate at least the lower layers of the Haskell binding by using them. The 
advantage would be that they are "official" and maintained. But there were 
quite a few problems with them:

 * The syntax and semantics of the .spec files are only "documented" 
implicitly via the Perl scripts in the SI which use them for various 
purposes.

 * The information contained in them is often not enough for a strongly typed 
language like Haskell. Note that I consider the C binding of OpenGL as 
untyped, there are almost no programming errors which could be caught by a C 
compiler, because almost everything is an integral.

 * The token names in OpenGL are chosen in a linguistic way, meaning that a 
single token is often used for various purposes if its name "sounds right". 
Again, this is a problem for a strongly typed language where we have to 
disambiguate those uses somehow.

 * There were a few overlaps with the extension .specs which had to be 
resolved.

 * At some point in time the .spec files contained some bugs, and I'm not sure 
if they are fixed by now officially.

I am sure that all these problem could be solved, even without touching the 
original .spec files, but at some point in time it seemed a bit too much work 
for me, so the current binding for OpenGL is done by hand, only the enumerant 
(un)marshalers are generated automatically and cut-n-pasted into the right 
places.

As a sidenote, The Mesa project was not very satisfied with the .spec files, 
either, so they decided to do it better. Consequently, recent distributions 
of Mesa contain a much cleaner and more easy to use description of the OpenGL 
API, see:

   http://cvs.freedesktop.org/mesa/Mesa/src/mesa/glapi/

It contains an XML description of the whole OpenGL API and almost all 
extension ever seen on earth plus some nice Python scripts for processing 
them. If I'll ever go the "mechanic way" again of generating parts of the 
Haskell binding, I would probably use this XML description plus (of course) 
one of our Haskell libraries for processing XML. But that is only guessing, 
because I haven't made some actual experiments with that route.

But the strongest reason for doing the binding by hand is that I don't want a 
plain 1:1 mapping of the C API. What I intended to create is a 1:1 mapping of 
the OpenGL *concepts* to Haskell. To give an example of what I mean with 
that: The OpenGL spec explains everything in terms of OpenGL state, which is 
a very good thing IMHO. But in the C API, things which belong together are 
actually torn apart due to some lacking features in the C language: State is 
set through explicit API calls, but retrieved through generic query functions 
(e.g. glStecilOp vs. 3 calls to glGetIntegerv). In the Haskell binding these 
things are grouped together into a StateVar, which (normally) can be set and 
read. The code needed for that can't be generated automatically and is 
actually the most work (not regarding the number of lines, but regarding the 
amount of thinking involved). And writing user documentation (which I haven't 
finished) for the Haskell API is even more work...

In a nutshell: For a new "nice" OpenGL binding I would recommend that at least 
the token (un-)marshalers get generated semi-automatically (they are a lot of 
boring work with lots of possibilities for unrecognised typos), but the rest 
can be done by hand. For a plain 1:1 mapping of the C API, things can 
probably be automated almost completely via the Mesa XML description. So the 
choice is yours... :-)

Cheers,
   S.


More information about the HOpenGL mailing list