Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qopenglvertexarrayobject.cpp
Go to the documentation of this file.
1// Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sean Harmer <sean.harmer@kdab.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/private/qobject_p.h>
7#include <QtCore/qthread.h>
8#include <QtGui/qopenglcontext.h>
9#include <QtGui/qoffscreensurface.h>
10#include <QtGui/qguiapplication.h>
11
12#include <QtOpenGL/QOpenGLVersionFunctionsFactory>
13
14#if !QT_CONFIG(opengles2)
15# include <QtOpenGL/qopenglfunctions_3_0.h>
16# include <QtOpenGL/qopenglfunctions_3_2_core.h>
17#endif
18
19#include <private/qopenglcontext_p.h>
20#include <private/qopenglextensions_p.h>
21#include <private/qopenglvertexarrayobject_p.h>
22
24
27
29{
30 delete vaoHelper;
31}
32
34{
36
37 auto contextPrivate = QOpenGLContextPrivate::get(context);
38 auto &vaoHelper = contextPrivate->vaoHelper;
39
40 if (!vaoHelper) {
42 contextPrivate->vaoHelperDestroyCallback = &vertexArrayObjectHelperDestroyCallback;
43 }
44
45 return vaoHelper;
46}
47
48void QOpenGLVertexArrayObjectHelper::initializeFromContext(QOpenGLContext *context)
49{
51
52 bool tryARB = true;
53
54 if (context->isOpenGLES()) {
55 if (context->format().majorVersion() >= 3) {
56 QOpenGLExtraFunctionsPrivate *extra = static_cast<QOpenGLExtensions *>(context->extraFunctions())->d();
57 GenVertexArrays = extra->f.GenVertexArrays;
58 DeleteVertexArrays = extra->f.DeleteVertexArrays;
59 BindVertexArray = extra->f.BindVertexArray;
60 IsVertexArray = extra->f.IsVertexArray;
61 tryARB = false;
62 } else if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
63 GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArraysOES"));
64 DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArraysOES"));
65 BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArrayOES"));
66 IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArrayOES"));
67 tryARB = false;
68 }
69 } else if (context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object")) &&
70 !context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
71 GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArraysAPPLE"));
72 DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArraysAPPLE"));
73 BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArrayAPPLE"));
74 IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArrayAPPLE"));
75 tryARB = false;
76 }
77
78 if (tryARB && context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
79 GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArrays"));
80 DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArrays"));
81 BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArray"));
82 IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArray"));
83 }
84}
85
124
126{
127 if (vao) {
128 qWarning("QOpenGLVertexArrayObject::create() VAO is already created");
129 return false;
130 }
131
133
135 if (!ctx) {
136 qWarning("QOpenGLVertexArrayObject::create() requires a valid current OpenGL context");
137 return false;
138 }
139
140 //Fail early, if context is the same as ctx, it means we have tried to initialize for this context and failed
141 if (ctx == context)
142 return false;
143
144 context = ctx;
146
147 guiThread = qGuiApp->thread();
148
149 if (ctx->isOpenGLES()) {
150 if (ctx->format().majorVersion() >= 3 || ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
153 vaoFuncs.helper->glGenVertexArrays(1, &vao);
154 }
155 } else {
156 vaoFuncs.core_3_0 = nullptr;
158 QSurfaceFormat format = ctx->format();
159#if !QT_CONFIG(opengles2)
160 if (format.version() >= qMakePair(3,2)) {
161 vaoFuncs.core_3_2 = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_2_Core>(ctx);
163 vaoFuncs.core_3_2->glGenVertexArrays(1, &vao);
164 } else if (format.majorVersion() >= 3) {
165 vaoFuncs.core_3_0 = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_0>(ctx);
167 vaoFuncs.core_3_0->glGenVertexArrays(1, &vao);
168 } else
169#endif
170 if (ctx->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
173 vaoFuncs.helper->glGenVertexArrays(1, &vao);
174 } else if (ctx->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
177 vaoFuncs.helper->glGenVertexArrays(1, &vao);
178 }
179 }
180
181 return (vao != 0);
182}
183
185{
187
189 QOpenGLContext *oldContext = nullptr;
190 QSurface *oldContextSurface = nullptr;
191 QScopedPointer<QOffscreenSurface> offscreenSurface;
192 if (context && context != ctx) {
193 oldContext = ctx;
194 oldContextSurface = ctx ? ctx->surface() : nullptr;
195 // Before going through the effort of creating an offscreen surface
196 // check that we are on the GUI thread because otherwise many platforms
197 // will not able to create that offscreen surface.
199 ctx = nullptr;
200 } else {
201 // Cannot just make the current surface current again with another context.
202 // The format may be incompatible and some platforms (iOS) may impose
203 // restrictions on using a window with different contexts. Create an
204 // offscreen surface (a pbuffer or a hidden window) instead to be safe.
205 offscreenSurface.reset(new QOffscreenSurface);
206 offscreenSurface->setFormat(context->format());
207 offscreenSurface->create();
208 if (context->makeCurrent(offscreenSurface.data())) {
209 ctx = context;
210 } else {
211 qWarning("QOpenGLVertexArrayObject::destroy() failed to make VAO's context current");
212 ctx = nullptr;
213 }
214 }
215 }
216
217 if (context) {
219 context = nullptr;
220 }
221
222 if (vao && ctx) {
223 switch (vaoFuncsType) {
224#if !QT_CONFIG(opengles2)
225 case Core_3_2:
226 vaoFuncs.core_3_2->glDeleteVertexArrays(1, &vao);
227 break;
228 case Core_3_0:
229 vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao);
230 break;
231#endif
232 case ARB:
233 case APPLE:
234 case OES:
235 vaoFuncs.helper->glDeleteVertexArrays(1, &vao);
236 break;
237 default:
238 break;
239 }
240
241 vao = 0;
242 }
243
244 if (oldContext && oldContextSurface && oldContextSurface->surfaceHandle()) {
245 if (!oldContext->makeCurrent(oldContextSurface))
246 qWarning("QOpenGLVertexArrayObject::destroy() failed to restore current context");
247 }
248}
249
257
259{
260 switch (vaoFuncsType) {
261#if !QT_CONFIG(opengles2)
262 case Core_3_2:
263 vaoFuncs.core_3_2->glBindVertexArray(vao);
264 break;
265 case Core_3_0:
266 vaoFuncs.core_3_0->glBindVertexArray(vao);
267 break;
268#endif
269 case ARB:
270 case APPLE:
271 case OES:
272 vaoFuncs.helper->glBindVertexArray(vao);
273 break;
274 default:
275 break;
276 }
277}
278
280{
281 switch (vaoFuncsType) {
282#if !QT_CONFIG(opengles2)
283 case Core_3_2:
284 vaoFuncs.core_3_2->glBindVertexArray(0);
285 break;
286 case Core_3_0:
287 vaoFuncs.core_3_0->glBindVertexArray(0);
288 break;
289#endif
290 case ARB:
291 case APPLE:
292 case OES:
293 vaoFuncs.helper->glBindVertexArray(0);
294 break;
295 default:
296 break;
297 }
298}
299
300
364
369 : QObject(dd)
370{
371}
372
380
398{
400 return d->create();
401}
402
408{
410 d->destroy();
411}
412
419{
420 Q_D(const QOpenGLVertexArrayObject);
421 return (d->vao != 0);
422}
423
428{
429 Q_D(const QOpenGLVertexArrayObject);
430 return d->vao;
431}
432
443{
445 d->bind();
446}
447
452{
454 d->release();
455}
456
457
516
517#include "moc_qopenglvertexarrayobject.cpp"
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
\inmodule QtGui
static QOpenGLContextPrivate * get(QOpenGLContext *context)
\inmodule QtGui
bool makeCurrent(QSurface *surface)
Makes the context current in the current thread, against the given surface.
QSurfaceFormat format() const
Returns the format of the underlying platform context, if create() has been called.
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
static Q_OPENGL_EXPORT QOpenGLVertexArrayObjectHelper * vertexArrayObjectHelperForContext(QOpenGLContext *context)
QOpenGLVertexArrayObjectHelper * helper
union QOpenGLVertexArrayObjectPrivate::@414 vaoFuncs
enum QOpenGLVertexArrayObjectPrivate::@415 vaoFuncsType
The QOpenGLVertexArrayObject class wraps an OpenGL Vertex Array Object.
void destroy()
Destroys the underlying OpenGL vertex array object.
QOpenGLVertexArrayObject(QObject *parent=nullptr)
Creates a QOpenGLVertexArrayObject with the given parent.
void release()
Unbinds this vertex array object by binding the default vertex array object (id = 0).
~QOpenGLVertexArrayObject()
Destroys the QOpenGLVertexArrayObject and the underlying OpenGL resource.
bool create()
Creates the underlying OpenGL vertex array object.
bool isCreated() const
Returns true is the underlying OpenGL vertex array object has been created.
void bind()
Binds this vertex array object to the OpenGL binding point.
GLuint objectId() const
Returns the id of the underlying OpenGL vertex array object.
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
\inmodule QtGui
Definition qsurface.h:21
static QThread * currentThread()
Definition qthread.cpp:1039
EGLContext ctx
Combined button and popup list for selecting options.
static void * context
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
#define qGuiApp
#define qWarning
Definition qlogging.h:166
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLint GLsizei GLsizei GLenum format
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
static void vertexArrayObjectHelperDestroyCallback(QOpenGLVertexArrayObjectHelper *vaoHelper)
QT_BEGIN_NAMESPACE constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
Definition qpair.h:19
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define GLuint
QObject::connect nullptr