2/18/2009

Parsing OpenGL 'spec' files

A few notes after some experiments in parsing OpenGL spec files, describing enums and commands for every OpenGL version and extension.

The parsing part when smoothly, as the files are consistently formatted, but I encountered some traps in interpreting values and commands though.

'gl.spec'

It describes OpenGL commands. Every command has a 'category' property that mostly represent the extension or GL version it belongs to. For exemple, OpenGL 1.2 commands have a 'VERSION_1_2' category value, and so on.

Problems come from GL 1.0 & 1.1 commands, that require special handling :
  • GL 1.0 commands have a 'category' which truly represent a category within GL functionnalities (such as 'drawing', 'display-list', ...) and not an extension or GL version.
  • GL 1.1 commands have a 'category' value of '1_1' (should be 'VERSION_1_1' to be consistent) which is easily fixed.
'enumext.spec'

It contains every enum value - starting from OpenGL 1.2... A comment in the file mentions that previous values are not needed as vendors provide a gl.h file containing every entries for OpenGL 1.1... doh.

Otherwise, interpretation is quite smooth. Enum values are grouped in 'sections' that represent either a GL_VERSION or an extension name.

Care must be taken to handle value aliases, as the aliased values may be defined after the alias definition (such as COMPARE_REF_TO_TEXTURE aliasing to COMPARE_R_TO_TEXTURE_ARB) or not defined in the file, when aliasing to OpenGL 1.1 (such as CLIP_DISTANCE0 aliasing to CLIP_PLANE0)... doh.

'enum.spec'

It contains every enum definition, for OpenGL 1.0 to the latest extension, and it used to allocate enum values for vendors.

It looks like it's not really meant to be parsed in its whole : every extension definition is in a commented section, without obvious formal grammar. The parsing of the uncommented lines allow to get the definitions for OpenGL <= 1.1 enums, that are missing from 'enumext'.

The parsing has a lot in common with 'enumext' except that, here, the 'sections' are the GL commands accepting the enum value as a parameter. So the set of every defined value (not in comment) should represent the whole OpenGL <= 1.1 enums. It seems that there is, at least, a typo in the spec file that prevents this good behaviour : TEXTURE_BINDING_3D is defined in 'enum.spec' but it belongs to OpenGL 1.2, as seen in 'enumext.spec'.

Merging enums

To resolve the enums values, without missing values or duplicates (i hope), I set up a linker-like behaviour :
  • scan 'enum.spec' to create the GL1.1 value table (including some wrong values)
  • scan 'enumext.spec', using the previous value table to resolve external aliases
  • remove from 'enum.spec' value table every enum defined in 'enumext.spec'

No comments: