7#include <QtCore/private/qobject_p.h>
8#include <QtCore/qthread.h>
9#include <QtGui/qopenglcontext.h>
10#include <QtGui/qoffscreensurface.h>
11#include <QtGui/qguiapplication.h>
13#include <QtOpenGL/QOpenGLVersionFunctionsFactory>
15#if !QT_CONFIG(opengles2)
16# include <QtOpenGL/qopenglfunctions_3_0.h>
17# include <QtOpenGL/qopenglfunctions_3_2_core.h>
20#include <private/qopenglcontext_p.h>
21#include <private/qopenglextensions_p.h>
22#include <private/qopenglvertexarrayobject_p.h>
26class QOpenGLFunctions_3_0;
27class QOpenGLFunctions_3_2_Core;
34QOpenGLVertexArrayObjectHelper *QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(QOpenGLContext *context)
38 auto contextPrivate = QOpenGLContextPrivate::get(context);
39 auto &vaoHelper = contextPrivate->vaoHelper;
42 vaoHelper =
new QOpenGLVertexArrayObjectHelper(context);
43 contextPrivate->vaoHelperDestroyCallback = &vertexArrayObjectHelperDestroyCallback;
49void QOpenGLVertexArrayObjectHelper::initializeFromContext(QOpenGLContext *context)
55 if (context->isOpenGLES()) {
56 if (context->format().majorVersion() >= 3) {
57 QOpenGLExtraFunctionsPrivate *extra =
static_cast<QOpenGLExtensions *>(context->extraFunctions())->d();
58 GenVertexArrays = extra->f.GenVertexArrays;
59 DeleteVertexArrays = extra->f.DeleteVertexArrays;
60 BindVertexArray = extra->f.BindVertexArray;
61 IsVertexArray = extra->f.IsVertexArray;
63 }
else if (context->hasExtension(QByteArrayLiteral(
"GL_OES_vertex_array_object"))) {
64 GenVertexArrays =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress(
"glGenVertexArraysOES"));
65 DeleteVertexArrays =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress(
"glDeleteVertexArraysOES"));
66 BindVertexArray =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(
"glBindVertexArrayOES"));
67 IsVertexArray =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress(
"glIsVertexArrayOES"));
70 }
else if (context->hasExtension(QByteArrayLiteral(
"GL_APPLE_vertex_array_object")) &&
71 !context->hasExtension(QByteArrayLiteral(
"GL_ARB_vertex_array_object"))) {
72 GenVertexArrays =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress(
"glGenVertexArraysAPPLE"));
73 DeleteVertexArrays =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress(
"glDeleteVertexArraysAPPLE"));
74 BindVertexArray =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(
"glBindVertexArrayAPPLE"));
75 IsVertexArray =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress(
"glIsVertexArrayAPPLE"));
79 if (tryARB && context->hasExtension(QByteArrayLiteral(
"GL_ARB_vertex_array_object"))) {
80 GenVertexArrays =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress(
"glGenVertexArrays"));
81 DeleteVertexArrays =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress(
"glDeleteVertexArrays"));
82 BindVertexArray =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(
"glBindVertexArray"));
83 IsVertexArray =
reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress(
"glIsVertexArray"));
104 Q_DECLARE_PUBLIC(QOpenGLVertexArrayObject)
129 qWarning(
"QOpenGLVertexArrayObject::create() VAO is already created");
133 Q_Q(QOpenGLVertexArrayObject);
135 QOpenGLContext *ctx = QOpenGLContext::currentContext();
137 qWarning(
"QOpenGLVertexArrayObject::create() requires a valid current OpenGL context");
146 QObject::connect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
148 guiThread = qGuiApp->thread();
150 if (ctx->isOpenGLES()) {
151 if (ctx->format().majorVersion() >= 3 || ctx->hasExtension(QByteArrayLiteral(
"GL_OES_vertex_array_object"))) {
152 vaoFuncs.helper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(ctx);
154 vaoFuncs.helper->glGenVertexArrays(1, &vao);
157 vaoFuncs.core_3_0 =
nullptr;
159 QSurfaceFormat format = ctx->format();
160#if !QT_CONFIG(opengles2)
161 if (format.version() >= std::pair(3,2)) {
162 vaoFuncs.core_3_2 = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_2_Core>(ctx);
163 vaoFuncsType = Core_3_2;
164 vaoFuncs.core_3_2->glGenVertexArrays(1, &vao);
165 }
else if (format.majorVersion() >= 3) {
166 vaoFuncs.core_3_0 = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_0>(ctx);
167 vaoFuncsType = Core_3_0;
168 vaoFuncs.core_3_0->glGenVertexArrays(1, &vao);
171 if (ctx->hasExtension(QByteArrayLiteral(
"GL_ARB_vertex_array_object"))) {
172 vaoFuncs.helper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(ctx);
174 vaoFuncs.helper->glGenVertexArrays(1, &vao);
175 }
else if (ctx->hasExtension(QByteArrayLiteral(
"GL_APPLE_vertex_array_object"))) {
176 vaoFuncs.helper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(ctx);
177 vaoFuncsType =
APPLE;
178 vaoFuncs.helper->glGenVertexArrays(1, &vao);
187 Q_Q(QOpenGLVertexArrayObject);
189 QOpenGLContext *ctx = QOpenGLContext::currentContext();
190 QOpenGLContext *oldContext =
nullptr;
191 QSurface *oldContextSurface =
nullptr;
192 QScopedPointer<QOffscreenSurface> offscreenSurface;
193 if (context && context != ctx) {
195 oldContextSurface = ctx ? ctx->surface() :
nullptr;
199 if (QThread::currentThread() != guiThread) {
206 offscreenSurface.reset(
new QOffscreenSurface);
207 offscreenSurface->setFormat(context->format());
208 offscreenSurface->create();
209 if (context->makeCurrent(offscreenSurface.data())) {
212 qWarning(
"QOpenGLVertexArrayObject::destroy() failed to make VAO's context current");
219 QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
224 switch (vaoFuncsType) {
225#if !QT_CONFIG(opengles2)
227 vaoFuncs.core_3_2->glDeleteVertexArrays(1, &vao);
230 vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao);
236 vaoFuncs.helper->glDeleteVertexArrays(1, &vao);
245 if (oldContext && oldContextSurface && oldContextSurface->surfaceHandle()) {
246 if (!oldContext->makeCurrent(oldContextSurface))
247 qWarning(
"QOpenGLVertexArrayObject::destroy() failed to restore current context");
252
253
261 switch (vaoFuncsType) {
262#if !QT_CONFIG(opengles2)
264 vaoFuncs.core_3_2->glBindVertexArray(vao);
267 vaoFuncs.core_3_0->glBindVertexArray(vao);
273 vaoFuncs.helper->glBindVertexArray(vao);
282 switch (vaoFuncsType) {
283#if !QT_CONFIG(opengles2)
285 vaoFuncs.core_3_2->glBindVertexArray(0);
288 vaoFuncs.core_3_0->glBindVertexArray(0);
294 vaoFuncs.helper->glBindVertexArray(0);
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
355
358
359
360
361QOpenGLVertexArrayObject::QOpenGLVertexArrayObject(QObject* parent)
362 : QObject(*
new QOpenGLVertexArrayObjectPrivate, parent)
367
368
369QOpenGLVertexArrayObject::QOpenGLVertexArrayObject(QOpenGLVertexArrayObjectPrivate &dd)
375
376
377QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject()
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398bool QOpenGLVertexArrayObject::create()
400 Q_D(QOpenGLVertexArrayObject);
405
406
407
408void QOpenGLVertexArrayObject::destroy()
410 Q_D(QOpenGLVertexArrayObject);
415
416
417
418
419bool QOpenGLVertexArrayObject::isCreated()
const
421 Q_D(
const QOpenGLVertexArrayObject);
422 return (d->vao != 0);
426
427
428GLuint QOpenGLVertexArrayObject::objectId()
const
430 Q_D(
const QOpenGLVertexArrayObject);
435
436
437
438
439
440
441
442
443void QOpenGLVertexArrayObject::bind()
445 Q_D(QOpenGLVertexArrayObject);
450
451
452void QOpenGLVertexArrayObject::release()
454 Q_D(QOpenGLVertexArrayObject);
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
487
488
489
490
491
492
495
496
497
498
501
502
503
504
505
506
509
510
511
512
513
514
518#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)