go-gl/gl — pull request #128 by Niriel (2013-10-19 09:30:18+00:00)
Title: Added GetUniformBlockIndex and UniformBlockBinding.

Rationale.
==========

I would like two introduce one data type and two methods that are the bare minimum to get **Uniform Buffer Objects** (UBO) to work.

UBOs provide an efficient way to

1. share uniforms between programs (for instance, projection and view matrix set once per frame instead of once per program),
2. store BIG uniforms (could get useful when instancing a lot).

Implementation.
===============

UniformBlockIndex type.
-----------------------
Uniform Blocks have an "index", like Uniforms and Attribs have a "location". The index is an unsigned int while locations are signed.

For consistency with the rest of go-gl/gl, I created a new type `UniformBlockIndex`, declared in its own file `uniformblockindex.go`. However, unlike `UniformLocation` and `AttribLocation`, this type does not require any method. Indeed, a Uniform Block Index is not used directly to associate a UBO to a program, one extra step (the Uniform Binding point) is required.

This is all very well described by Jason L. McKesson (aka Nicol Bolas) in his tutorial [Shared Uniforms](http://www.arcsynthesis.org/gltut/Positioning/Tut07%20Shared%20Uniforms.html).

glGetUniformBlockIndex wrapper.
-------------------------------
OpenGL documentation [glGetUniformBlockIndex](http://www.opengl.org/sdk/docs/man3/xhtml/glGetUniformBlockIndex.xml).

I attached a `GetUniformBlockIndex` method to the `Program` type, as it is very similar to `GetUniformLocation`. `Program.GetUniformBlockIndex` returns a `UniformBlockIndex`. Note that old versions of GLEW will prevent the package from compiling here. I had GLEW 1.6 on my machine, which had a bug in its header file (it used char instead of GLchar for the name). GLEW 1.10 is fine.

glUniformBlockBinding wrapper.
------------------------------
OpenGL documentation [glUniformBlockBinding](http://www.opengl.org/sdk/docs/man3/xhtml/glUniformBlockBinding.xml).

Since `glUniformBlockBinding` require three things (the program, the index and the binding), I had to choose which of the three corresponding types would be the main one and become the receiver for the method. I settled for `Program`. Indeed, `glUniformBlockBinding(program, block_index, block_binding)` means something like

program.BlockBinding[block_index] = block_binding // Pseudo-code.

So `Program` seemed a good receiver for the method.

Note that the block binding does not have its own dedicated type. It is just an unsigned integer `uint`, the same that is used in `Buffer.BindBufferBase` and `Buffer.BindBufferRange` which were already implemented.