qt5base-lts/util/glgen/README.txt

151 lines
5.8 KiB
Plaintext
Raw Normal View History

OpenGL: Add code generator for OpenGL enabler classes This patch provides a code generator that can be executed offline to generate a few classes for enhancing Qt's support for OpenGL. The generated code effectively provides all the benefits of GLEW in its multi-context form but for all platforms and even for ES2. The code generator takes as input the official Khronos gl.spec specification and gl.tm typemap files. These provide all of the information required to create the OpenGL Desktop related classes. The classes for ES2 are hand-crafted as no similar spec files have been published. The generated code supports all OpenGL extensions listed in the Khronos registry for both Desktop OpenGL and ES 2. There is a helper factory class generated which are used by QOpenGLContext::versionFunctions(). This allows code like the following to be written: QOpenGLFunctions_3_3_Core* m_funcs = 0; m_funcs = m_context->versionFunctions<QOpenGLFunctions_3_3_Core>(); if (!m_funcs) { qWarning() << "Could not obtain required OpenGL context version"; exit(1); } if (!m_funcs->initializeOpenGLFunctions()) { qWarning() << "Failed to resolve entry points"; exit(2); } // Get an extension object QOpenGLExtension_ARB_draw_buffers* ext = 0; if (m_context->hasExtension("GL_ARB_draw_buffers")) { ext = new QOpenGLExtension_ARB_draw_buffers(); ext->initializeOpenGLFunctions(m_context); } Such usage will allow much easier and rigorous use of features in modern OpenGL and extensions both in Qt itself and by users of Qt. Follow-up patches will import the generated files and then use these to reinstate OpenGL geometry shaders, add tessellation shaders, and other OpenGL constructs. Change-Id: Id0172e8aa1fd57eb4e6979a96d10fb5a34826426 Reviewed-by: Samuel Rødal <samuel.rodal@digia.com> Reviewed-by: James Turner <james.turner@kdab.com>
2012-08-08 15:43:48 +00:00
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/