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>
12#include <QtOpenGL/QOpenGLVersionFunctionsFactory>
14#if !QT_CONFIG(opengles2)
15# include <QtOpenGL/qopenglfunctions_3_0.h>
16# include <QtOpenGL/qopenglfunctions_3_2_core.h>
19#include <private/qopenglcontext_p.h>
20#include <private/qopenglextensions_p.h>
21#include <private/qopenglvertexarrayobject_p.h>
25class QOpenGLFunctions_3_0;
26class QOpenGLFunctions_3_2_Core;
33QOpenGLVertexArrayObjectHelper *QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(QOpenGLContext *context)
37 auto contextPrivate = QOpenGLContextPrivate::get(context);
38 auto &vaoHelper = contextPrivate->vaoHelper;
41 vaoHelper =
new QOpenGLVertexArrayObjectHelper(context);
42 contextPrivate->vaoHelperDestroyCallback = &vertexArrayObjectHelperDestroyCallback;
48void QOpenGLVertexArrayObjectHelper::initializeFromContext(QOpenGLContext *context)
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;
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"));
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"));
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"));
103 Q_DECLARE_PUBLIC(QOpenGLVertexArrayObject)
128 qWarning(
"QOpenGLVertexArrayObject::create() VAO is already created");
132 Q_Q(QOpenGLVertexArrayObject);
134 QOpenGLContext *ctx = QOpenGLContext::currentContext();
136 qWarning(
"QOpenGLVertexArrayObject::create() requires a valid current OpenGL context");
145 QObject::connect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
147 guiThread = qGuiApp->thread();
149 if (ctx->isOpenGLES()) {
150 if (ctx->format().majorVersion() >= 3 || ctx->hasExtension(QByteArrayLiteral(
"GL_OES_vertex_array_object"))) {
151 vaoFuncs.helper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(ctx);
153 vaoFuncs.helper->glGenVertexArrays(1, &vao);
156 vaoFuncs.core_3_0 =
nullptr;
158 QSurfaceFormat format = ctx->format();
159#if !QT_CONFIG(opengles2)
160 if (format.version() >= std::pair(3,2)) {
161 vaoFuncs.core_3_2 = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_2_Core>(ctx);
162 vaoFuncsType = Core_3_2;
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);
166 vaoFuncsType = Core_3_0;
167 vaoFuncs.core_3_0->glGenVertexArrays(1, &vao);
170 if (ctx->hasExtension(QByteArrayLiteral(
"GL_ARB_vertex_array_object"))) {
171 vaoFuncs.helper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(ctx);
173 vaoFuncs.helper->glGenVertexArrays(1, &vao);
174 }
else if (ctx->hasExtension(QByteArrayLiteral(
"GL_APPLE_vertex_array_object"))) {
175 vaoFuncs.helper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(ctx);
176 vaoFuncsType =
APPLE;
177 vaoFuncs.helper->glGenVertexArrays(1, &vao);
186 Q_Q(QOpenGLVertexArrayObject);
188 QOpenGLContext *ctx = QOpenGLContext::currentContext();
189 QOpenGLContext *oldContext =
nullptr;
190 QSurface *oldContextSurface =
nullptr;
191 QScopedPointer<QOffscreenSurface> offscreenSurface;
192 if (context && context != ctx) {
194 oldContextSurface = ctx ? ctx->surface() :
nullptr;
198 if (QThread::currentThread() != guiThread) {
205 offscreenSurface.reset(
new QOffscreenSurface);
206 offscreenSurface->setFormat(context->format());
207 offscreenSurface->create();
208 if (context->makeCurrent(offscreenSurface.data())) {
211 qWarning(
"QOpenGLVertexArrayObject::destroy() failed to make VAO's context current");
218 QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
223 switch (vaoFuncsType) {
224#if !QT_CONFIG(opengles2)
226 vaoFuncs.core_3_2->glDeleteVertexArrays(1, &vao);
229 vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao);
235 vaoFuncs.helper->glDeleteVertexArrays(1, &vao);
244 if (oldContext && oldContextSurface && oldContextSurface->surfaceHandle()) {
245 if (!oldContext->makeCurrent(oldContextSurface))
246 qWarning(
"QOpenGLVertexArrayObject::destroy() failed to restore current context");
251
252
253void QOpenGLVertexArrayObjectPrivate::_q_contextAboutToBeDestroyed()
258void QOpenGLVertexArrayObjectPrivate::bind()
260 switch (vaoFuncsType) {
261#if !QT_CONFIG(opengles2)
263 vaoFuncs.core_3_2->glBindVertexArray(vao);
266 vaoFuncs.core_3_0->glBindVertexArray(vao);
272 vaoFuncs.helper->glBindVertexArray(vao);
279void QOpenGLVertexArrayObjectPrivate::release()
281 switch (vaoFuncsType) {
282#if !QT_CONFIG(opengles2)
284 vaoFuncs.core_3_2->glBindVertexArray(0);
287 vaoFuncs.core_3_0->glBindVertexArray(0);
293 vaoFuncs.helper->glBindVertexArray(0);
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
357
358
359
360QOpenGLVertexArrayObject::QOpenGLVertexArrayObject(QObject* parent)
361 : QObject(*
new QOpenGLVertexArrayObjectPrivate, parent)
366
367
368QOpenGLVertexArrayObject::QOpenGLVertexArrayObject(QOpenGLVertexArrayObjectPrivate &dd)
374
375
376QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject()
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397bool QOpenGLVertexArrayObject::create()
399 Q_D(QOpenGLVertexArrayObject);
404
405
406
407void QOpenGLVertexArrayObject::destroy()
409 Q_D(QOpenGLVertexArrayObject);
414
415
416
417
418bool QOpenGLVertexArrayObject::isCreated()
const
420 Q_D(
const QOpenGLVertexArrayObject);
421 return (d->vao != 0);
425
426
427GLuint QOpenGLVertexArrayObject::objectId()
const
429 Q_D(
const QOpenGLVertexArrayObject);
434
435
436
437
438
439
440
441
442void QOpenGLVertexArrayObject::bind()
444 Q_D(QOpenGLVertexArrayObject);
449
450
451void QOpenGLVertexArrayObject::release()
453 Q_D(QOpenGLVertexArrayObject);
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
486
487
488
489
490
491
494
495
496
497
500
501
502
503
504
505
508
509
510
511
512
513
517#include "moc_qopenglvertexarrayobject.cpp"
QOpenGLVertexArrayObjectHelper * helper
QOpenGLFunctions_3_0 * core_3_0
void _q_contextAboutToBeDestroyed()
QOpenGLFunctions_3_2_Core * core_3_2
QOpenGLVertexArrayObjectPrivate()
Combined button and popup list for selecting options.
static void vertexArrayObjectHelperDestroyCallback(QOpenGLVertexArrayObjectHelper *vaoHelper)