OpenGLRawgen is a generator tool to make a Raw FFI import of OpenGL to Haskell in style of OpenGLRaw.
The current (01-2013) OpenGLRaw is quite outdated and not practical to keep up to date as everything needs to be done by hand. The goal of this project is to make a generator which can produce most of the otherwise handwritten source of OpenGLRaw. The generated sources should strike a balance between being similar to OpenGLRaw and being future proof.
The generator creates all sources in the Graphics.Rendering.OpenGL.Raw
namespace, which is currently hard coded. In will generate
- The top level module
Raw.hs
, which will export the most recent Core version of OpenGL. - The
Core
namespace for the definition of the OpenGL profiles. This will in turn contain- Modules
CoreXY
andCoreXYCompatibility
which contain the functions and enumerations for OpenGL version X.Y, one for the Core profile and one for the one with Compatibility profile. These modules are build by reexporting from the internal modules. - Modules
Internal.CoreXY
andInternal.CoreXYCompatibility
for the definitions of enumerations and functions that are introduced in version XY of OpenGL. The Compatibility version contains the ones that were later deprecated.
- Modules
- Extension granter (e.g.
ARB
andNV
) modules and namespaces, where each extension gets its own module under the namespace of the maker. For example theARB_sync
extension is created in the moduleARB.Sync
. All the extensions of a single maker are grouped under a module with the name of the vendor (e.g.ARB.hs
). Though this latter functionality can be disabled.
Furthermore if asked (-c
flag) it can generate modules for backwards
compatibility with the old OpenGLRaw. These are Core31
and Core32
and
Core31.Types
.
Apart from the Haskell sources the generator also outputs several other files.
- For generating a cabal file it creates
modulesI.txt
andmodulesE.txt
which contain all the internal and exposed modules for in the cabal file. - A set of interface files describing the mapping between OpenGL names and the corresponding Haskell names, including the module from which they are exported.
Several steps are needed to be preformed to generate a working cabal package
out of the generated sources. These steps are detailed in
BuildSources.BUILDING.md
. All the steps are also combined, mostly for testing
purposes, in the testbuild.sh
script.
Some building blocks of the OpenGLRaw package have been reused from the old
package. These parts are those representing types and the several of the
internals (e.g. the ones for retrieving proc-addresses). These are also found
in BuildSources
, with their License.
There are of course some changes from the OpenGLRaw. (The list is probably not complete, but these are the major points.)
The major change is probably that the core modules have been rearranged.
Compatibility modules can be generated by giving the generator the -c flag.
Raw.hs
now exports the latest OpenGL specification in stead of every binding.
The old naming scheme for functions and enumeration was not very clear on when the extension suffixes should be kept for a function and when not. It seemed to keep the suffix only when there is a version without suffix and the one without suffix is different in specification is different from the one with suffix.
Implementing such a naming scheme in the generator would require quite a bit of extra information about the equality of functions. In the past the generator included two naming schemes, one where all suffixes are kept while the other dropped all of them. After the introduction of the specification in xml format it became clear that the dropping version would generate many name clashes. Therefore it was disabled and later removed. The only naming scheme now available is to keep all extension names.
An example such a name clash is PRIMARY_COLOR
and PRIMARY_COLOR_NV
in the
NV_path_rendering
extension, which would both be mapped to gl_PRIMARY_COLOR
while they have different numerical values. Furthermore there are also similar
clashes that would prevent the generation of extension grouping modules.
The generator can roughly be split in several steps.
- Parsing of the specification files into a specific format (found in
Spec.Parsing
). - Amending and filtering the specification. (found in
Spec.Processing
). - Generating
RawModule
s, a specification of the modules to be generated (found in theModules
namespace). - Generating files from these
RawModule
s (Currently done inMain
andCode.ModuleCode
).
Apart from these steps there are several other modules,
Modules.Types
Defines the types for the abstract modules.Spec.RawSpec
Defines the types for working with the original specification.Main.Options
Defines the commandline options.Main.Monad
Defines theRawGen
monads that distribute the options and does the error handling.
The implementation is based around the .spec files from the OpenGL registry which provide a source of all function and enumerations in use. The files are parsed by a separately packaged spec parser.
The further processing is relatively simple. As the amount of extensions is
quite large there is the possibility to exclude them based on vendor.
Therefore a file (novendor
) is used to filter the categories.
The translation from the specification to code is done via RawModule
, which
specify the contents of a module in the final OpenGLRaw. This extra layer is
added to separate the logic creating the contents from the actual templates
used to generate the code. In addition these intermediate forms can be used to
generate other output. Different types of modules to generate have all there
own module,
Modules.Types
Defines theRawModule
and associated types.Modules.Builder
represents the builder monads used to generate them.Modules.Compatibility
has some functions for generating modules that are no longer present in the new file structure.Modules.GroupModule
has builders for modules that group other modules together to reexport them for easy imports (e.g. for Core and vendor modules).Modules.Module
makes the actual enumeration and functions.Modules.Raw
binds all the modules together to generate the full OpenGLRaw.
The RawModule
s are used to generate to forms of output.
- The real haskell modules are generated using the template from
Code.ModuleCode
. - Two listings specifying the internal modules (
other-modules
field in cabal) inmodulesI.txt
and the external modules (exposed-modules
in cabal) inmodulesE.txt
. - The interface, which describes what each module defines, useful to lookup where a piece (function or enum) has been defined and what its haskell name and type are.
The generator has some quite some dependencies, of which some are managed by using git submodules. The current submodules are
CodeGenerating
to add some extra functions tohaskell-src-exts
for generating source code.opengl-xml
the parser for the xml specification.OpenGLRawgenBase
basic types also used in the interface, which could be used without the generator. This also includes the interface reader and writer.
To simplify the installation (for both users and travis CI) there is a
dependecy installation script depsinstall.sh
. This should be invoked with
your favorite cabal command e.g. ./depsinstall.sh cabal
or ./depsinstall.sh cabal-dev
. Doing so will update the git submodules and install all the
dependencies.