9eb9bd703b
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>
221 lines
8.6 KiB
Plaintext
221 lines
8.6 KiB
Plaintext
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
|
|
** Contact: http://www.qt-project.org/legal
|
|
**
|
|
** This file is part of the QtGui module of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:LGPL$
|
|
** Commercial License Usage
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
** accordance with the commercial license agreement provided with the
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
** a written agreement between you and Digia. For licensing terms and
|
|
** conditions see http://qt.digia.com/licensing. For further information
|
|
** use the contact form at http://qt.digia.com/contact-us.
|
|
**
|
|
** GNU Lesser General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
** General Public License version 2.1 as published by the Free Software
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
** packaging of this file. Please review the following information to
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
**
|
|
** In addition, as a special exception, Digia gives you certain additional
|
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
** General Public License version 3.0 as published by the Free Software
|
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
|
** packaging of this file. Please review the following information to
|
|
** ensure the GNU General Public License version 3.0 requirements will be
|
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
**
|
|
** This file was generated by glgen version 0.1
|
|
** Command line was: glgen
|
|
**
|
|
** glgen is Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
|
|
**
|
|
** This is an auto-generated file.
|
|
** Do not edit! All changes made to it will be lost.
|
|
**
|
|
****************************************************************************/
|
|
|
|
#include "qopenglversionfunctions.h"
|
|
#include "qopenglcontext.h"
|
|
#include "qdebug.h"
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
QOpenGLVersionFunctionsBackend *QAbstractOpenGLFunctionsPrivate::functionsBackend(QOpenGLContext *context,
|
|
const QOpenGLVersionStatus &v)
|
|
{
|
|
Q_ASSERT(context);
|
|
return context->functionsBackend(v);
|
|
}
|
|
|
|
void QAbstractOpenGLFunctionsPrivate::insertFunctionsBackend(QOpenGLContext *context,
|
|
const QOpenGLVersionStatus &v,
|
|
QOpenGLVersionFunctionsBackend *backend)
|
|
{
|
|
Q_ASSERT(context);
|
|
context->insertFunctionsBackend(v, backend);
|
|
}
|
|
|
|
void QAbstractOpenGLFunctionsPrivate::removeFunctionsBackend(QOpenGLContext *context, const QOpenGLVersionStatus &v)
|
|
{
|
|
Q_ASSERT(context);
|
|
context->removeFunctionsBackend(v);
|
|
}
|
|
|
|
|
|
/*!
|
|
\class QAbstractOpenGLFunctions
|
|
\inmodule QtGui
|
|
\since 5.1
|
|
\brief The QAbstractOpenGLFunctions class is the base class of a family of
|
|
classes that expose all functions for each OpenGL version and
|
|
profile.
|
|
|
|
OpenGL implementations on different platforms are able to link to a variable
|
|
number of OpenGL functions depending upon the OpenGL ABI on that platform.
|
|
For example, on Microsoft Windows only functions up to those in OpenGL 1.1
|
|
can be linked to at build time. All other functions must be resolved at
|
|
runtime. The traditional solution to this has been to use either
|
|
QOpenGLContext::getProcAddress() or QOpenGLFunctions. The former is tedious
|
|
and error prone and means dealing directly with function pointers. The
|
|
latter only exposes those functions common to OpenGL ES 2 and desktop
|
|
OpenGL. There is however much new OpenGL functionality that is useful when
|
|
writing real world OpenGL applications.
|
|
|
|
Qt now provides a family of classes which all inherit from
|
|
QAbstractOpenGLFunctions which expose every core OpenGL function by way of a
|
|
corresponding member function. There is a class for every valid combination
|
|
of OpenGL version and profile. Each class follows the naming convention
|
|
QOpenGLFunctions_<MAJOR VERSION>_<MINOR VERSION>[_PROFILE].
|
|
|
|
For OpenGL versions 1.0 through to 3.0 there are no profiles, leading to the
|
|
classes:
|
|
|
|
\list
|
|
\li QOpenGLFunctions_1_0
|
|
\li QOpenGLFunctions_1_1
|
|
\li QOpenGLFunctions_1_2
|
|
\li QOpenGLFunctions_1_3
|
|
\li QOpenGLFunctions_1_4
|
|
\li QOpenGLFunctions_1_5
|
|
\li QOpenGLFunctions_2_0
|
|
\li QOpenGLFunctions_2_1
|
|
\li QOpenGLFunctions_3_0
|
|
\endlist
|
|
|
|
where each class inherits from QAbstractOpenGLFunctions.
|
|
|
|
OpenGL version 3.1 removed many deprecated functions leading to a much
|
|
simpler and generic API.
|
|
|
|
With OpenGL 3.2 the concept of profiles was introduced. Two profiles are
|
|
currently defined for OpenGL: Core and Compatibility.
|
|
|
|
The Core profile does not include any of the functions that were removed
|
|
in OpenGL 3.1. The Compatibility profile contains all functions in the
|
|
Core profile of the same version plus all of the functions that were
|
|
removed in OpenGL 3.1. In this way the Compatibility profile classes allow
|
|
use of newer OpenGL functionality but also allows you to keep using your
|
|
legacy OpenGL code. For new OpenGL code the Core profile should be
|
|
preferred.
|
|
|
|
Please note that some vendors, notably Apple, do not implement the
|
|
Compatibility profile. Therefore if you wish to target new OpenGL features
|
|
on OS X then you should ensure that you request a Core profile context via
|
|
QSurfaceFormat::setProfile().
|
|
|
|
Qt provides classes for all version and Core and Compatibility profile
|
|
combinations. The classes for OpenGL versions 3.1 through to 4.3 are:
|
|
|
|
\list
|
|
\li QOpenGLFunctions_3_1
|
|
\li QOpenGLFunctions_3_2_Core
|
|
\li QOpenGLFunctions_3_2_Compatibility
|
|
\li QOpenGLFunctions_3_3_Core
|
|
\li QOpenGLFunctions_3_3_Compatibility
|
|
\li QOpenGLFunctions_4_0_Core
|
|
\li QOpenGLFunctions_4_0_Compatibility
|
|
\li QOpenGLFunctions_4_1_Core
|
|
\li QOpenGLFunctions_4_1_Compatibility
|
|
\li QOpenGLFunctions_4_2_Core
|
|
\li QOpenGLFunctions_4_2_Compatibility
|
|
\li QOpenGLFunctions_4_3_Core
|
|
\li QOpenGLFunctions_4_3_Compatibility
|
|
\endlist
|
|
|
|
where each class inherits from QAbstractOpenGLFunctions.
|
|
|
|
A pointer to an object of the class corresponding to the version and
|
|
profile of OpenGL in use can be obtained from
|
|
QOpenGLFunctions::versionFunctions(). If obtained in this way, note that
|
|
the QOpenGLContext retains ownership of the object. This is so that only
|
|
one instance need be created.
|
|
|
|
Before calling any of the exposed OpenGL functions you must ensure that the
|
|
object has resolved the function pointers to the OpenGL functions. This
|
|
only needs to be done once per instance with initializeOpenGLFunctions().
|
|
Once initialized, the object can be used to call any OpenGL function for
|
|
the corresponding version and profile. Note that initializeOpenGLFunctions()
|
|
can fail in some circumstances so check the return value. Situations in
|
|
which initialization can fail are if you have a functions object for a version
|
|
or profile that contains functions that are not part of the context being
|
|
used to resolve the function pointers.
|
|
|
|
If you exclusively use function objects then you will get compile time
|
|
errors if you attempt to use a function not included in that version and
|
|
profile. This is obviously a lot easier to debug than undefined behavior
|
|
at run time.
|
|
|
|
\sa QOpenGLContext::versionFunctions()
|
|
*/
|
|
QAbstractOpenGLFunctions::QAbstractOpenGLFunctions()
|
|
: d_ptr(new QAbstractOpenGLFunctionsPrivate)
|
|
{
|
|
}
|
|
|
|
QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions()
|
|
{
|
|
delete d_ptr;
|
|
}
|
|
|
|
bool QAbstractOpenGLFunctions::initializeOpenGLFunctions()
|
|
{
|
|
Q_D(QAbstractOpenGLFunctions);
|
|
d->initialized = true;
|
|
return true;
|
|
}
|
|
|
|
bool QAbstractOpenGLFunctions::isInitialized() const
|
|
{
|
|
Q_D(const QAbstractOpenGLFunctions);
|
|
return d->initialized;
|
|
}
|
|
|
|
void QAbstractOpenGLFunctions::setOwningContext(const QOpenGLContext *context)
|
|
{
|
|
Q_D(QAbstractOpenGLFunctions);
|
|
d->owningContext = const_cast<QOpenGLContext*>(context);
|
|
}
|
|
|
|
QOpenGLContext *QAbstractOpenGLFunctions::owningContext() const
|
|
{
|
|
Q_D(const QAbstractOpenGLFunctions);
|
|
return d->owningContext;
|
|
}
|
|
|
|
#if !defined(QT_OPENGL_ES_2)
|
|
|