Support APPLE VAO extension on Mac.

Since Mac lacks a compatibility profile, we often use the highest
supported compatible version, 2.1; this lacks vertex-array-object (VAO)
support in the API, but Apple provide a compatible extension. Extend
the helper object to detect this case and make VAO support work.

Change-Id: I75a74e048a0d188cec76bc5a4a9eafa4c9143740
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
This commit is contained in:
James Turner 2013-10-15 18:32:02 +01:00 committed by The Qt Project
parent b271ddebfc
commit 42c8c7e9db

View File

@ -58,9 +58,15 @@ public:
{ {
Q_ASSERT(context); Q_ASSERT(context);
#if !defined(QT_OPENGL_ES_2) #if !defined(QT_OPENGL_ES_2)
GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress("glGenVertexArrays")); if (context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress("glDeleteVertexArrays")); GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysAPPLE")));
BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress("glBindVertexArray")); DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysAPPLE")));
BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayAPPLE")));
} else {
GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress("glGenVertexArrays"));
DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress("glDeleteVertexArrays"));
BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress("glBindVertexArray"));
}
#else #else
GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress("glGenVertexArraysOES")); GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress("glGenVertexArraysOES"));
DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress("glDeleteVertexArraysOES")); DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress("glDeleteVertexArraysOES"));
@ -84,7 +90,7 @@ public:
} }
private: private:
// Function signatures are equivalent between desktop core, ARB and ES 2 extensions // Function signatures are equivalent between desktop core, ARB, APPLE and ES 2 extensions
void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays);
void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays);
void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array);
@ -109,8 +115,8 @@ public:
#if defined(QT_OPENGL_ES_2) #if defined(QT_OPENGL_ES_2)
delete vaoFuncs; delete vaoFuncs;
#else #else
if (vaoFuncsType == ARB) if ((vaoFuncsType == ARB) || (vaoFuncsType == APPLE))
delete vaoFuncs.arb; delete vaoFuncs.helper;
#endif #endif
} }
@ -130,13 +136,14 @@ public:
union { union {
QOpenGLFunctions_3_0 *core_3_0; QOpenGLFunctions_3_0 *core_3_0;
QOpenGLFunctions_3_2_Core *core_3_2; QOpenGLFunctions_3_2_Core *core_3_2;
QVertexArrayObjectHelper *arb; QVertexArrayObjectHelper *helper;
} vaoFuncs; } vaoFuncs;
enum { enum {
NotSupported, NotSupported,
Core_3_0, Core_3_0,
Core_3_2, Core_3_2,
ARB ARB,
APPLE
} vaoFuncsType; } vaoFuncsType;
#endif #endif
QOpenGLContext *context; QOpenGLContext *context;
@ -181,9 +188,13 @@ bool QOpenGLVertexArrayObjectPrivate::create()
vaoFuncs.core_3_0->initializeOpenGLFunctions(); vaoFuncs.core_3_0->initializeOpenGLFunctions();
vaoFuncs.core_3_0->glGenVertexArrays(1, &vao); vaoFuncs.core_3_0->glGenVertexArrays(1, &vao);
} else if (ctx->hasExtension("GL_ARB_vertex_array_object")) { } else if (ctx->hasExtension("GL_ARB_vertex_array_object")) {
vaoFuncs.arb = new QVertexArrayObjectHelper(ctx); vaoFuncs.helper = new QVertexArrayObjectHelper(ctx);
vaoFuncsType = ARB; vaoFuncsType = ARB;
vaoFuncs.arb->glGenVertexArrays(1, &vao); vaoFuncs.helper->glGenVertexArrays(1, &vao);
} else if (ctx->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
vaoFuncs.helper = new QVertexArrayObjectHelper(ctx);
vaoFuncsType = APPLE;
vaoFuncs.helper->glGenVertexArrays(1, &vao);
} }
#endif #endif
return (vao != 0); return (vao != 0);
@ -205,7 +216,8 @@ void QOpenGLVertexArrayObjectPrivate::destroy()
vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao); vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao);
break; break;
case ARB: case ARB:
vaoFuncs.arb->glDeleteVertexArrays(1, &vao); case APPLE:
vaoFuncs.helper->glDeleteVertexArrays(1, &vao);
break; break;
case NotSupported: case NotSupported:
break; break;
@ -236,7 +248,8 @@ void QOpenGLVertexArrayObjectPrivate::bind()
vaoFuncs.core_3_0->glBindVertexArray(vao); vaoFuncs.core_3_0->glBindVertexArray(vao);
break; break;
case ARB: case ARB:
vaoFuncs.arb->glBindVertexArray(vao); case APPLE:
vaoFuncs.helper->glBindVertexArray(vao);
break; break;
case NotSupported: case NotSupported:
break; break;
@ -258,7 +271,8 @@ void QOpenGLVertexArrayObjectPrivate::release()
vaoFuncs.core_3_0->glBindVertexArray(0); vaoFuncs.core_3_0->glBindVertexArray(0);
break; break;
case ARB: case ARB:
vaoFuncs.arb->glBindVertexArray(0); case APPLE:
vaoFuncs.helper->glBindVertexArray(0);
break; break;
case NotSupported: case NotSupported:
break; break;