Chapter 9: Hacking OpenTK

This chapter contains instructions for people wishing to modify or extend OpenTK. It describes the project structure, wrapper design, coding style and various caveats and hacks employed by OpenTK to achieve wider platform support.

Project Structure

The OpenTK project consists of a number of managed, cross-platform assemblies:

  • OpenTK: this is the core OpenTK assembly. It provides the Graphics, Audio and Compute APIs, the math toolkit and the platform abstraction layer.
  • OpenTK.Compatibility: this assembly provides an upgrade path for applications compiled against older versions of OpenTK and the Tao Framework. When a deprecated method is removed from core OpenTK, it is added to this dll.
  • OpenTK.GLControl: this assembly provides the GLControl class, which adds OpenGL support to System.Windows.Forms applications.
  • OpenTK.Build: this assembly provides the cross-platform build system for OpenTK. It can be used to generate MSBuild-compatible project files for use with Visual Studio (version 2005 or higher), Sharpdevelop (version 2.0 or higher) and MonoDevelop (version 2.0 or higher).
  • OpenTK.Examples: this assembly provides a number of samples built with OpenTK. It covers topics related to OpenGL, OpenGL|ES, OpenAL, OpenCL and general OpenTK usage.

In addition to these assemblies, OpenTK maintains a custom binding generator which generates the OpenGL, OpenGL|ES and OpenCL bindings. It consists of two assemblies:

  • Converter, which converts the OpenGL|ES and OpenCL C headers to XML files.
  • Bind, which converts the OpenGL .spec files or the Converter XML files into C# code.

Finally, OpenTK provides a QuickStart project, which shows how to setup and build an OpenTK application.

OpenTK Structure

The OpenTK solution provides the following public namespaces:

  • OpenTK: contains classes to create windows (GameWindow, NativeWindow), perform 3d math, interact with the monitor (DisplayDevice, DisplayResolution) as well as query the platform configuration.
  • OpenTK.Graphics: contains bindings for OpenGL and OpenGL|ES.
  • OpenTK.Audio: contains bindings for OpenAL.
  • OpenTK.Compute: contains bindings for OpenCL.
  • OpenTK.Input: contains classes to interact with input devices (Keyboard, Mouse, Joystick).
  • OpenTK.Platform: contains classes to extend OpenTK or interact with the underlying platform.

The public API of OpenTK is completely cross-platform. All platform-specific code is contained in internal interfaces under the OpenTK.Platform namespace. In that sense, most public classes act as façades that forward method calls to the correct platform-specific implementation.

public class Foo : IFoo
{
    IFoo implementation;
 
    public Foo()
    {
        implementation = OpenTK.Platform.Factory.Default.CreateFoo();
    }
 
    #region IFoo Members
 
    public void Bar()
    {
        implementation.Bar();
    }
 
    #endregion
}

This pattern is used in all public OpenTK classes that need platform-specific code to operate: DisplayDevice, DisplayResolution, GraphicsContext, GraphicsMode, NativeWindow and the various input classes.

Classes that do not rely on platform-specific code and classes that contain performance-sensitive code do not use this pattern: the various math classes, the OpenGL, OpenCL and OpenAL bindings, the AudioContext and AudioCapture classes all fall into these categories.

Wrapper Design

OpenTK provides .Net wrappers for a various important native APIs: OpenGL, OpenGL ES, OpenAL and OpenCL (in progress). Unlike similar libraries, OpenTK places an emphasis in usability and developer efficiency, while staying true to the nature of the native interface. To that end, it utilizes a number of .Net constructs that are not available in native C by default:

  • Strongly-typed enum parameters instead of integer constants.
  • Generics instead of void pointers.
  • Namespaces instead of function prefixes ('gl', 'al').
  • Function overloads instead of function suffices (Vector3 instead of Vector3f>, Vector3d, ...).
  • Automatic extension loading.
  • Inline documentation for functions and parameters, accessible through IDE tooltips (intellisense).
  • CLS-compliance, which makes the bindings usable by all .Net languages.
  • Cross-platform support, which allows the bindings to be used by any platform supported by .Net or Mono.

The bindings are generated through an automated binding generator, which converts the official API specifications into C# code. The following pages describe the generation process in detail.

Official API specifications: