The binding generator
--------------------------------------------------------------------

OpenGL and OpenAL binding methods are now generated by the generator tool
located in org.lwjgl.util.generator.*. This includes the OpenGL java source files in
org.lwjgl.opengl.* and the OpenAL source files in org.lwjgl.openal.*. The
generator itself is based on the Annotation Processing
Tool, 'apt', bundled with the 1.5 JDK. The initial implementation is designed
to completely replace the manually generated java and native source, but not
introduce any new functionality. The user-visible bindings API will not
change. Later, having the source generated will make it much easier to
implement additional binding features. Examples include:

1. Support for multiple contexts and consequently multiple function pointer
sets. This feature along with support for an AWT compatible OpenGL Canvas is
my primary motivation for the generator.
2. Support for java native arrays.
3. More extensive debugging and checking.
4. Changes in the naming convention (e.g., removing the 'gl' prefix).

Note that all additional features can be enabled/disabled at build time,
according to the performance and conformance requirements.

You're invited to browse the generator source, the templates and the generated
source to get a feel of how the generator works.

Requirements
------------
The generator needs a JDK 1.5, since template files depend on annotations and
the generator itself works as an annotation processor in the APT framework.
Since we support Mac OS X which only includes java 1.5 from Mac OS X 10.4, the
generated files are in CVS and the generator is not invoked in a default build.

How to use it
-------------
The generator is invoked from ant with 'ant generate-all'.

If you want to do a stripped version of LWJGL including only a select subset
of extensions and core function sets, use the "opengl-template-pattern"
ant property. For example, this will only create source files for the core
OpenGL functions:

ant -Dopengl-template-pattern="org/lwjgl/opengl/GL*.java" clean-generated
generate-all

How it works
------------
The generator reads template files from src/templates. Template files are
regular java interfaces containing zero or more constant fields and zero or
more annotated methods. Each interface will generate a java source file in
src/java and, if needed, a native source file in src/native/common.

There's an auxillary generator that creates the ContextCapabilities class. It
is invoked as part of the 'generate-all' and target. It can also be invoked
stand-alone with the target 'generate-opengl-capabilites'.

Template file format
--------------------
A template file is a regular java interface with annotations describing the
information that cannot be represented in a regular java source file. An
example template file is listed here:

package org.lwjgl.opengl;

import org.lwjgl.generator.*;

public interface EXT_blend_equation_separate {
	/*
	 * Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
	 * GetFloatv, and GetDoublev:
	 */
	public static final int GL_BLEND_EQUATION_RGB_EXT =
		0x8009;
	public static final int GL_BLEND_EQUATION_ALPHA_EXT
		= 0x883D;

	public void glBlendEquationSeparateEXT(@GLenum
			int modeRGB, @GLenum int modeAlpha);
}

The template file is named after the extension name or GL*/AL*, and there is exactly one method
for each function symbol in the extension. The method name will be used to
look up the symbol in the driver, so make sure it is correct.

Apart from the naming convention of the interface, the most notable annotation
group is the native types. As can be seen from the example, the modeRGB and
modeAlpha parameters is annotated with @GLenum to tell the generator which
native type the parameter has. If the native type is not specified the native
type is defaulted to the corresponding native type. For example, the
corresponding native type for 'int' is GLint when generating OpenGL source and
ALint when generating OpenAL source.

Another important feature is the multityped methods. An example:

public void glVertexPointer(int size, @AutoType("pointer") @GLenum int type, @GLsizei int stride,
		@BufferObject(BufferKind.ArrayVBO)
		@Check
		@Const
		@GLint
		@GLfloat
		Buffer
		pointer);

Note that the parameter 'pointer' is annotated with multiple native types and
is a java.nio.Buffer. This tells generator to generate multiple versions of
glVertexPointer, one for each native type. Additionally, the @AutoType
annotation tells the generator to automatically generate a type from the
Buffer type. The generated source looks like this:

public static void glVertexPointer(int size, int stride, IntBuffer pointer) {
	GLBufferChecks.ensureArrayVBOdisabled();
	BufferChecks.checkDirect(pointer);
	nglVertexPointer(size, GL11.GL_INT, stride, pointer, pointer.position() << 2);
}
public static void glVertexPointer(int size, int stride, FloatBuffer pointer) {
	GLBufferChecks.ensureArrayVBOdisabled();
	BufferChecks.checkDirect(pointer);
	nglVertexPointer(size, GL11.GL_FLOAT, stride, pointer, pointer.position() << 2);
}
private static native void nglVertexPointer(int size, int type, int stride, Buffer pointer, int pointer_position);

Notice how the type parameter is not included in the public method and that
its value is pre-computed by the generator. @AutoSize specifies that the
remaining() of a Buffer argument should be inserted (In this case, a @Check is
not necessary). A more complex case is when both
the signed and unsigned native type mapping to one java type is specified. In
that case the generator creates an 'unsigned' boolean parameter that selects the
desired type. See GL11.glColorPointer for an example of this.

The @BufferObject annotation is used to specify VBO or PBO support. It tells the generator that the
parameter can take an integer offset and a separate buffer object method
version should be created. The generated code looks like this:

public static void glVertexPointer(int size, int type, int stride, int pointer_buffer_offset) {
	GLBufferChecks.ensureArrayVBOenabled();
	nglVertexPointerBO(size, type, stride, pointer_buffer_offset);
}
private static native void nglVertexPointerBO(int size, int type, int stride, int pointer_buffer_offset);

The @Check annotation specify how a buffer argument is to be checked. @Check
with no value implies a simple BufferChecks.checkDirect() check, while a
non-empty value indicates a BufferChecks.checkBuffer() check. Additionally,
canBeNull can be specified to allow null arguments. The default value for
canBeNull is false.

The @StripPostfix annotation is specified to strip the method of its postfix,
according the a specified parameter type. For example,

@StripPostfix("values")
public void glGetPixelMapfv(@GLenum int map, @Check("256") @BufferObject(BufferKind.PackPBO) FloatBuffer values);

Becomes:

public static void glGetPixelMap(int map, FloatBuffer values) {
	GLBufferChecks.ensurePackPBOdisabled();
	BufferChecks.checkBuffer(values, 256);
	nglGetPixelMapfv(map, values, values.position());
}
private static native void nglGetPixelMapfv(int map, FloatBuffer values, int values_position);
public static void glGetPixelMapfv(int map, int values_buffer_offset) {
	GLBufferChecks.ensurePackPBOenabled();
	nglGetPixelMapfvBO(map, values_buffer_offset);
}
private static native void nglGetPixelMapfvBO(int map, int values_buffer_offset);

 - elias
