[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