Overview
========

This is the glgen application used to generate OpenGL related classes from the
official Khronos OpenGL specification and typemap files.

To run this application download the gl.spec and gl.tm files from:

http://www.opengl.org/registry/api/gl.spec
http://www.opengl.org/registry/api/gl.tm

and place them into the application directory. These files are not stored in
the Qt Project's git repo or downloaded automatically to

a) avoid copyright issues
b) make sure the version of OpenGL used is controlled by a human

The glgen application parses these files and generates:

1) A set of public classes, one for each combination of OpenGL version and profile.
2) A set of backend helper classes that contain the actual function pointers
3) A factory class for the classes in 1)
4) A set of classes, one for each OpenGL extension which introduces new entry points

We will now describe each of these categories.


OpenGL Version and Profile Classes
==================================

The base class of this set is QAbstractOpenGLFunctions. From this we inherit one class
for each OpenGL version and if supported, profile.

The Core profile contains only the non-deprecated functionality. The Compatibility profile
also includes all functionality that was removed in OpenGL 3.1. Therefore, for OpenGL
3.2 onwards we have two classes for each version.

All of these classes are named with the following convention:

QOpenGLFunctions_<MAJOR>_<MINOR>[_PROFILE]

For example QOpenGLFunctions_2_1, QOpenGLFunctions_4_3_Core

The source and header files for these classes take the form

qopenglfunction_<MAJOR>_<MINOR>[_PROFILE].cpp
qopenglfunction_<MAJOR>_<MINOR>[_PROFILE].h

and should be moved to

$QTBASE/src/gui/opengl/

and forms part of the public QtGui library API.


Backend Helper Classes
======================

Every OpenGL function is categorised by which version it was introduced with and
whether it is part of the Core Profile and is deemed part of the core specification
or whther it is only part of the Compatibility profile and has been marked as
deprecated.

Glgen creates a backend helper class containing function pointers to match each
possible case. E.g. QOpenGLFunctions_1_5_CoreBackend contains functions introduced
in OpenGL 1.5 which are still core (not deprecated).

The public frontend classes described above contain pointers to the set of backend
objects necessary to implement the functions for their version and profile.

Creating new instances of these backend objects for each public version functions
object would be wasteful in terms of memory (repeated function pointers) and CPU
time (no need to keep re-solving the same functions).

We cannot share the backend objects globally as OpenGL entry point addresses are
specific to the OpenGL context. They cannot even be reliably shared between a
context group. This is not surprising if you consider the case of contexts in a share
group where the contexts have different versions or even profiles. We therefore share
the backend instances at the QOpenGLContext level using a simple reference counting
scheme.

When the frontend version functions objects are intialized they check to see if
the associated context already has suitable backend objects available. If so they use
them, otherwise they will create backend objects and associate them with the context.

The backend classes are in

qopenglversionfunctions.h
qopenglversionfunctions.cpp

and should also be moved to

$QTBASE/src/gui/opengl/


OpenGL Version and Profile Factory
==================================

Instances of the OpenGL version and profile classes described above can be obtained
from QOpenGLContext by means of the versionFunctions() member. The OpenGLContext
retains ownership of the QOpenGLFunctions_* object. If a suitable object does not
already exist it is created by the factory class generated by glgen.

It is possible to request version functions objects for any version/profile
combination from a context. However not all requests can be serviced. For example
consider the case of an OpenGL 3.3 Core profile context. In this case:

* Requesting a 3.3 core profile functions object would succeed.
* Requesting a 3.3 compatibility profile functions object would fail. We would fail
  to resolve the deprecated functions.
* Requesting a 4.3 core profile functions object would fail. We would fail to resolve
  the new core functions introduced in versions 4.0-4.3.
* Requesting a 3.1 functions object would succeed. There is nothing in 3.1 that is not
  also in 3.3 core.

If a request is not able to be serviced the factory, and hence QOpenGLContext::versionFunctions()
will return a null pointer that can be checked for.

The source and header file for this class should be moved to

$QTBASE/src/gui/opengl/

and forms part of the QtGui library.

If a user instantiates a version functions object directly (i.e. not via QOpenGLContext)
then it bypasses the above checks. However, the same checks are applied in the
initializeOpenGLFunctions() method and the result can once again be checked.

This approach allows maximum flexibility but ensure's safety in that once the user
posesses a functions object that has been successfully initialized they can rely upon its
member functions being successfully resolved.


OpenGL Extension Classes
========================

In addition, glgen also creates one class for each OpenGL extension that introduces
new entry points. These classes are named with the convention

QOpenGLExtension_<name-of-extension>

The usage pattern for OpenGL extensions is to just use a small
number of extensions out of the large number of those available.

Rather than bloat QtGui with all possible extensions, a new static library will be
introduced to hold these classes. That way users will only link in the code for
the extensions that they actually use.

The source and header file for these classes should be moved to

$QTBASE/src/openglextensions/