Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

OpenGL Library

Table of Contents

  1. OpenGL Library
    1. Prerequisites
    2. Compilation Options
    3. Initialization
  2. Library Reference
    1. gl.load()
    2. Type Constants
    3. gl.version()
    4. Extensions
    5. Most Everything
    6. Special Functions
      1. gl.gluErrorString(code: int)
      2. gl.gluGetString(code: int)
      3. gl.glShaderSource(shader: int, code: string)
      4. gl.glShaderSourceARB(shader: int, code: string)
      5. gl.glMapBuffer(target: int, access: int, size: int[, vec: Vector])
    7. Unsupported Functions

Work in Progress

This library is not yet finished. It may be useful for some tasks, but is still missing features and some features may change or be removed.

OpenGL is a cross-platform standard 3D graphics API. Hooray!

This addon attempts to bind to as much of OpenGL and its numerous extensions as efficiently and transparently as possible. Every attempt has been made to preserve the names, parameter types, and feel of the raw native library. It does no heap allocations (except possibly for string and Vector return values). No attempt is made to check the validity of data passed to the GL. This means this library is unsafe and has the potential to crash your app if misused.

Prerequisites

This library requires Derelict. You (obviously) need an OpenGL driver installed. I don't know if it's even possible to have a computer without one these days.

Also, you need to have created an OpenGL context. This can most easily be done by using the SDL Addon, but you're free to use whatever method you want.

Currently I don't think multiple contexts are supported. On Windows at least, I think extensions have different entry points with different contexts or something dumb like that. Sorry.

Compilation Options

By default, this library does not perform any kind of error checking. When doing development, though, it can be nice to not have to call glCheckError after every friggin' call. By defining the MDGLCheckErrors version, this library will call glCheckError after each call (unless it's currently in a glBegin..glEnd block, of course), and if an error occurred, an exception will be thrown with the name of the function that caused the error followed by the description obtained by gluErrorString. This adds some overhead, of course - not only does it have to check the error after every call, but it also has to check a global indicating whether or not it is in a glBegin..glEnd block on every call. Profile!

Initialization

To initialize the library within your host app, just do this:

import minid.addons.gl;
...

// after opening a VM and loading the standard libraries into it
GlLib.init(t);

That's it. Now any MiniD code loaded by your host program will be able to import the "gl" module.

Library Reference

This library is exposed through the "gl" module in MiniD.

When you first import this library, before you've initialized it, there is only one function in it: load. You must call it to be able to access any other functions.

gl.load()

Call this function after you've created a GL context in order to load the GL lib. If no context has been created yet, an exception will be thrown. If the library has already been loaded, this function just returns immediately.

This function loads as much as it can. It will always load GL 1.0 and 1.1 functions and the GLU library. Everything else is optional. Depending on your driver's version, it will load up to (and including) GL 2.1. It will also load any extensions your driver supports. Any functions your driver doesn't support simply will not appear in the gl namespace.

If everything goes well, when this function returns, you can start using OpenGL.

Type Constants

There are some string constants defined in gl for use with the Vector class. They are: GLenum, GLboolean, GLbitfield, GLbyte, GLshort, GLint, GLubyte, GLushort, GLuint, GLsizei, GLfloat, GLclampf, GLdouble, and GLclampd. Each of these holds a Vector type code that corresponds to the given native OpenGL type. You should try to use these instead of using raw type codes yourself in order to reduce platform-specific behavior. For instance, to allocate a Vector of GLfloats:

local v = Vector(gl.GLfloat, 64)

gl.version()

Returns a string indicating the highest supported version of OpenGL. This will be of the form "Version X.Y", where "X.Y" is the version number.

Extensions

Naming convention: this library uses the same extension naming convention as Derelict. Basically, if the original extension name was something like NV_float_buffer, it becomes NVFloatBuffer in this naming scheme.

As mentioned in gl.load, any supported extensions are loaded. In order to see what extensions are supported, there is a namespace gl.ext which contains the names of every extension mapping to booleans indicating whether or not that extension is supported. For instance, if you want to see if the NVFloatBuffer extension is supported, gl.ext.NVFloatBuffer will tell you. To get a list of supported extensions, you could do something like:

local supportedExts = [name for name, loaded in gl.ext if loaded].sort()

If an extension is supported, all its functions and constants will simply be loaded into the gl namespace, like gl.glSetFenceNV for instance.

Most Everything

I'm not going to list every function and its signature. That's what the OpenGL docs are for. However what you do need to know is how the native function parameter types are mapped to MiniD.

Original GL typeMiniD type
GLbooleanbool
GLenum, GLbitfield, GLbyte, GLubyte, GLshort, GLushort, GLint, GLuint, GLsizeiint
GLfloat, GLclampf, GLdouble, GLclampdfloat
GLcharchar
GLchar*string
Most other pointer typesnull, int, Vector

That last row is interesting. GL uses its pointer parameters somewhat freely. Sometimes they accept pointers to blocks of memory, and other times they accept integers (I'm looking at you, glVertexPointer). In order to allow all the different possibilities, pointer parameters will accept null, an integer, or a Vector object.

When passing Vector objects to the GL, keep in mind that it does not keep a reference to the vector. It is your responsibility to ensure that the Vector object is not collected while the GL is using it. This isn't likely to come up that often, but it's easy to prevent issues: just keep a reference around.

Return types are a similar case. Pointer returns are not supported right now except for those which return a GLchar*, in which case they are converted to a string.

Special Functions

Some functions are special, in that they don't follow the pattern set by other wrapped functions. Sometimes this is because the idiom used in the underlying GL function doesn't map well to MiniD. The following functions are just a little bit.. special.

gl.gluErrorString(code: int)

This is only special because the return type is defined as GLubyte* for some God-only-knows-why reason. It returns a string. Shouldn't that be, I don't know, GLchar*?

gl.gluGetString(code: int)

Same story as above.

gl.glShaderSource(shader: int, code: string)

This is somewhat different because the underlying GL function takes an array of strings. There's not much reason to support this behavior in MiniD since, well, if you have an array of strings, you can just join them all.

gl.glShaderSourceARB(shader: int, code: string)

Same story as above.

gl.glMapBuffer(target: int, access: int, size: int[, vec: Vector])

This is a fun one. The underlying function normally returns a void*. The closest MiniD type to that would be a Vector. Fortunately, we know the size, so we know how big to make the Vector. This function returns a Vector object that does not own its memory (i.e. it cannot be resized in any way). Its type will be u8 and its length will be size. If you want to reuse an existing Vector object, pass it as the vec parameter; it can be any type and size.

Unsupported Functions

Some functions are not yet supported. Most of them are functions that return pointers without any indication of the length. These will probably become integer returns (since pointer parameters can accept ints). A listing:

  • glGetPointerv
  • Any glu function that takes or returns a GLUnurbs*, GLUquadric*, or GLUtess*.
  • glMultiDrawElements - not sure how to tackle this one.. array of pointers, hm.
  • glGetBufferPointerv
  • glGetVertexAttribPointerv
  • glMapBufferARB
  • glMapObjectBufferATI