summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl/qopenglvertexarrayobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/opengl/qopenglvertexarrayobject.cpp')
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.cpp531
1 files changed, 0 insertions, 531 deletions
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp
deleted file mode 100644
index f15fe06ee8..0000000000
--- a/src/gui/opengl/qopenglvertexarrayobject.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sean Harmer <sean.harmer@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qopenglvertexarrayobject.h"
-
-#include <QtCore/private/qobject_p.h>
-#include <QtCore/qthread.h>
-#include <QtGui/qopenglcontext.h>
-#include <QtGui/qoffscreensurface.h>
-#include <QtGui/qguiapplication.h>
-
-#include <QtGui/qopenglfunctions_3_0.h>
-#include <QtGui/qopenglfunctions_3_2_core.h>
-
-#include <private/qopenglextensions_p.h>
-#include <private/qopenglvertexarrayobject_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLFunctions_3_0;
-class QOpenGLFunctions_3_2_Core;
-
-void qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper, QOpenGLContext *context)
-{
- Q_ASSERT(helper);
- Q_ASSERT(context);
-
- bool tryARB = true;
-
- if (context->isOpenGLES()) {
- if (context->format().majorVersion() >= 3) {
- QOpenGLExtraFunctionsPrivate *extra = static_cast<QOpenGLExtensions *>(context->extraFunctions())->d();
- helper->GenVertexArrays = extra->f.GenVertexArrays;
- helper->DeleteVertexArrays = extra->f.DeleteVertexArrays;
- helper->BindVertexArray = extra->f.BindVertexArray;
- helper->IsVertexArray = extra->f.IsVertexArray;
- tryARB = false;
- } else if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
- helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArraysOES"));
- helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArraysOES"));
- helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArrayOES"));
- helper->IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArrayOES"));
- tryARB = false;
- }
- } else if (context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object")) &&
- !context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
- helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArraysAPPLE"));
- helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArraysAPPLE"));
- helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArrayAPPLE"));
- helper->IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArrayAPPLE"));
- tryARB = false;
- }
-
- if (tryARB && context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
- helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArrays"));
- helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArrays"));
- helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArray"));
- helper->IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArray"));
- }
-}
-
-class QOpenGLVertexArrayObjectPrivate : public QObjectPrivate
-{
-public:
- QOpenGLVertexArrayObjectPrivate()
- : vao(0)
- , vaoFuncsType(NotSupported)
- , context(nullptr)
- {
- }
-
- ~QOpenGLVertexArrayObjectPrivate()
- {
- if (vaoFuncsType == ARB || vaoFuncsType == APPLE || vaoFuncsType == OES)
- delete vaoFuncs.helper;
- }
-
- bool create();
- void destroy();
- void bind();
- void release();
- void _q_contextAboutToBeDestroyed();
-
- Q_DECLARE_PUBLIC(QOpenGLVertexArrayObject)
-
- GLuint vao;
-
- union {
- QOpenGLFunctions_3_0 *core_3_0;
- QOpenGLFunctions_3_2_Core *core_3_2;
- QOpenGLVertexArrayObjectHelper *helper;
- } vaoFuncs;
- enum {
- NotSupported,
- Core_3_0,
- Core_3_2,
- ARB,
- APPLE,
- OES
- } vaoFuncsType;
-
- QOpenGLContext *context;
-};
-
-bool QOpenGLVertexArrayObjectPrivate::create()
-{
- if (vao) {
- qWarning("QOpenGLVertexArrayObject::create() VAO is already created");
- return false;
- }
-
- Q_Q(QOpenGLVertexArrayObject);
-
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- if (!ctx) {
- qWarning("QOpenGLVertexArrayObject::create() requires a valid current OpenGL context");
- return false;
- }
-
- //Fail early, if context is the same as ctx, it means we have tried to initialize for this context and failed
- if (ctx == context)
- return false;
-
- context = ctx;
- QObject::connect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
-
- if (ctx->isOpenGLES()) {
- if (ctx->format().majorVersion() >= 3 || ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
- vaoFuncs.helper = new QOpenGLVertexArrayObjectHelper(ctx);
- vaoFuncsType = OES;
- vaoFuncs.helper->glGenVertexArrays(1, &vao);
- }
- } else {
- vaoFuncs.core_3_0 = nullptr;
- vaoFuncsType = NotSupported;
- QSurfaceFormat format = ctx->format();
-#ifndef QT_OPENGL_ES_2
- if (format.version() >= qMakePair<int, int>(3,2)) {
- vaoFuncs.core_3_2 = ctx->versionFunctions<QOpenGLFunctions_3_2_Core>();
- vaoFuncsType = Core_3_2;
- vaoFuncs.core_3_2->glGenVertexArrays(1, &vao);
- } else if (format.majorVersion() >= 3) {
- vaoFuncs.core_3_0 = ctx->versionFunctions<QOpenGLFunctions_3_0>();
- vaoFuncsType = Core_3_0;
- vaoFuncs.core_3_0->glGenVertexArrays(1, &vao);
- } else
-#endif
- if (ctx->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
- vaoFuncs.helper = new QOpenGLVertexArrayObjectHelper(ctx);
- vaoFuncsType = ARB;
- vaoFuncs.helper->glGenVertexArrays(1, &vao);
- } else if (ctx->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
- vaoFuncs.helper = new QOpenGLVertexArrayObjectHelper(ctx);
- vaoFuncsType = APPLE;
- vaoFuncs.helper->glGenVertexArrays(1, &vao);
- }
- }
-
- return (vao != 0);
-}
-
-void QOpenGLVertexArrayObjectPrivate::destroy()
-{
- Q_Q(QOpenGLVertexArrayObject);
-
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- QOpenGLContext *oldContext = nullptr;
- QSurface *oldContextSurface = nullptr;
- QScopedPointer<QOffscreenSurface> offscreenSurface;
- if (context && context != ctx) {
- oldContext = ctx;
- oldContextSurface = ctx ? ctx->surface() : nullptr;
- // Before going through the effort of creating an offscreen surface
- // check that we are on the GUI thread because otherwise many platforms
- // will not able to create that offscreen surface.
- if (QThread::currentThread() != qGuiApp->thread()) {
- ctx = nullptr;
- } else {
- // Cannot just make the current surface current again with another context.
- // The format may be incompatible and some platforms (iOS) may impose
- // restrictions on using a window with different contexts. Create an
- // offscreen surface (a pbuffer or a hidden window) instead to be safe.
- offscreenSurface.reset(new QOffscreenSurface);
- offscreenSurface->setFormat(context->format());
- offscreenSurface->create();
- if (context->makeCurrent(offscreenSurface.data())) {
- ctx = context;
- } else {
- qWarning("QOpenGLVertexArrayObject::destroy() failed to make VAO's context current");
- ctx = nullptr;
- }
- }
- }
-
- if (context) {
- QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
- context = nullptr;
- }
-
- if (vao && ctx) {
- switch (vaoFuncsType) {
-#ifndef QT_OPENGL_ES_2
- case Core_3_2:
- vaoFuncs.core_3_2->glDeleteVertexArrays(1, &vao);
- break;
- case Core_3_0:
- vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao);
- break;
-#endif
- case ARB:
- case APPLE:
- case OES:
- vaoFuncs.helper->glDeleteVertexArrays(1, &vao);
- break;
- default:
- break;
- }
-
- vao = 0;
- }
-
- if (oldContext && oldContextSurface) {
- if (!oldContext->makeCurrent(oldContextSurface))
- qWarning("QOpenGLVertexArrayObject::destroy() failed to restore current context");
- }
-}
-
-/*!
- \internal
-*/
-void QOpenGLVertexArrayObjectPrivate::_q_contextAboutToBeDestroyed()
-{
- destroy();
-}
-
-void QOpenGLVertexArrayObjectPrivate::bind()
-{
- switch (vaoFuncsType) {
-#ifndef QT_OPENGL_ES_2
- case Core_3_2:
- vaoFuncs.core_3_2->glBindVertexArray(vao);
- break;
- case Core_3_0:
- vaoFuncs.core_3_0->glBindVertexArray(vao);
- break;
-#endif
- case ARB:
- case APPLE:
- case OES:
- vaoFuncs.helper->glBindVertexArray(vao);
- break;
- default:
- break;
- }
-}
-
-void QOpenGLVertexArrayObjectPrivate::release()
-{
- switch (vaoFuncsType) {
-#ifndef QT_OPENGL_ES_2
- case Core_3_2:
- vaoFuncs.core_3_2->glBindVertexArray(0);
- break;
- case Core_3_0:
- vaoFuncs.core_3_0->glBindVertexArray(0);
- break;
-#endif
- case ARB:
- case APPLE:
- case OES:
- vaoFuncs.helper->glBindVertexArray(0);
- break;
- default:
- break;
- }
-}
-
-
-/*!
- \class QOpenGLVertexArrayObject
- \brief The QOpenGLVertexArrayObject class wraps an OpenGL Vertex Array Object.
- \inmodule QtGui
- \since 5.1
- \ingroup painting-3D
-
- A Vertex Array Object (VAO) is an OpenGL container object that encapsulates
- the state needed to specify per-vertex attribute data to the OpenGL pipeline.
- To put it another way, a VAO remembers the states of buffer objects (see
- QOpenGLBuffer) and their associated state (e.g. vertex attribute divisors).
- This allows a very easy and efficient method of switching between OpenGL buffer
- states for rendering different "objects" in a scene. The QOpenGLVertexArrayObject
- class is a thin wrapper around an OpenGL VAO.
-
- For the desktop, VAOs are supported as a core feature in OpenGL 3.0 or newer and by the
- GL_ARB_vertex_array_object for older versions. On OpenGL ES 2, VAOs are provided by
- the optional GL_OES_vertex_array_object extension. You can check the version of
- OpenGL with QOpenGLContext::surfaceFormat() and check for the presence of extensions
- with QOpenGLContext::hasExtension().
-
- As with the other Qt OpenGL classes, QOpenGLVertexArrayObject has a create()
- function to create the underlying OpenGL object. This is to allow the developer to
- ensure that there is a valid current OpenGL context at the time.
-
- Once you have successfully created a VAO the typical usage pattern is:
-
- \list
- \li In scene initialization function, for each visual object:
- \list
- \li Bind the VAO
- \li Set vertex data state for this visual object (vertices, normals, texture coordinates etc.)
- \li Unbind (release()) the VAO
- \endlist
- \li In render function, for each visual object:
- \list
- \li Bind the VAO (and shader program if needed)
- \li Call a glDraw*() function
- \li Unbind (release()) the VAO
- \endlist
- \endlist
-
- The act of binding the VAO in the render function has the effect of restoring
- all of the vertex data state setup in the initialization phase. In this way we can
- set a great deal of state when setting up a VAO and efficiently switch between
- state sets of objects to be rendered. Using VAOs also allows the OpenGL driver
- to amortise the validation checks of the vertex data.
-
- \note Vertex Array Objects, like all other OpenGL container objects, are specific
- to the context for which they were created and cannot be shared amongst a
- context group.
-
- \sa QOpenGLVertexArrayObject::Binder, QOpenGLBuffer
-*/
-
-/*!
- Creates a QOpenGLVertexArrayObject with the given \a parent. You must call create()
- with a valid OpenGL context before using.
-*/
-QOpenGLVertexArrayObject::QOpenGLVertexArrayObject(QObject* parent)
- : QObject(*new QOpenGLVertexArrayObjectPrivate, parent)
-{
-}
-
-/*!
- \internal
-*/
-QOpenGLVertexArrayObject::QOpenGLVertexArrayObject(QOpenGLVertexArrayObjectPrivate &dd)
- : QObject(dd)
-{
-}
-
-/*!
- Destroys the QOpenGLVertexArrayObject and the underlying OpenGL resource.
-*/
-QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject()
-{
- destroy();
-}
-
-/*!
- Creates the underlying OpenGL vertex array object. There must be a valid OpenGL context
- that supports vertex array objects current for this function to succeed.
-
- Returns \c true if the OpenGL vertex array object was successfully created.
-
- When the return value is \c false, vertex array object support is not available. This
- is not an error: on systems with OpenGL 2.x or OpenGL ES 2.0 vertex array objects may
- not be supported. The application is free to continue execution in this case, but it
- then has to be prepared to operate in a VAO-less manner too. This means that instead
- of merely calling bind(), the value of isCreated() must be checked and the vertex
- arrays has to be initialized in the traditional way when there is no vertex array
- object present.
-
- \sa isCreated()
-*/
-bool QOpenGLVertexArrayObject::create()
-{
- Q_D(QOpenGLVertexArrayObject);
- return d->create();
-}
-
-/*!
- Destroys the underlying OpenGL vertex array object. There must be a valid OpenGL context
- that supports vertex array objects current for this function to succeed.
-*/
-void QOpenGLVertexArrayObject::destroy()
-{
- Q_D(QOpenGLVertexArrayObject);
- d->destroy();
-}
-
-/*!
- Returns \c true is the underlying OpenGL vertex array object has been created. If this
- returns \c true and the associated OpenGL context is current, then you are able to bind()
- this object.
-*/
-bool QOpenGLVertexArrayObject::isCreated() const
-{
- Q_D(const QOpenGLVertexArrayObject);
- return (d->vao != 0);
-}
-
-/*!
- Returns the id of the underlying OpenGL vertex array object.
-*/
-GLuint QOpenGLVertexArrayObject::objectId() const
-{
- Q_D(const QOpenGLVertexArrayObject);
- return d->vao;
-}
-
-/*!
- Binds this vertex array object to the OpenGL binding point. From this point on
- and until release() is called or another vertex array object is bound, any
- modifications made to vertex data state are stored inside this vertex array object.
-
- If another vertex array object is then bound you can later restore the set of
- state associated with this object by calling bind() on this object once again.
- This allows efficient changes between vertex data states in rendering functions.
-*/
-void QOpenGLVertexArrayObject::bind()
-{
- Q_D(QOpenGLVertexArrayObject);
- d->bind();
-}
-
-/*!
- Unbinds this vertex array object by binding the default vertex array object (id = 0).
-*/
-void QOpenGLVertexArrayObject::release()
-{
- Q_D(QOpenGLVertexArrayObject);
- d->release();
-}
-
-
-/*!
- \class QOpenGLVertexArrayObject::Binder
- \brief The QOpenGLVertexArrayObject::Binder class is a convenience class to help
- with the binding and releasing of OpenGL Vertex Array Objects.
- \inmodule QtGui
- \reentrant
- \since 5.1
- \ingroup painting-3D
-
- QOpenGLVertexArrayObject::Binder is a simple convenience class that can be used
- to assist with the binding and releasing of QOpenGLVertexArrayObject instances.
- This class is to QOpenGLVertexArrayObject as QMutexLocker is to QMutex.
-
- This class implements the RAII principle which helps to ensure behavior in
- complex code or in the presence of exceptions.
-
- The constructor of this class accepts a QOpenGLVertexArrayObject (VAO) as an
- argument and attempts to bind the VAO, calling QOpenGLVertexArrayObject::create()
- if necessary. The destructor of this class calls QOpenGLVertexArrayObject::release()
- which unbinds the VAO.
-
- If needed the VAO can be temporarily unbound with the release() function and bound
- once more with rebind().
-
- \sa QOpenGLVertexArrayObject
-*/
-
-/*!
- \fn QOpenGLVertexArrayObject::Binder::Binder(QOpenGLVertexArrayObject *v)
-
- Creates a QOpenGLVertexArrayObject::Binder object and binds \a v by calling
- QOpenGLVertexArrayObject::bind(). If necessary it first calls
- QOpenGLVertexArrayObject::create().
-*/
-
-/*!
- \fn QOpenGLVertexArrayObject::Binder::~Binder()
-
- Destroys the QOpenGLVertexArrayObject::Binder and releases the associated vertex array object.
-*/
-
-/*!
- \fn QOpenGLVertexArrayObject::Binder::release()
-
- Can be used to temporarily release the associated vertex array object.
-
- \sa rebind()
-*/
-
-/*!
- \fn QOpenGLVertexArrayObject::Binder::rebind()
-
- Can be used to rebind the associated vertex array object.
-
- \sa release()
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qopenglvertexarrayobject.cpp"