diff options
Diffstat (limited to 'src/gui/opengl')
29 files changed, 7219 insertions, 512 deletions
diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri index 8659bd6dea..b13f258fda 100644 --- a/src/gui/opengl/opengl.pri +++ b/src/gui/opengl/opengl.pri @@ -36,7 +36,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) { opengl/qopengltexture.h \ opengl/qopengltexture_p.h \ opengl/qopengltexturehelper_p.h \ - opengl/qopenglpixeltransferoptions.h + opengl/qopenglpixeltransferoptions.h \ + opengl/qopenglextrafunctions.h SOURCES += opengl/qopengl.cpp \ opengl/qopenglfunctions.cpp \ diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index 1c008ccb42..68cd8a82b4 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -135,20 +135,42 @@ static const char operators[][3] = {"!=", "<", "<=", "=", ">", ">="}; static inline QString valueKey() { return QStringLiteral("value"); } static inline QString opKey() { return QStringLiteral("op"); } static inline QString versionKey() { return QStringLiteral("version"); } +static inline QString releaseKey() { return QStringLiteral("release"); } static inline QString typeKey() { return QStringLiteral("type"); } static inline QString osKey() { return QStringLiteral("os"); } static inline QString vendorIdKey() { return QStringLiteral("vendor_id"); } static inline QString glVendorKey() { return QStringLiteral("gl_vendor"); } static inline QString deviceIdKey() { return QStringLiteral("device_id"); } static inline QString driverVersionKey() { return QStringLiteral("driver_version"); } +static inline QString driverDescriptionKey() { return QStringLiteral("driver_description"); } static inline QString featuresKey() { return QStringLiteral("features"); } static inline QString idKey() { return QStringLiteral("id"); } static inline QString descriptionKey() { return QStringLiteral("description"); } static inline QString exceptionsKey() { return QStringLiteral("exceptions"); } +typedef QJsonArray::ConstIterator JsonArrayConstIt; + +static inline bool contains(const QJsonArray &haystack, unsigned needle) +{ + for (JsonArrayConstIt it = haystack.constBegin(), cend = haystack.constEnd(); it != cend; ++it) { + if (needle == it->toString().toUInt(Q_NULLPTR, /* base */ 0)) + return true; + } + return false; +} + +static inline bool contains(const QJsonArray &haystack, const QString &needle) +{ + for (JsonArrayConstIt it = haystack.constBegin(), cend = haystack.constEnd(); it != cend; ++it) { + if (needle == it->toString()) + return true; + } + return false; +} + namespace { // VersionTerm describing a version term consisting of number and operator -// found in "os", "driver_version", "gl_version". +// found in os.version and driver_version. struct VersionTerm { VersionTerm() : op(NotEqual) {} static VersionTerm fromJson(const QJsonValue &v); @@ -206,9 +228,38 @@ struct OsTypeTerm static OsTypeTerm fromJson(const QJsonValue &v); static QString hostOs(); static QVersionNumber hostKernelVersion() { return QVersionNumber::fromString(QSysInfo::kernelVersion()); } + static QString hostOsRelease() { + QString ver; +#ifdef Q_OS_WIN + switch (QSysInfo::windowsVersion()) { + case QSysInfo::WV_XP: + case QSysInfo::WV_2003: + ver = QStringLiteral("xp"); + break; + case QSysInfo::WV_VISTA: + ver = QStringLiteral("vista"); + break; + case QSysInfo::WV_WINDOWS7: + ver = QStringLiteral("7"); + break; + case QSysInfo::WV_WINDOWS8: + ver = QStringLiteral("8"); + break; + case QSysInfo::WV_WINDOWS8_1: + ver = QStringLiteral("8.1"); + break; + case QSysInfo::WV_WINDOWS10: + ver = QStringLiteral("10"); + break; + default: + break; + } +#endif + return ver; + } bool isNull() const { return type.isEmpty(); } - bool matches(const QString &osName, const QVersionNumber &kernelVersion) const + bool matches(const QString &osName, const QVersionNumber &kernelVersion, const QString &osRelease) const { if (isNull() || osName.isEmpty() || kernelVersion.isNull()) { qWarning() << Q_FUNC_INFO << "called with invalid parameters"; @@ -216,11 +267,17 @@ struct OsTypeTerm } if (type != osName) return false; - return versionTerm.isNull() || versionTerm.matches(kernelVersion); + if (!versionTerm.isNull() && !versionTerm.matches(kernelVersion)) + return false; + // release is a list of Windows versions where the rule should match + if (!release.isEmpty() && !contains(release, osRelease)) + return false; + return true; } QString type; VersionTerm versionTerm; + QJsonArray release; }; OsTypeTerm OsTypeTerm::fromJson(const QJsonValue &v) @@ -231,6 +288,7 @@ OsTypeTerm OsTypeTerm::fromJson(const QJsonValue &v) const QJsonObject o = v.toObject(); result.type = o.value(typeKey()).toString(); result.versionTerm = VersionTerm::fromJson(o.value(versionKey())); + result.release = o.value(releaseKey()).toArray(); return result; } @@ -251,17 +309,6 @@ QString OsTypeTerm::hostOs() } } // anonymous namespace -typedef QJsonArray::ConstIterator JsonArrayConstIt; - -static inline bool contains(const QJsonArray &a, unsigned needle) -{ - for (JsonArrayConstIt it = a.constBegin(), cend = a.constEnd(); it != cend; ++it) { - if (needle == it->toString().toUInt(Q_NULLPTR, /* base */ 0)) - return true; - } - return false; -} - static QString msgSyntaxWarning(const QJsonObject &object, const QString &what) { QString result; @@ -277,17 +324,18 @@ static QString msgSyntaxWarning(const QJsonObject &object, const QString &what) static bool matches(const QJsonObject &object, const QString &osName, const QVersionNumber &kernelVersion, + const QString &osRelease, const QOpenGLConfig::Gpu &gpu) { const OsTypeTerm os = OsTypeTerm::fromJson(object.value(osKey())); - if (!os.isNull() && !os.matches(osName, kernelVersion)) + if (!os.isNull() && !os.matches(osName, kernelVersion, osRelease)) return false; const QJsonValue exceptionsV = object.value(exceptionsKey()); if (exceptionsV.isArray()) { const QJsonArray exceptionsA = exceptionsV.toArray(); for (JsonArrayConstIt it = exceptionsA.constBegin(), cend = exceptionsA.constEnd(); it != cend; ++it) { - if (matches(it->toObject(), osName, kernelVersion, gpu)) + if (matches(it->toObject(), osName, kernelVersion, osRelease, gpu)) return false; } } @@ -336,12 +384,22 @@ static bool matches(const QJsonObject &object, QLatin1String("Driver version must be of type object.")); } } + + if (!gpu.driverDescription.isEmpty()) { + const QJsonValue driverDescriptionV = object.value(driverDescriptionKey()); + if (driverDescriptionV.isString()) { + if (!gpu.driverDescription.contains(driverDescriptionV.toString().toUtf8())) + return false; + } + } + return true; } static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, const QString &osName, const QVersionNumber &kernelVersion, + const QString &osRelease, const QJsonDocument &doc, QSet<QString> *result, QString *errorMessage) @@ -358,7 +416,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, for (JsonArrayConstIt eit = entriesA.constBegin(), ecend = entriesA.constEnd(); eit != ecend; ++eit) { if (eit->isObject()) { const QJsonObject object = eit->toObject(); - if (matches(object, osName, kernelVersion, gpu)) { + if (matches(object, osName, kernelVersion, osRelease, gpu)) { const QJsonValue featuresListV = object.value(featuresKey()); if (featuresListV.isArray()) { const QJsonArray featuresListA = featuresListV.toArray(); @@ -374,6 +432,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, const QString &osName, const QVersionNumber &kernelVersion, + const QString &osRelease, const QByteArray &jsonAsciiData, QSet<QString> *result, QString *errorMessage) { @@ -389,12 +448,13 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, << error.offset << ")."; return false; } - return readGpuFeatures(gpu, osName, kernelVersion, document, result, errorMessage); + return readGpuFeatures(gpu, osName, kernelVersion, osRelease, document, result, errorMessage); } static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, const QString &osName, const QVersionNumber &kernelVersion, + const QString &osRelease, const QString &fileName, QSet<QString> *result, QString *errorMessage) { @@ -407,7 +467,7 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, << file.errorString(); return false; } - const bool success = readGpuFeatures(gpu, osName, kernelVersion, file.readAll(), result, errorMessage); + const bool success = readGpuFeatures(gpu, osName, kernelVersion, osRelease, file.readAll(), result, errorMessage); if (!success) { errorMessage->prepend(QLatin1String("Error reading \"") + QDir::toNativeSeparators(fileName) @@ -417,37 +477,39 @@ static bool readGpuFeatures(const QOpenGLConfig::Gpu &gpu, } QSet<QString> QOpenGLConfig::gpuFeatures(const QOpenGLConfig::Gpu &gpu, - const QString &osName, - const QVersionNumber &kernelVersion, - const QJsonDocument &doc) + const QString &osName, + const QVersionNumber &kernelVersion, + const QString &osRelease, + const QJsonDocument &doc) { QSet<QString> result; QString errorMessage; - if (!readGpuFeatures(gpu, osName, kernelVersion, doc, &result, &errorMessage)) + if (!readGpuFeatures(gpu, osName, kernelVersion, osRelease, doc, &result, &errorMessage)) qWarning().noquote() << errorMessage; return result; } QSet<QString> QOpenGLConfig::gpuFeatures(const QOpenGLConfig::Gpu &gpu, - const QString &osName, - const QVersionNumber &kernelVersion, - const QString &fileName) + const QString &osName, + const QVersionNumber &kernelVersion, + const QString &osRelease, + const QString &fileName) { QSet<QString> result; QString errorMessage; - if (!readGpuFeatures(gpu, osName, kernelVersion, fileName, &result, &errorMessage)) + if (!readGpuFeatures(gpu, osName, kernelVersion, osRelease, fileName, &result, &errorMessage)) qWarning().noquote() << errorMessage; return result; } QSet<QString> QOpenGLConfig::gpuFeatures(const Gpu &gpu, const QJsonDocument &doc) { - return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), doc); + return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), OsTypeTerm::hostOsRelease(), doc); } QSet<QString> QOpenGLConfig::gpuFeatures(const Gpu &gpu, const QString &fileName) { - return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), fileName); + return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), OsTypeTerm::hostOsRelease(), fileName); } QOpenGLConfig::Gpu QOpenGLConfig::Gpu::fromContext() diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index 72abce760d..87dc2a830e 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -83,13 +83,11 @@ typedef void* GLeglImageOES; // include headers on top of each other, meaning that applications can // include gl2.h even if gl31.h gets included here. -// This compile time differentation is important inside Qt because, -// unlike desktop GL, GLES is different when it comes to versioning -// and extensions: Standard functions that are new in a given version -// are always available in a version-specific header and are not -// guaranteed to be dynamically resolvable via eglGetProcAddress (and -// are typically not available as extensions even if they were part of -// an extension for a previous version). +// NB! This file contains the only usages of the ES_3 and ES_3_1 +// macros. They are useless for pretty much anything else. The fact +// that Qt was built against an SDK with f.ex. ES 2 only does not mean +// applications cannot target ES 3. Therefore QOpenGLFunctions and +// friends do everything dynamically and never rely on these macros. # if defined(QT_OPENGL_ES_3_1) # include <GLES3/gl31.h> diff --git a/src/gui/opengl/qopengl_p.h b/src/gui/opengl/qopengl_p.h index 980e02aea6..6b66a3ba57 100644 --- a/src/gui/opengl/qopengl_p.h +++ b/src/gui/opengl/qopengl_p.h @@ -49,7 +49,7 @@ #include <private/qopenglcontext_p.h> #include <QtCore/qset.h> #include <QtCore/qstring.h> -#include <private/qversionnumber_p.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -79,19 +79,21 @@ public: bool isValid() const { return deviceId || !glVendor.isEmpty(); } bool equals(const Gpu &other) const { return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion - && glVendor == other.glVendor; + && driverDescription == other.driverDescription && glVendor == other.glVendor; } uint vendorId; uint deviceId; QVersionNumber driverVersion; + QByteArray driverDescription; QByteArray glVendor; - static Gpu fromDevice(uint vendorId, uint deviceId, QVersionNumber driverVersion) { + static Gpu fromDevice(uint vendorId, uint deviceId, QVersionNumber driverVersion, const QByteArray &driverDescription) { Gpu gpu; gpu.vendorId = vendorId; gpu.deviceId = deviceId; gpu.driverVersion = driverVersion; + gpu.driverDescription = driverDescription; return gpu; } @@ -105,10 +107,10 @@ public: }; static QSet<QString> gpuFeatures(const Gpu &gpu, - const QString &osName, const QVersionNumber &kernelVersion, + const QString &osName, const QVersionNumber &kernelVersion, const QString &osVersion, const QJsonDocument &doc); static QSet<QString> gpuFeatures(const Gpu &gpu, - const QString &osName, const QVersionNumber &kernelVersion, + const QString &osName, const QVersionNumber &kernelVersion, const QString &osVersion, const QString &fileName); static QSet<QString> gpuFeatures(const Gpu &gpu, const QJsonDocument &doc); static QSet<QString> gpuFeatures(const Gpu &gpu, const QString &fileName); diff --git a/src/gui/opengl/qopenglbuffer.h b/src/gui/opengl/qopenglbuffer.h index 847c1efaa0..ca3d85d8e0 100644 --- a/src/gui/opengl/qopenglbuffer.h +++ b/src/gui/opengl/qopenglbuffer.h @@ -118,7 +118,7 @@ public: void write(int offset, const void *data, int count); void allocate(const void *data, int count); - inline void allocate(int count) { allocate(0, count); } + inline void allocate(int count) { allocate(Q_NULLPTR, count); } void *map(QOpenGLBuffer::Access access); void *mapRange(int offset, int count, QOpenGLBuffer::RangeAccessFlags access); diff --git a/src/gui/opengl/qopengldebug.h b/src/gui/opengl/qopengldebug.h index 425ab78d7a..3e93ad4120 100644 --- a/src/gui/opengl/qopengldebug.h +++ b/src/gui/opengl/qopengldebug.h @@ -97,14 +97,14 @@ public: QOpenGLDebugMessage(); QOpenGLDebugMessage(const QOpenGLDebugMessage &debugMessage); - ~QOpenGLDebugMessage(); QOpenGLDebugMessage &operator=(const QOpenGLDebugMessage &debugMessage); #ifdef Q_COMPILER_RVALUE_REFS - inline QOpenGLDebugMessage &operator=(QOpenGLDebugMessage &&debugMessage) - { d.swap(debugMessage.d); return *this; } + QOpenGLDebugMessage &operator=(QOpenGLDebugMessage &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - inline void swap(QOpenGLDebugMessage &debugMessage) { d.swap(debugMessage.d); } + ~QOpenGLDebugMessage(); + + void swap(QOpenGLDebugMessage &other) Q_DECL_NOTHROW { qSwap(d, other.d); } Source source() const; Type type() const; @@ -156,7 +156,7 @@ public: }; Q_ENUM(LoggingMode) - explicit QOpenGLDebugLogger(QObject *parent = 0); + explicit QOpenGLDebugLogger(QObject *parent = Q_NULLPTR); ~QOpenGLDebugLogger(); bool initialize(); diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp index 7e53c01cba..40f4ce94c2 100644 --- a/src/gui/opengl/qopenglengineshadermanager.cpp +++ b/src/gui/opengl/qopenglengineshadermanager.cpp @@ -427,11 +427,10 @@ QOpenGLEngineShaderProg *QOpenGLEngineSharedShaders::findProgramInCache(const QO if (!inCache) shaderCache.store(newProg->program, QOpenGLContext::currentContext()); } else { - QLatin1String none("none"); - QLatin1String br("\n"); QString error; error = QLatin1String("Shader program failed to link,"); #if defined(QT_DEBUG) + QLatin1String br("\n"); error += QLatin1String("\n Shaders Used:\n"); for (int i = 0; i < newProg->program->shaders().count(); ++i) { QOpenGLShader *shader = newProg->program->shaders().at(i); diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h index 7def687f49..aa2a08242d 100644 --- a/src/gui/opengl/qopenglextensions_p.h +++ b/src/gui/opengl/qopenglextensions_p.h @@ -45,7 +45,7 @@ // We mean it. // -#include "qopenglfunctions.h" +#include "qopenglextrafunctions.h" #include <QtCore/qlibrary.h> QT_BEGIN_NAMESPACE @@ -57,32 +57,194 @@ class QOpenGLES3Helper public: QOpenGLES3Helper(); - GLvoid* (QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access); + // GLES3 + void (QOPENGLF_APIENTRYP ReadBuffer)(GLenum mode); + void (QOPENGLF_APIENTRYP DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); + void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + void (QOPENGLF_APIENTRYP CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); + void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + void (QOPENGLF_APIENTRYP GenQueries)(GLsizei n, GLuint *ids); + void (QOPENGLF_APIENTRYP DeleteQueries)(GLsizei n, const GLuint *ids); + GLboolean (QOPENGLF_APIENTRYP IsQuery)(GLuint id); + void (QOPENGLF_APIENTRYP BeginQuery)(GLenum target, GLuint id); + void (QOPENGLF_APIENTRYP EndQuery)(GLenum target); + void (QOPENGLF_APIENTRYP GetQueryiv)(GLenum target, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params); GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); + void (QOPENGLF_APIENTRYP GetBufferPointerv)(GLenum target, GLenum pname, void **params); + void (QOPENGLF_APIENTRYP DrawBuffers)(GLsizei n, const GLenum *bufs); + void (QOPENGLF_APIENTRYP UniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height); - - void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); - void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP FramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + void *(QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + void (QOPENGLF_APIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length); void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); + void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); GLboolean (QOPENGLF_APIENTRYP IsVertexArray)(GLuint array); - - void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); - - void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth); - void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP GetIntegeri_v)(GLenum target, GLuint index, GLint *data); + void (QOPENGLF_APIENTRYP BeginTransformFeedback)(GLenum primitiveMode); + void (QOPENGLF_APIENTRYP EndTransformFeedback)(void); + void (QOPENGLF_APIENTRYP BindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + void (QOPENGLF_APIENTRYP BindBufferBase)(GLenum target, GLuint index, GLuint buffer); + void (QOPENGLF_APIENTRYP TransformFeedbackVaryings)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); + void (QOPENGLF_APIENTRYP GetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); + void (QOPENGLF_APIENTRYP VertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + void (QOPENGLF_APIENTRYP GetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params); + void (QOPENGLF_APIENTRYP VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w); + void (QOPENGLF_APIENTRYP VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void (QOPENGLF_APIENTRYP VertexAttribI4iv)(GLuint index, const GLint *v); + void (QOPENGLF_APIENTRYP VertexAttribI4uiv)(GLuint index, const GLuint *v); + void (QOPENGLF_APIENTRYP GetUniformuiv)(GLuint program, GLint location, GLuint *params); + GLint (QOPENGLF_APIENTRYP GetFragDataLocation)(GLuint program, const GLchar *name); + void (QOPENGLF_APIENTRYP Uniform1ui)(GLint location, GLuint v0); + void (QOPENGLF_APIENTRYP Uniform2ui)(GLint location, GLuint v0, GLuint v1); + void (QOPENGLF_APIENTRYP Uniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2); + void (QOPENGLF_APIENTRYP Uniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void (QOPENGLF_APIENTRYP Uniform1uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform2uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform3uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform4uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value); + void (QOPENGLF_APIENTRYP ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value); + void (QOPENGLF_APIENTRYP ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value); + void (QOPENGLF_APIENTRYP ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + const GLubyte *(QOPENGLF_APIENTRYP GetStringi)(GLenum name, GLuint index); + void (QOPENGLF_APIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + void (QOPENGLF_APIENTRYP GetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); + void (QOPENGLF_APIENTRYP GetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); + GLuint (QOPENGLF_APIENTRYP GetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName); + void (QOPENGLF_APIENTRYP GetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); + void (QOPENGLF_APIENTRYP UniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + void (QOPENGLF_APIENTRYP DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + void (QOPENGLF_APIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); + GLsync (QOPENGLF_APIENTRYP FenceSync)(GLenum condition, GLbitfield flags); + GLboolean (QOPENGLF_APIENTRYP IsSync)(GLsync sync); + void (QOPENGLF_APIENTRYP DeleteSync)(GLsync sync); + GLenum (QOPENGLF_APIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + void (QOPENGLF_APIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + void (QOPENGLF_APIENTRYP GetInteger64v)(GLenum pname, GLint64 *data); + void (QOPENGLF_APIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); + void (QOPENGLF_APIENTRYP GetInteger64i_v)(GLenum target, GLuint index, GLint64 *data); + void (QOPENGLF_APIENTRYP GetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 *params); + void (QOPENGLF_APIENTRYP GenSamplers)(GLsizei count, GLuint *samplers); + void (QOPENGLF_APIENTRYP DeleteSamplers)(GLsizei count, const GLuint *samplers); + GLboolean (QOPENGLF_APIENTRYP IsSampler)(GLuint sampler); + void (QOPENGLF_APIENTRYP BindSampler)(GLuint unit, GLuint sampler); + void (QOPENGLF_APIENTRYP SamplerParameteri)(GLuint sampler, GLenum pname, GLint param); + void (QOPENGLF_APIENTRYP SamplerParameteriv)(GLuint sampler, GLenum pname, const GLint *param); + void (QOPENGLF_APIENTRYP SamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param); + void (QOPENGLF_APIENTRYP SamplerParameterfv)(GLuint sampler, GLenum pname, const GLfloat *param); + void (QOPENGLF_APIENTRYP GetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat *params); + void (QOPENGLF_APIENTRYP VertexAttribDivisor)(GLuint index, GLuint divisor); + void (QOPENGLF_APIENTRYP BindTransformFeedback)(GLenum target, GLuint id); + void (QOPENGLF_APIENTRYP DeleteTransformFeedbacks)(GLsizei n, const GLuint *ids); + void (QOPENGLF_APIENTRYP GenTransformFeedbacks)(GLsizei n, GLuint *ids); + GLboolean (QOPENGLF_APIENTRYP IsTransformFeedback)(GLuint id); + void (QOPENGLF_APIENTRYP PauseTransformFeedback)(void); + void (QOPENGLF_APIENTRYP ResumeTransformFeedback)(void); + void (QOPENGLF_APIENTRYP GetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); + void (QOPENGLF_APIENTRYP ProgramBinary)(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); + void (QOPENGLF_APIENTRYP ProgramParameteri)(GLuint program, GLenum pname, GLint value); + void (QOPENGLF_APIENTRYP InvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments); + void (QOPENGLF_APIENTRYP InvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + void (QOPENGLF_APIENTRYP GetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); + + // GLES 3.1 + void (QOPENGLF_APIENTRYP DispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); + void (QOPENGLF_APIENTRYP DispatchComputeIndirect)(GLintptr indirect); + void (QOPENGLF_APIENTRYP DrawArraysIndirect)(GLenum mode, const void *indirect); + void (QOPENGLF_APIENTRYP DrawElementsIndirect)(GLenum mode, GLenum type, const void *indirect); + void (QOPENGLF_APIENTRYP FramebufferParameteri)(GLenum target, GLenum pname, GLint param); + void (QOPENGLF_APIENTRYP GetFramebufferParameteriv)(GLenum target, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint *params); + GLuint (QOPENGLF_APIENTRYP GetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar *name); + void (QOPENGLF_APIENTRYP GetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); + void (QOPENGLF_APIENTRYP GetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); + GLint (QOPENGLF_APIENTRYP GetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar *name); + void (QOPENGLF_APIENTRYP UseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program); + void (QOPENGLF_APIENTRYP ActiveShaderProgram)(GLuint pipeline, GLuint program); + GLuint (QOPENGLF_APIENTRYP CreateShaderProgramv)(GLenum type, GLsizei count, const GLchar *const*strings); + void (QOPENGLF_APIENTRYP BindProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP DeleteProgramPipelines)(GLsizei n, const GLuint *pipelines); + void (QOPENGLF_APIENTRYP GenProgramPipelines)(GLsizei n, GLuint *pipelines); + GLboolean (QOPENGLF_APIENTRYP IsProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP GetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP ProgramUniform1i)(GLuint program, GLint location, GLint v0); + void (QOPENGLF_APIENTRYP ProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1); + void (QOPENGLF_APIENTRYP ProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); + void (QOPENGLF_APIENTRYP ProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void (QOPENGLF_APIENTRYP ProgramUniform1ui)(GLuint program, GLint location, GLuint v0); + void (QOPENGLF_APIENTRYP ProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1); + void (QOPENGLF_APIENTRYP ProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); + void (QOPENGLF_APIENTRYP ProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void (QOPENGLF_APIENTRYP ProgramUniform1f)(GLuint program, GLint location, GLfloat v0); + void (QOPENGLF_APIENTRYP ProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1); + void (QOPENGLF_APIENTRYP ProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void (QOPENGLF_APIENTRYP ProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + void (QOPENGLF_APIENTRYP ProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ValidateProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP GetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + void (QOPENGLF_APIENTRYP BindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); + void (QOPENGLF_APIENTRYP GetBooleani_v)(GLenum target, GLuint index, GLboolean *data); + void (QOPENGLF_APIENTRYP MemoryBarrierFunc)(GLbitfield barriers); + void (QOPENGLF_APIENTRYP MemoryBarrierByRegion)(GLbitfield barriers); + void (QOPENGLF_APIENTRYP TexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + void (QOPENGLF_APIENTRYP GetMultisamplefv)(GLenum pname, GLuint index, GLfloat *val); + void (QOPENGLF_APIENTRYP SampleMaski)(GLuint maskNumber, GLbitfield mask); + void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params); + void (QOPENGLF_APIENTRYP BindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + void (QOPENGLF_APIENTRYP VertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + void (QOPENGLF_APIENTRYP VertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + void (QOPENGLF_APIENTRYP VertexAttribBinding)(GLuint attribindex, GLuint bindingindex); + void (QOPENGLF_APIENTRYP VertexBindingDivisor)(GLuint bindingindex, GLuint divisor); + + QPair<int, int> supportedVersion() const { return m_supportedVersion; } private: bool init(); QFunctionPointer resolve(const char *name); - +#ifndef QT_NO_LIBRARY QLibrary m_gl; +#endif + QPair<int, int> m_supportedVersion; }; -class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLFunctions +class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLExtraFunctions { Q_DECLARE_PRIVATE(QOpenGLExtensions) public: @@ -113,7 +275,8 @@ public: GeometryShaders = 0x00080000, MapBufferRange = 0x00100000, Sized8Formats = 0x00200000, - DiscardFramebuffer = 0x00400000 + DiscardFramebuffer = 0x00400000, + Sized16Formats = 0x00800000 }; Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension) @@ -121,19 +284,7 @@ public: bool hasOpenGLExtension(QOpenGLExtensions::OpenGLExtension extension) const; GLvoid *glMapBuffer(GLenum target, GLenum access); - GLvoid *glMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access); - GLboolean glUnmapBuffer(GLenum target); - - void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - - void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, - GLenum internalFormat, - GLsizei width, GLsizei height); - void glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data); - void glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); QOpenGLES3Helper *gles3Helper(); @@ -146,21 +297,12 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLExtensions::OpenGLExtensions) -class QOpenGLExtensionsPrivate : public QOpenGLFunctionsPrivate +class QOpenGLExtensionsPrivate : public QOpenGLExtraFunctionsPrivate { public: explicit QOpenGLExtensionsPrivate(QOpenGLContext *ctx); GLvoid* (QOPENGLF_APIENTRYP MapBuffer)(GLenum target, GLenum access); - GLvoid* (QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, qopengl_GLintptr offset, - qopengl_GLsizeiptr length, GLbitfield access); - GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); - void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, - GLenum internalFormat, - GLsizei width, GLsizei height); void (QOPENGLF_APIENTRYP GetBufferSubData)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data); void (QOPENGLF_APIENTRYP DiscardFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments); @@ -177,45 +319,6 @@ inline GLvoid *QOpenGLExtensions::glMapBuffer(GLenum target, GLenum access) return result; } -inline GLvoid *QOpenGLExtensions::glMapBufferRange(GLenum target, qopengl_GLintptr offset, - qopengl_GLsizeiptr length, GLbitfield access) -{ - Q_D(QOpenGLExtensions); - Q_ASSERT(QOpenGLExtensions::isInitialized(d)); - GLvoid *result = d->MapBufferRange(target, offset, length, access); - Q_OPENGL_FUNCTIONS_DEBUG - return result; -} - -inline GLboolean QOpenGLExtensions::glUnmapBuffer(GLenum target) -{ - Q_D(QOpenGLExtensions); - Q_ASSERT(QOpenGLExtensions::isInitialized(d)); - GLboolean result = d->UnmapBuffer(target); - Q_OPENGL_FUNCTIONS_DEBUG - return result; -} - -inline void QOpenGLExtensions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - Q_D(QOpenGLExtensions); - Q_ASSERT(QOpenGLExtensions::isInitialized(d)); - d->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - Q_OPENGL_FUNCTIONS_DEBUG -} - -inline void QOpenGLExtensions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, - GLenum internalFormat, - GLsizei width, GLsizei height) -{ - Q_D(QOpenGLExtensions); - Q_ASSERT(QOpenGLExtensions::isInitialized(d)); - d->RenderbufferStorageMultisample(target, samples, internalFormat, width, height); - Q_OPENGL_FUNCTIONS_DEBUG -} - inline void QOpenGLExtensions::glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data) { Q_D(QOpenGLExtensions); diff --git a/src/gui/opengl/qopenglextrafunctions.h b/src/gui/opengl/qopenglextrafunctions.h new file mode 100644 index 0000000000..6558284bd0 --- /dev/null +++ b/src/gui/opengl/qopenglextrafunctions.h @@ -0,0 +1,1990 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOPENGLEXTRAFUNCTIONS_H +#define QOPENGLEXTRAFUNCTIONS_H + +#include <QtCore/qglobal.h> + +#ifndef QT_NO_OPENGL + +#include <QtGui/qopenglfunctions.h> + +QT_BEGIN_NAMESPACE + +class QOpenGLExtraFunctionsPrivate; + +#undef glReadBuffer +#undef glDrawRangeElements +#undef glTexImage3D +#undef glTexSubImage3D +#undef glCopyTexSubImage3D +#undef glCompressedTexImage3D +#undef glCompressedTexSubImage3D +#undef glGenQueries +#undef glDeleteQueries +#undef glIsQuery +#undef glBeginQuery +#undef glEndQuery +#undef glGetQueryiv +#undef glGetQueryObjectuiv +#undef glUnmapBuffer +#undef glGetBufferPointerv +#undef glDrawBuffers +#undef glUniformMatrix2x3fv +#undef glUniformMatrix3x2fv +#undef glUniformMatrix2x4fv +#undef glUniformMatrix4x2fv +#undef glUniformMatrix3x4fv +#undef glUniformMatrix4x3fv +#undef glBlitFramebuffer +#undef glRenderbufferStorageMultisample +#undef glFramebufferTextureLayer +#undef glMapBufferRange +#undef glFlushMappedBufferRange +#undef glBindVertexArray +#undef glDeleteVertexArrays +#undef glGenVertexArrays +#undef glIsVertexArray +#undef glGetIntegeri_v +#undef glBeginTransformFeedback +#undef glEndTransformFeedback +#undef glBindBufferRange +#undef glBindBufferBase +#undef glTransformFeedbackVaryings +#undef glGetTransformFeedbackVarying +#undef glVertexAttribIPointer +#undef glGetVertexAttribIiv +#undef glGetVertexAttribIuiv +#undef glVertexAttribI4i +#undef glVertexAttribI4ui +#undef glVertexAttribI4iv +#undef glVertexAttribI4uiv +#undef glGetUniformuiv +#undef glGetFragDataLocation +#undef glUniform1ui +#undef glUniform2ui +#undef glUniform3ui +#undef glUniform4ui +#undef glUniform1uiv +#undef glUniform2uiv +#undef glUniform3uiv +#undef glUniform4uiv +#undef glClearBufferiv +#undef glClearBufferuiv +#undef glClearBufferfv +#undef glClearBufferfi +#undef glGetStringi +#undef glCopyBufferSubData +#undef glGetUniformIndices +#undef glGetActiveUniformsiv +#undef glGetUniformBlockIndex +#undef glGetActiveUniformBlockiv +#undef glGetActiveUniformBlockName +#undef glUniformBlockBinding +#undef glDrawArraysInstanced +#undef glDrawElementsInstanced +#undef glFenceSync +#undef glIsSync +#undef glDeleteSync +#undef glClientWaitSync +#undef glWaitSync +#undef glGetInteger64v +#undef glGetSynciv +#undef glGetInteger64i_v +#undef glGetBufferParameteri64v +#undef glGenSamplers +#undef glDeleteSamplers +#undef glIsSampler +#undef glBindSampler +#undef glSamplerParameteri +#undef glSamplerParameteriv +#undef glSamplerParameterf +#undef glSamplerParameterfv +#undef glGetSamplerParameteriv +#undef glGetSamplerParameterfv +#undef glVertexAttribDivisor +#undef glBindTransformFeedback +#undef glDeleteTransformFeedbacks +#undef glGenTransformFeedbacks +#undef glIsTransformFeedback +#undef glPauseTransformFeedback +#undef glResumeTransformFeedback +#undef glGetProgramBinary +#undef glProgramBinary +#undef glProgramParameteri +#undef glInvalidateFramebuffer +#undef glInvalidateSubFramebuffer +#undef glTexStorage2D +#undef glTexStorage3D +#undef glGetInternalformativ + +#undef glDispatchCompute +#undef glDispatchComputeIndirect +#undef glDrawArraysIndirect +#undef glDrawElementsIndirect +#undef glFramebufferParameteri +#undef glGetFramebufferParameteriv +#undef glGetProgramInterfaceiv +#undef glGetProgramResourceIndex +#undef glGetProgramResourceName +#undef glGetProgramResourceiv +#undef glGetProgramResourceLocation +#undef glUseProgramStages +#undef glActiveShaderProgram +#undef glCreateShaderProgramv +#undef glBindProgramPipeline +#undef glDeleteProgramPipelines +#undef glGenProgramPipelines +#undef glIsProgramPipeline +#undef glGetProgramPipelineiv +#undef glProgramUniform1i +#undef glProgramUniform2i +#undef glProgramUniform3i +#undef glProgramUniform4i +#undef glProgramUniform1ui +#undef glProgramUniform2ui +#undef glProgramUniform3ui +#undef glProgramUniform4ui +#undef glProgramUniform1f +#undef glProgramUniform2f +#undef glProgramUniform3f +#undef glProgramUniform4f +#undef glProgramUniform1iv +#undef glProgramUniform2iv +#undef glProgramUniform3iv +#undef glProgramUniform4iv +#undef glProgramUniform1uiv +#undef glProgramUniform2uiv +#undef glProgramUniform3uiv +#undef glProgramUniform4uiv +#undef glProgramUniform1fv +#undef glProgramUniform2fv +#undef glProgramUniform3fv +#undef glProgramUniform4fv +#undef glProgramUniformMatrix2fv +#undef glProgramUniformMatrix3fv +#undef glProgramUniformMatrix4fv +#undef glProgramUniformMatrix2x3fv +#undef glProgramUniformMatrix3x2fv +#undef glProgramUniformMatrix2x4fv +#undef glProgramUniformMatrix4x2fv +#undef glProgramUniformMatrix3x4fv +#undef glProgramUniformMatrix4x3fv +#undef glValidateProgramPipeline +#undef glGetProgramPipelineInfoLog +#undef glBindImageTexture +#undef glGetBooleani_v +#undef glMemoryBarrier +#undef glMemoryBarrierByRegion +#undef glTexStorage2DMultisample +#undef glGetMultisamplefv +#undef glSampleMaski +#undef glGetTexLevelParameteriv +#undef glGetTexLevelParameterfv +#undef glBindVertexBuffer +#undef glVertexAttribFormat +#undef glVertexAttribIFormat +#undef glVertexAttribBinding +#undef glVertexBindingDivisor + +class Q_GUI_EXPORT QOpenGLExtraFunctions : public QOpenGLFunctions +{ + Q_DECLARE_PRIVATE(QOpenGLExtraFunctions) + +public: + QOpenGLExtraFunctions(); + QOpenGLExtraFunctions(QOpenGLContext *context); + ~QOpenGLExtraFunctions() {} + + // GLES3 + void glReadBuffer(GLenum mode); + void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); + void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); + void glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + void glGenQueries(GLsizei n, GLuint *ids); + void glDeleteQueries(GLsizei n, const GLuint *ids); + GLboolean glIsQuery(GLuint id); + void glBeginQuery(GLenum target, GLuint id); + void glEndQuery(GLenum target); + void glGetQueryiv(GLenum target, GLenum pname, GLint *params); + void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); + GLboolean glUnmapBuffer(GLenum target); + void glGetBufferPointerv(GLenum target, GLenum pname, void **params); + void glDrawBuffers(GLsizei n, const GLenum *bufs); + void glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + void glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + void *glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + void glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length); + void glBindVertexArray(GLuint array); + void glDeleteVertexArrays(GLsizei n, const GLuint *arrays); + void glGenVertexArrays(GLsizei n, GLuint *arrays); + GLboolean glIsVertexArray(GLuint array); + void glGetIntegeri_v(GLenum target, GLuint index, GLint *data); + void glBeginTransformFeedback(GLenum primitiveMode); + void glEndTransformFeedback(void); + void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + void glBindBufferBase(GLenum target, GLuint index, GLuint buffer); + void glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); + void glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); + void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + void glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params); + void glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params); + void glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); + void glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void glVertexAttribI4iv(GLuint index, const GLint *v); + void glVertexAttribI4uiv(GLuint index, const GLuint *v); + void glGetUniformuiv(GLuint program, GLint location, GLuint *params); + GLint glGetFragDataLocation(GLuint program, const GLchar *name); + void glUniform1ui(GLint location, GLuint v0); + void glUniform2ui(GLint location, GLuint v0, GLuint v1); + void glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2); + void glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void glUniform1uiv(GLint location, GLsizei count, const GLuint *value); + void glUniform2uiv(GLint location, GLsizei count, const GLuint *value); + void glUniform3uiv(GLint location, GLsizei count, const GLuint *value); + void glUniform4uiv(GLint location, GLsizei count, const GLuint *value); + void glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value); + void glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value); + void glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value); + void glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + const GLubyte *glGetStringi(GLenum name, GLuint index); + void glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + void glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); + void glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); + GLuint glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName); + void glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); + void glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); + void glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); + GLsync glFenceSync(GLenum condition, GLbitfield flags); + GLboolean glIsSync(GLsync sync); + void glDeleteSync(GLsync sync); + GLenum glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); + void glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); + void glGetInteger64v(GLenum pname, GLint64 *data); + void glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); + void glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data); + void glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params); + void glGenSamplers(GLsizei count, GLuint *samplers); + void glDeleteSamplers(GLsizei count, const GLuint *samplers); + GLboolean glIsSampler(GLuint sampler); + void glBindSampler(GLuint unit, GLuint sampler); + void glSamplerParameteri(GLuint sampler, GLenum pname, GLint param); + void glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param); + void glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param); + void glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param); + void glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params); + void glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params); + void glVertexAttribDivisor(GLuint index, GLuint divisor); + void glBindTransformFeedback(GLenum target, GLuint id); + void glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids); + void glGenTransformFeedbacks(GLsizei n, GLuint *ids); + GLboolean glIsTransformFeedback(GLuint id); + void glPauseTransformFeedback(void); + void glResumeTransformFeedback(void); + void glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); + void glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); + void glProgramParameteri(GLuint program, GLenum pname, GLint value); + void glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments); + void glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); + void glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + void glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + void glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); + + // GLES 3.1 + void glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); + void glDispatchComputeIndirect(GLintptr indirect); + void glDrawArraysIndirect(GLenum mode, const void *indirect); + void glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect); + void glFramebufferParameteri(GLenum target, GLenum pname, GLint param); + void glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params); + void glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint *params); + GLuint glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name); + void glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); + void glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); + GLint glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar *name); + void glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program); + void glActiveShaderProgram(GLuint pipeline, GLuint program); + GLuint glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const*strings); + void glBindProgramPipeline(GLuint pipeline); + void glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines); + void glGenProgramPipelines(GLsizei n, GLuint *pipelines); + GLboolean glIsProgramPipeline(GLuint pipeline); + void glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params); + void glProgramUniform1i(GLuint program, GLint location, GLint v0); + void glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1); + void glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); + void glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void glProgramUniform1ui(GLuint program, GLint location, GLuint v0); + void glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1); + void glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); + void glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void glProgramUniform1f(GLuint program, GLint location, GLfloat v0); + void glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1); + void glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + void glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glValidateProgramPipeline(GLuint pipeline); + void glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + void glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); + void glGetBooleani_v(GLenum target, GLuint index, GLboolean *data); + void glMemoryBarrier(GLbitfield barriers); + void glMemoryBarrierByRegion(GLbitfield barriers); + void glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + void glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val); + void glSampleMaski(GLuint maskNumber, GLbitfield mask); + void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params); + void glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params); + void glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + void glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + void glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + void glVertexAttribBinding(GLuint attribindex, GLuint bindingindex); + void glVertexBindingDivisor(GLuint bindingindex, GLuint divisor); + +private: + static bool isInitialized(const QOpenGLExtraFunctionsPrivate *d) { return d != 0; } +}; + +class QOpenGLExtraFunctionsPrivate : public QOpenGLFunctionsPrivate +{ +public: + QOpenGLExtraFunctionsPrivate(QOpenGLContext *ctx); + + // GLES3 + void (QOPENGLF_APIENTRYP ReadBuffer)(GLenum mode); + void (QOPENGLF_APIENTRYP DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); + void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + void (QOPENGLF_APIENTRYP CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); + void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + void (QOPENGLF_APIENTRYP GenQueries)(GLsizei n, GLuint *ids); + void (QOPENGLF_APIENTRYP DeleteQueries)(GLsizei n, const GLuint *ids); + GLboolean (QOPENGLF_APIENTRYP IsQuery)(GLuint id); + void (QOPENGLF_APIENTRYP BeginQuery)(GLenum target, GLuint id); + void (QOPENGLF_APIENTRYP EndQuery)(GLenum target); + void (QOPENGLF_APIENTRYP GetQueryiv)(GLenum target, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params); + GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); + void (QOPENGLF_APIENTRYP GetBufferPointerv)(GLenum target, GLenum pname, void **params); + void (QOPENGLF_APIENTRYP DrawBuffers)(GLsizei n, const GLenum *bufs); + void (QOPENGLF_APIENTRYP UniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP UniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP FramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + void *(QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + void (QOPENGLF_APIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length); + void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); + void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); + GLboolean (QOPENGLF_APIENTRYP IsVertexArray)(GLuint array); + void (QOPENGLF_APIENTRYP GetIntegeri_v)(GLenum target, GLuint index, GLint *data); + void (QOPENGLF_APIENTRYP BeginTransformFeedback)(GLenum primitiveMode); + void (QOPENGLF_APIENTRYP EndTransformFeedback)(void); + void (QOPENGLF_APIENTRYP BindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + void (QOPENGLF_APIENTRYP BindBufferBase)(GLenum target, GLuint index, GLuint buffer); + void (QOPENGLF_APIENTRYP TransformFeedbackVaryings)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); + void (QOPENGLF_APIENTRYP GetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); + void (QOPENGLF_APIENTRYP VertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + void (QOPENGLF_APIENTRYP GetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params); + void (QOPENGLF_APIENTRYP VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w); + void (QOPENGLF_APIENTRYP VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void (QOPENGLF_APIENTRYP VertexAttribI4iv)(GLuint index, const GLint *v); + void (QOPENGLF_APIENTRYP VertexAttribI4uiv)(GLuint index, const GLuint *v); + void (QOPENGLF_APIENTRYP GetUniformuiv)(GLuint program, GLint location, GLuint *params); + GLint (QOPENGLF_APIENTRYP GetFragDataLocation)(GLuint program, const GLchar *name); + void (QOPENGLF_APIENTRYP Uniform1ui)(GLint location, GLuint v0); + void (QOPENGLF_APIENTRYP Uniform2ui)(GLint location, GLuint v0, GLuint v1); + void (QOPENGLF_APIENTRYP Uniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2); + void (QOPENGLF_APIENTRYP Uniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void (QOPENGLF_APIENTRYP Uniform1uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform2uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform3uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP Uniform4uiv)(GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value); + void (QOPENGLF_APIENTRYP ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value); + void (QOPENGLF_APIENTRYP ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value); + void (QOPENGLF_APIENTRYP ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + const GLubyte *(QOPENGLF_APIENTRYP GetStringi)(GLenum name, GLuint index); + void (QOPENGLF_APIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + void (QOPENGLF_APIENTRYP GetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); + void (QOPENGLF_APIENTRYP GetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); + GLuint (QOPENGLF_APIENTRYP GetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName); + void (QOPENGLF_APIENTRYP GetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); + void (QOPENGLF_APIENTRYP UniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + void (QOPENGLF_APIENTRYP DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + void (QOPENGLF_APIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); + GLsync (QOPENGLF_APIENTRYP FenceSync)(GLenum condition, GLbitfield flags); + GLboolean (QOPENGLF_APIENTRYP IsSync)(GLsync sync); + void (QOPENGLF_APIENTRYP DeleteSync)(GLsync sync); + GLenum (QOPENGLF_APIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + void (QOPENGLF_APIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + void (QOPENGLF_APIENTRYP GetInteger64v)(GLenum pname, GLint64 *data); + void (QOPENGLF_APIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); + void (QOPENGLF_APIENTRYP GetInteger64i_v)(GLenum target, GLuint index, GLint64 *data); + void (QOPENGLF_APIENTRYP GetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 *params); + void (QOPENGLF_APIENTRYP GenSamplers)(GLsizei count, GLuint *samplers); + void (QOPENGLF_APIENTRYP DeleteSamplers)(GLsizei count, const GLuint *samplers); + GLboolean (QOPENGLF_APIENTRYP IsSampler)(GLuint sampler); + void (QOPENGLF_APIENTRYP BindSampler)(GLuint unit, GLuint sampler); + void (QOPENGLF_APIENTRYP SamplerParameteri)(GLuint sampler, GLenum pname, GLint param); + void (QOPENGLF_APIENTRYP SamplerParameteriv)(GLuint sampler, GLenum pname, const GLint *param); + void (QOPENGLF_APIENTRYP SamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param); + void (QOPENGLF_APIENTRYP SamplerParameterfv)(GLuint sampler, GLenum pname, const GLfloat *param); + void (QOPENGLF_APIENTRYP GetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat *params); + void (QOPENGLF_APIENTRYP VertexAttribDivisor)(GLuint index, GLuint divisor); + void (QOPENGLF_APIENTRYP BindTransformFeedback)(GLenum target, GLuint id); + void (QOPENGLF_APIENTRYP DeleteTransformFeedbacks)(GLsizei n, const GLuint *ids); + void (QOPENGLF_APIENTRYP GenTransformFeedbacks)(GLsizei n, GLuint *ids); + GLboolean (QOPENGLF_APIENTRYP IsTransformFeedback)(GLuint id); + void (QOPENGLF_APIENTRYP PauseTransformFeedback)(void); + void (QOPENGLF_APIENTRYP ResumeTransformFeedback)(void); + void (QOPENGLF_APIENTRYP GetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); + void (QOPENGLF_APIENTRYP ProgramBinary)(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); + void (QOPENGLF_APIENTRYP ProgramParameteri)(GLuint program, GLenum pname, GLint value); + void (QOPENGLF_APIENTRYP InvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments); + void (QOPENGLF_APIENTRYP InvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + void (QOPENGLF_APIENTRYP GetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); + + // GLES 3.1 + void (QOPENGLF_APIENTRYP DispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); + void (QOPENGLF_APIENTRYP DispatchComputeIndirect)(GLintptr indirect); + void (QOPENGLF_APIENTRYP DrawArraysIndirect)(GLenum mode, const void *indirect); + void (QOPENGLF_APIENTRYP DrawElementsIndirect)(GLenum mode, GLenum type, const void *indirect); + void (QOPENGLF_APIENTRYP FramebufferParameteri)(GLenum target, GLenum pname, GLint param); + void (QOPENGLF_APIENTRYP GetFramebufferParameteriv)(GLenum target, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint *params); + GLuint (QOPENGLF_APIENTRYP GetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar *name); + void (QOPENGLF_APIENTRYP GetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); + void (QOPENGLF_APIENTRYP GetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); + GLint (QOPENGLF_APIENTRYP GetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar *name); + void (QOPENGLF_APIENTRYP UseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program); + void (QOPENGLF_APIENTRYP ActiveShaderProgram)(GLuint pipeline, GLuint program); + GLuint (QOPENGLF_APIENTRYP CreateShaderProgramv)(GLenum type, GLsizei count, const GLchar *const*strings); + void (QOPENGLF_APIENTRYP BindProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP DeleteProgramPipelines)(GLsizei n, const GLuint *pipelines); + void (QOPENGLF_APIENTRYP GenProgramPipelines)(GLsizei n, GLuint *pipelines); + GLboolean (QOPENGLF_APIENTRYP IsProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP GetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP ProgramUniform1i)(GLuint program, GLint location, GLint v0); + void (QOPENGLF_APIENTRYP ProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1); + void (QOPENGLF_APIENTRYP ProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); + void (QOPENGLF_APIENTRYP ProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void (QOPENGLF_APIENTRYP ProgramUniform1ui)(GLuint program, GLint location, GLuint v0); + void (QOPENGLF_APIENTRYP ProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1); + void (QOPENGLF_APIENTRYP ProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); + void (QOPENGLF_APIENTRYP ProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void (QOPENGLF_APIENTRYP ProgramUniform1f)(GLuint program, GLint location, GLfloat v0); + void (QOPENGLF_APIENTRYP ProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1); + void (QOPENGLF_APIENTRYP ProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void (QOPENGLF_APIENTRYP ProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + void (QOPENGLF_APIENTRYP ProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint *value); + void (QOPENGLF_APIENTRYP ProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); + void (QOPENGLF_APIENTRYP ProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void (QOPENGLF_APIENTRYP ValidateProgramPipeline)(GLuint pipeline); + void (QOPENGLF_APIENTRYP GetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + void (QOPENGLF_APIENTRYP BindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); + void (QOPENGLF_APIENTRYP GetBooleani_v)(GLenum target, GLuint index, GLboolean *data); + void (QOPENGLF_APIENTRYP MemoryBarrierFunc)(GLbitfield barriers); + void (QOPENGLF_APIENTRYP MemoryBarrierByRegion)(GLbitfield barriers); + void (QOPENGLF_APIENTRYP TexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + void (QOPENGLF_APIENTRYP GetMultisamplefv)(GLenum pname, GLuint index, GLfloat *val); + void (QOPENGLF_APIENTRYP SampleMaski)(GLuint maskNumber, GLbitfield mask); + void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params); + void (QOPENGLF_APIENTRYP GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params); + void (QOPENGLF_APIENTRYP BindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + void (QOPENGLF_APIENTRYP VertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + void (QOPENGLF_APIENTRYP VertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + void (QOPENGLF_APIENTRYP VertexAttribBinding)(GLuint attribindex, GLuint bindingindex); + void (QOPENGLF_APIENTRYP VertexBindingDivisor)(GLuint bindingindex, GLuint divisor); +}; + +// GLES 3.0 and 3.1 + +inline void QOpenGLExtraFunctions::glBeginQuery(GLenum target, GLuint id) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BeginQuery(target, id); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBeginTransformFeedback(GLenum primitiveMode) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BeginTransformFeedback(primitiveMode); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindBufferBase(GLenum target, GLuint index, GLuint buffer) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindBufferBase(target, index, buffer); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindBufferRange(target, index, buffer, offset, size); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindSampler(GLuint unit, GLuint sampler) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindSampler(unit, sampler); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindTransformFeedback(GLenum target, GLuint id) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindTransformFeedback(target, id); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindVertexArray(GLuint array) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindVertexArray(array); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ClearBufferfi(buffer, drawbuffer, depth, stencil); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ClearBufferfv(buffer, drawbuffer, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ClearBufferiv(buffer, drawbuffer, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ClearBufferuiv(buffer, drawbuffer, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLenum QOpenGLExtraFunctions::glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLenum result = d->ClientWaitSync(sync, flags, timeout); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteQueries(GLsizei n, const GLuint * ids) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteQueries(n, ids); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteSamplers(GLsizei count, const GLuint * samplers) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteSamplers(count, samplers); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteSync(GLsync sync) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteSync(sync); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteTransformFeedbacks(GLsizei n, const GLuint * ids) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteTransformFeedbacks(n, ids); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDeleteVertexArrays(GLsizei n, const GLuint * arrays) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteVertexArrays(n, arrays); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawArraysInstanced(mode, first, count, instancecount); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawBuffers(GLsizei n, const GLenum * bufs) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawBuffers(n, bufs); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawElementsInstanced(mode, count, type, indices, instancecount); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawRangeElements(mode, start, end, count, type, indices); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glEndQuery(GLenum target) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->EndQuery(target); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glEndTransformFeedback() +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->EndTransformFeedback(); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLsync QOpenGLExtraFunctions::glFenceSync(GLenum condition, GLbitfield flags) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLsync result = d->FenceSync(condition, flags); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->FlushMappedBufferRange(target, offset, length); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->FramebufferTextureLayer(target, attachment, texture, level, layer); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenQueries(GLsizei n, GLuint* ids) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenQueries(n, ids); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenSamplers(GLsizei count, GLuint* samplers) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenSamplers(count, samplers); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenTransformFeedbacks(GLsizei n, GLuint* ids) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenTransformFeedbacks(n, ids); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenVertexArrays(GLsizei n, GLuint* arrays) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenVertexArrays(n, arrays); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetBufferParameteri64v(target, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetBufferPointerv(GLenum target, GLenum pname, void ** params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetBufferPointerv(target, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLint QOpenGLExtraFunctions::glGetFragDataLocation(GLuint program, const GLchar * name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLint result = d->GetFragDataLocation(program, name); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetInteger64i_v(target, index, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetInteger64v(GLenum pname, GLint64* data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetInteger64v(pname, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetIntegeri_v(GLenum target, GLuint index, GLint* data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetIntegeri_v(target, index, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetInternalformativ(target, internalformat, pname, bufSize, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void * binary) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramBinary(program, bufSize, length, binaryFormat, binary); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetQueryObjectuiv(id, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetQueryiv(GLenum target, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetQueryiv(target, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetSamplerParameterfv(sampler, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetSamplerParameteriv(sampler, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline const GLubyte * QOpenGLExtraFunctions::glGetStringi(GLenum name, GLuint index) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + const GLubyte * result = d->GetStringi(name, index); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetSynciv(sync, pname, bufSize, length, values); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLuint QOpenGLExtraFunctions::glGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLuint result = d->GetUniformBlockIndex(program, uniformBlockName); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint* uniformIndices) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetUniformIndices(program, uniformCount, uniformNames, uniformIndices); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetUniformuiv(GLuint program, GLint location, GLuint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetUniformuiv(program, location, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetVertexAttribIiv(index, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetVertexAttribIuiv(index, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->InvalidateFramebuffer(target, numAttachments, attachments); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->InvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLboolean QOpenGLExtraFunctions::glIsQuery(GLuint id) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsQuery(id); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLboolean QOpenGLExtraFunctions::glIsSampler(GLuint sampler) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsSampler(sampler); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLboolean QOpenGLExtraFunctions::glIsSync(GLsync sync) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsSync(sync); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLboolean QOpenGLExtraFunctions::glIsTransformFeedback(GLuint id) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsTransformFeedback(id); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLboolean QOpenGLExtraFunctions::glIsVertexArray(GLuint array) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsVertexArray(array); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void * QOpenGLExtraFunctions::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + void *result = d->MapBufferRange(target, offset, length, access); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glPauseTransformFeedback() +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->PauseTransformFeedback(); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramBinary(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramBinary(program, binaryFormat, binary, length); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramParameteri(GLuint program, GLenum pname, GLint value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramParameteri(program, pname, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glReadBuffer(GLenum src) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ReadBuffer(src); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->RenderbufferStorageMultisample(target, samples, internalformat, width, height); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glResumeTransformFeedback() +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ResumeTransformFeedback(); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SamplerParameterf(sampler, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat * param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SamplerParameterfv(sampler, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SamplerParameteri(sampler, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint * param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SamplerParameteriv(sampler, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexStorage2D(target, levels, internalformat, width, height); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexStorage3D(target, levels, internalformat, width, height, depth); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TransformFeedbackVaryings(program, count, varyings, bufferMode); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform1ui(GLint location, GLuint v0) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform1ui(location, v0); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform1uiv(GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform1uiv(location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform2ui(GLint location, GLuint v0, GLuint v1) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform2ui(location, v0, v1); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform2uiv(GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform2uiv(location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform3ui(location, v0, v1, v2); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform3uiv(GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform3uiv(location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform4ui(location, v0, v1, v2, v3); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniform4uiv(GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->Uniform4uiv(location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix2x3fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix2x4fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix3x2fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix3x4fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix4x2fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UniformMatrix4x3fv(location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLboolean QOpenGLExtraFunctions::glUnmapBuffer(GLenum target) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->UnmapBuffer(target); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glVertexAttribDivisor(GLuint index, GLuint divisor) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribDivisor(index, divisor); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribI4i(index, x, y, z, w); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribI4iv(GLuint index, const GLint * v) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribI4iv(index, v); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribI4ui(index, x, y, z, w); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribI4uiv(GLuint index, const GLuint * v) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribI4uiv(index, v); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribIPointer(index, size, type, stride, pointer); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->WaitSync(sync, flags, timeout); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glActiveShaderProgram(GLuint pipeline, GLuint program) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ActiveShaderProgram(pipeline, program); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindImageTexture(unit, texture, level, layered, layer, access, format); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindProgramPipeline(GLuint pipeline) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindProgramPipeline(pipeline); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->BindVertexBuffer(bindingindex, buffer, offset, stride); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLuint QOpenGLExtraFunctions::glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const* strings) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLuint result = d->CreateShaderProgramv(type, count, strings); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glDeleteProgramPipelines(GLsizei n, const GLuint * pipelines) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DeleteProgramPipelines(n, pipelines); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DispatchCompute(num_groups_x, num_groups_y, num_groups_z); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDispatchComputeIndirect(GLintptr indirect) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DispatchComputeIndirect(indirect); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawArraysIndirect(GLenum mode, const void * indirect) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawArraysIndirect(mode, indirect); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->DrawElementsIndirect(mode, type, indirect); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glFramebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->FramebufferParameteri(target, pname, param); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGenProgramPipelines(GLsizei n, GLuint* pipelines) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GenProgramPipelines(n, pipelines); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetBooleani_v(GLenum target, GLuint index, GLboolean* data) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetBooleani_v(target, index, data); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetFramebufferParameteriv(target, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetMultisamplefv(pname, index, val); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramInterfaceiv(program, programInterface, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramPipelineiv(pipeline, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLuint QOpenGLExtraFunctions::glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLuint result = d->GetProgramResourceIndex(program, programInterface, name); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline GLint QOpenGLExtraFunctions::glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLint result = d->GetProgramResourceLocation(program, programInterface, name); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramResourceName(program, programInterface, index, bufSize, length, name); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei* length, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetTexLevelParameterfv(target, level, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->GetTexLevelParameteriv(target, level, pname, params); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline GLboolean QOpenGLExtraFunctions::glIsProgramPipeline(GLuint pipeline) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + GLboolean result = d->IsProgramPipeline(pipeline); + Q_OPENGL_FUNCTIONS_DEBUG + return result; +} + +inline void QOpenGLExtraFunctions::glMemoryBarrier(GLbitfield barriers) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->MemoryBarrierFunc(barriers); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glMemoryBarrierByRegion(GLbitfield barriers) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->MemoryBarrierByRegion(barriers); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1f(program, location, v0); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1fv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1i(program, location, v0); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1iv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1ui(GLuint program, GLint location, GLuint v0) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1ui(program, location, v0); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform1uiv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2f(program, location, v0, v1); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2fv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2i(program, location, v0, v1); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2iv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2ui(program, location, v0, v1); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform2uiv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3f(program, location, v0, v1, v2); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3fv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3i(program, location, v0, v1, v2); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3iv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3ui(program, location, v0, v1, v2); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform3uiv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4f(program, location, v0, v1, v2, v3); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4fv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4i(program, location, v0, v1, v2, v3); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4iv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4ui(program, location, v0, v1, v2, v3); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniform4uiv(program, location, count, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix2fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix2x3fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix2x4fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix3fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix3x2fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix3x4fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix4fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix4x2fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ProgramUniformMatrix4x3fv(program, location, count, transpose, value); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glSampleMaski(GLuint maskNumber, GLbitfield mask) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->SampleMaski(maskNumber, mask); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->UseProgramStages(pipeline, stages, program); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glValidateProgramPipeline(GLuint pipeline) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->ValidateProgramPipeline(pipeline); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribBinding(GLuint attribindex, GLuint bindingindex) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribBinding(attribindex, bindingindex); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribFormat(attribindex, size, type, normalized, relativeoffset); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexAttribIFormat(attribindex, size, type, relativeoffset); + Q_OPENGL_FUNCTIONS_DEBUG +} + +inline void QOpenGLExtraFunctions::glVertexBindingDivisor(GLuint bindingindex, GLuint divisor) +{ + Q_D(QOpenGLExtraFunctions); + Q_ASSERT(QOpenGLExtraFunctions::isInitialized(d)); + d->VertexBindingDivisor(bindingindex, divisor); + Q_OPENGL_FUNCTIONS_DEBUG +} + +QT_END_NAMESPACE + +#endif // QT_NO_OPENGL + +#endif diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 8d298496df..3596591cf6 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -166,7 +166,7 @@ void QOpenGLFramebufferObjectFormat::detach() the format of an OpenGL framebuffer object. By default the format specifies a non-multisample framebuffer object with no - attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8. + depth/stencil attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8. On OpenGL/ES systems, the default internal format is \c GL_RGBA. \sa samples(), attachment(), internalTextureFormat() @@ -436,10 +436,10 @@ namespace } } -void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &sz, - QOpenGLFramebufferObject::Attachment attachment, - GLenum texture_target, GLenum internal_format, - GLint samples, bool mipmap) +void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &size, + QOpenGLFramebufferObject::Attachment attachment, + GLenum texture_target, GLenum internal_format, + GLint samples, bool mipmap) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); @@ -458,9 +458,13 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi samples = qBound(0, int(samples), int(maxSamples)); } + colorAttachments.append(ColorAttachment(size, internal_format)); + + dsSize = size; + samples = qMax(0, samples); requestedSamples = samples; - size = sz; + target = texture_target; QT_RESET_GLERROR(); // reset error state @@ -471,64 +475,30 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true; - GLuint color_buffer = 0; - QT_CHECK_GLERROR(); - // init texture - if (samples == 0) { - initTexture(texture_target, internal_format, size, mipmap); - } else { - GLenum storageFormat = internal_format; - // ES requires a sized format. The older desktop extension does not. Correct the format on ES. - if (ctx->isOpenGLES() && internal_format == GL_RGBA) { - if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats)) - storageFormat = GL_RGBA8; - else - storageFormat = GL_RGBA4; - } - - mipmap = false; - funcs.glGenRenderbuffers(1, &color_buffer); - funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer); - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storageFormat, size.width(), size.height()); - funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, color_buffer); - QT_CHECK_GLERROR(); - valid = checkFramebufferStatus(ctx); - - if (valid) { - // Query the actual number of samples. This can be greater than the requested - // value since the typically supported values are 0, 4, 8, ..., and the - // requests are mapped to the next supported value. - funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); - color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc); - } - } format.setTextureTarget(target); - format.setSamples(int(samples)); format.setInternalTextureFormat(internal_format); format.setMipmap(mipmap); - initAttachments(ctx, attachment); + if (samples == 0) + initTexture(0); + else + initColorBuffer(0, &samples); + + format.setSamples(int(samples)); - if (valid) { + initDepthStencilAttachments(ctx, attachment); + + if (valid) fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc); - } else { - if (color_buffer_guard) { - color_buffer_guard->free(); - color_buffer_guard = 0; - } else if (texture_guard) { - texture_guard->free(); - texture_guard = 0; - } + else funcs.glDeleteFramebuffers(1, &fbo); - } + QT_CHECK_GLERROR(); } -void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal_format, - const QSize &size, bool mipmap) +void QOpenGLFramebufferObjectPrivate::initTexture(int idx) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); GLuint texture = 0; @@ -541,37 +511,76 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + ColorAttachment &color(colorAttachments[idx]); + GLuint pixelType = GL_UNSIGNED_BYTE; - if (internal_format == GL_RGB10_A2 || internal_format == GL_RGB10) + if (color.internalFormat == GL_RGB10_A2 || color.internalFormat == GL_RGB10) pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; - funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, + funcs.glTexImage2D(target, 0, color.internalFormat, color.size.width(), color.size.height(), 0, GL_RGBA, pixelType, NULL); - if (mipmap) { - int width = size.width(); - int height = size.height(); + if (format.mipmap()) { + int width = color.size.width(); + int height = color.size.height(); int level = 0; while (width > 1 || height > 1) { width = qMax(1, width >> 1); height = qMax(1, height >> 1); ++level; - funcs.glTexImage2D(target, level, internal_format, width, height, 0, + funcs.glTexImage2D(target, level, color.internalFormat, width, height, 0, GL_RGBA, pixelType, NULL); } } - funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + idx, target, texture, 0); QT_CHECK_GLERROR(); funcs.glBindTexture(target, 0); valid = checkFramebufferStatus(ctx); - if (valid) - texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc); - else + if (valid) { + color.guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc); + } else { funcs.glDeleteTextures(1, &texture); + } +} + +void QOpenGLFramebufferObjectPrivate::initColorBuffer(int idx, GLint *samples) +{ + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + GLuint color_buffer = 0; + + ColorAttachment &color(colorAttachments[idx]); + + GLenum storageFormat = color.internalFormat; + // ES requires a sized format. The older desktop extension does not. Correct the format on ES. + if (ctx->isOpenGLES() && color.internalFormat == GL_RGBA) { + if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats)) + storageFormat = GL_RGBA8; + else + storageFormat = GL_RGBA4; + } + + funcs.glGenRenderbuffers(1, &color_buffer); + funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer); + funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, *samples, storageFormat, color.size.width(), color.size.height()); + funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + idx, + GL_RENDERBUFFER, color_buffer); + + QT_CHECK_GLERROR(); + valid = checkFramebufferStatus(ctx); + if (valid) { + // Query the actual number of samples. This can be greater than the requested + // value since the typically supported values are 0, 4, 8, ..., and the + // requests are mapped to the next supported value. + funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, samples); + color.guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc); + } else { + funcs.glDeleteRenderbuffers(1, &color_buffer); + } } -void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment) +void QOpenGLFramebufferObjectPrivate::initDepthStencilAttachments(QOpenGLContext *ctx, + QOpenGLFramebufferObject::Attachment attachment) { // Use the same sample count for all attachments. format.samples() already contains // the actual number of samples for the color attachment and is not suitable. Use @@ -608,10 +617,10 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer)); if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH24_STENCIL8, size.width(), size.height()); + GL_DEPTH24_STENCIL8, dsSize.width(), dsSize.height()); else funcs.glRenderbufferStorage(GL_RENDERBUFFER, - GL_DEPTH24_STENCIL8, size.width(), size.height()); + GL_DEPTH24_STENCIL8, dsSize.width(), dsSize.height()); stencil_buffer = depth_buffer; funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, @@ -636,25 +645,25 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH_COMPONENT24, size.width(), size.height()); + GL_DEPTH_COMPONENT24, dsSize.width(), dsSize.height()); else funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH_COMPONENT16, size.width(), size.height()); + GL_DEPTH_COMPONENT16, dsSize.width(), dsSize.height()); } else { funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH_COMPONENT, size.width(), size.height()); + GL_DEPTH_COMPONENT, dsSize.width(), dsSize.height()); } } else { if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, - size.width(), size.height()); + dsSize.width(), dsSize.height()); } else { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, - size.width(), size.height()); + dsSize.width(), dsSize.height()); } } else { - funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height()); + funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, dsSize.width(), dsSize.height()); } } funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, @@ -678,9 +687,9 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen #endif if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height()); + funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, dsSize.width(), dsSize.height()); else - funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height()); + funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, dsSize.width(), dsSize.height()); funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_buffer); @@ -756,6 +765,11 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen format, and will be bound to the \c GL_COLOR_ATTACHMENT0 attachment in the framebuffer object. + Multiple render targets are also supported, in case the OpenGL + implementation supports this. Here there will be multiple textures (or, in + case of multisampling, renderbuffers) present and each of them will get + attached to \c GL_COLOR_ATTACHMENT0, \c 1, \c 2, ... + If you want to use a framebuffer object with multisampling enabled as a texture, you first need to copy from it to a regular framebuffer object using QOpenGLContext::blitFramebuffer(). @@ -785,6 +799,16 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen \sa attachment() */ +static inline GLenum effectiveInternalFormat(GLenum internalFormat) +{ + if (!internalFormat) +#ifdef QT_OPENGL_ES_2 + internalFormat = GL_RGBA; +#else + internalFormat = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; +#endif + return internalFormat; +} /*! \fn QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum target) @@ -814,13 +838,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum tar : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); - d->init(this, size, NoAttachment, target, -#ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 -#else - GL_RGBA -#endif - ); + d->init(this, size, NoAttachment, target, effectiveInternalFormat(0)); } /*! \overload @@ -834,13 +852,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); - d->init(this, QSize(width, height), NoAttachment, target, -#ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 -#else - GL_RGBA -#endif - ); + d->init(this, QSize(width, height), NoAttachment, target, effectiveInternalFormat(0)); } /*! \overload @@ -877,7 +889,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, const buffer of the given \a width and \a height. The \a attachment parameter describes the depth/stencil buffer - configuration, \a target the texture target and \a internal_format + configuration, \a target the texture target and \a internalFormat the internal texture format. The default texture target is \c GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8 for desktop OpenGL and \c GL_RGBA for OpenGL/ES. @@ -885,17 +897,11 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, const \sa size(), texture(), attachment() */ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attachment attachment, - GLenum target, GLenum internal_format) + GLenum target, GLenum internalFormat) : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); - if (!internal_format) -#ifdef QT_OPENGL_ES_2 - internal_format = GL_RGBA; -#else - internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; -#endif - d->init(this, QSize(width, height), attachment, target, internal_format); + d->init(this, QSize(width, height), attachment, target, effectiveInternalFormat(internalFormat)); } /*! \overload @@ -904,7 +910,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach buffer of the given \a size. The \a attachment parameter describes the depth/stencil buffer - configuration, \a target the texture target and \a internal_format + configuration, \a target the texture target and \a internalFormat the internal texture format. The default texture target is \c GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8 for desktop OpenGL and \c GL_RGBA for OpenGL/ES. @@ -912,17 +918,11 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach \sa size(), texture(), attachment() */ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment attachment, - GLenum target, GLenum internal_format) + GLenum target, GLenum internalFormat) : d_ptr(new QOpenGLFramebufferObjectPrivate) { Q_D(QOpenGLFramebufferObject); - if (!internal_format) -#ifdef QT_OPENGL_ES_2 - internal_format = GL_RGBA; -#else - internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; -#endif - d->init(this, size, attachment, target, internal_format); + d->init(this, size, attachment, target, effectiveInternalFormat(internalFormat)); } /*! @@ -936,10 +936,12 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject() if (isBound()) release(); - if (d->texture_guard) - d->texture_guard->free(); - if (d->color_buffer_guard) - d->color_buffer_guard->free(); + foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) { + if (color.guard) + color.guard->free(); + } + d->colorAttachments.clear(); + if (d->depth_buffer_guard) d->depth_buffer_guard->free(); if (d->stencil_buffer_guard && d->stencil_buffer_guard != d->depth_buffer_guard) @@ -949,6 +951,70 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject() } /*! + Creates and attaches an additional texture or renderbuffer of size \a width + and \a height. + + There is always an attachment at GL_COLOR_ATTACHMENT0. Call this function + to set up additional attachments at GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, ... + + When \a internalFormat is not \c 0, it specifies the internal format of the + texture or renderbuffer. Otherwise a default of GL_RGBA or GL_RGBA8 is + used. + + \note This is only functional when multiple render targets are supported by + the OpenGL implementation. When that is not the case, the function will not + add any additional color attachments. Call + QOpenGLFunctions::hasOpenGLFeature() with + QOpenGLFunctions::MultipleRenderTargets at runtime to check if MRT is + supported. + + \note The internal format of the color attachments may differ but there may + be limitations on the supported combinations, depending on the drivers. + + \note The size of the color attachments may differ but rendering is limited + to the area that fits all the attachments, according to the OpenGL + specification. Some drivers may not be fully conformant in this respect, + however. + + \since 5.6 + */ +void QOpenGLFramebufferObject::addColorAttachment(const QSize &size, GLenum internalFormat) +{ + Q_D(QOpenGLFramebufferObject); + + if (!QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { + qWarning("Multiple render targets not supported, ignoring extra color attachment request"); + return; + } + + QOpenGLFramebufferObjectPrivate::ColorAttachment color(size, effectiveInternalFormat(internalFormat)); + d->colorAttachments.append(color); + const int idx = d->colorAttachments.count() - 1; + + if (d->requestedSamples == 0) { + d->initTexture(idx); + } else { + GLint samples = d->requestedSamples; + d->initColorBuffer(idx, &samples); + } +} + +/*! \overload + + Creates and attaches an additional texture or renderbuffer of size \a width and \a height. + + When \a internalFormat is not \c 0, it specifies the internal format of the texture or + renderbuffer. Otherwise a default of GL_RGBA or GL_RGBA8 is used. + + \since 5.6 + */ +void QOpenGLFramebufferObject::addColorAttachment(int width, int height, GLenum internalFormat) +{ + addColorAttachment(QSize(width, height), internalFormat); +} + +/*! \fn bool QOpenGLFramebufferObject::isValid() const Returns \c true if the framebuffer object is valid. @@ -1002,10 +1068,16 @@ bool QOpenGLFramebufferObject::bind() QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true; - if (d->texture_guard || d->format.samples() != 0) - d->valid = d->checkFramebufferStatus(current); - else - d->initTexture(d->format.textureTarget(), d->format.internalTextureFormat(), d->size, d->format.mipmap()); + if (d->format.samples() == 0) { + // Create new textures to replace the ones stolen via takeTexture(). + for (int i = 0; i < d->colorAttachments.count(); ++i) { + if (!d->colorAttachments[i].guard) + d->initTexture(i); + } + } + + d->valid = d->checkFramebufferStatus(current); + return d->valid; } @@ -1052,12 +1124,36 @@ bool QOpenGLFramebufferObject::release() If a multisample framebuffer object is used then the value returned from this function will be invalid. - \sa takeTexture() + When multiple textures are attached, the return value is the ID of + the first one. + + \sa takeTexture(), textures() */ GLuint QOpenGLFramebufferObject::texture() const { Q_D(const QOpenGLFramebufferObject); - return d->texture_guard ? d->texture_guard->id() : 0; + return d->colorAttachments[0].guard ? d->colorAttachments[0].guard->id() : 0; +} + +/*! + Returns the texture id for all attached textures. + + If a multisample framebuffer object is used, then an empty vector is returned. + + \since 5.6 + + \sa takeTextures(), texture() +*/ +QVector<GLuint> QOpenGLFramebufferObject::textures() const +{ + Q_D(const QOpenGLFramebufferObject); + QVector<GLuint> ids; + if (d->format.samples() != 0) + return ids; + ids.reserve(d->colorAttachments.count()); + foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) + ids.append(color.guard ? color.guard->id() : 0); + return ids; } /*! @@ -1076,34 +1172,72 @@ GLuint QOpenGLFramebufferObject::texture() const \since 5.3 - \sa texture(), bind(), release() + \sa texture(), bind(), release(), takeTextures() */ GLuint QOpenGLFramebufferObject::takeTexture() { + return takeTexture(0); +} + +/*! \overload + + Returns the texture id for the texture attached to the color attachment of + index \a colorAttachmentIndex of this framebuffer object. The ownership of + the texture is transferred to the caller. + + When \a colorAttachmentIndex is \c 0, the behavior is identical to the + parameter-less variant of this function. + + If the framebuffer object is currently bound, an implicit release() + will be done. During the next call to bind() a new texture will be + created. + + If a multisample framebuffer object is used, then there is no + texture and the return value from this function will be invalid. + Similarly, incomplete framebuffer objects will also return 0. + + \since 5.6 + */ +GLuint QOpenGLFramebufferObject::takeTexture(int colorAttachmentIndex) +{ Q_D(QOpenGLFramebufferObject); GLuint id = 0; - if (isValid() && d->texture_guard) { + if (isValid() && d->format.samples() == 0 && d->colorAttachments.count() > colorAttachmentIndex) { QOpenGLContext *current = QOpenGLContext::currentContext(); if (current && current->shareGroup() == d->fbo_guard->group() && isBound()) release(); - id = d->texture_guard->id(); + id = d->colorAttachments[colorAttachmentIndex].guard ? d->colorAttachments[colorAttachmentIndex].guard->id() : 0; // Do not call free() on texture_guard, just null it out. // This way the texture will not be deleted when the guard is destroyed. - d->texture_guard = 0; + d->colorAttachments[colorAttachmentIndex].guard = 0; } return id; } /*! - \fn QSize QOpenGLFramebufferObject::size() const + \return the size of the color and depth/stencil attachments attached to + this framebuffer object. +*/ +QSize QOpenGLFramebufferObject::size() const +{ + Q_D(const QOpenGLFramebufferObject); + return d->dsSize; +} - Returns the size of the texture attached to this framebuffer +/*! + \return the sizes of all color attachments attached to this framebuffer object. + + \since 5.6 */ -QSize QOpenGLFramebufferObject::size() const +QVector<QSize> QOpenGLFramebufferObject::sizes() const { Q_D(const QOpenGLFramebufferObject); - return d->size; + QVector<QSize> sz; + sz.reserve(d->colorAttachments.size()); + foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) + sz.append(color.size); + return sz; } /*! @@ -1232,6 +1366,37 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, QImage QOpenGLFramebufferObject::toImage(bool flipped) const { + return toImage(flipped, 0); +} + +/*! + \fn QImage QOpenGLFramebufferObject::toImage() const + \overload + + Returns the contents of this framebuffer object as a QImage. This method flips + the image from OpenGL coordinates to raster coordinates. +*/ +// ### Qt 6: Remove this method and make it a default argument instead. +QImage QOpenGLFramebufferObject::toImage() const +{ + return toImage(true, 0); +} + +/*! \overload + + Returns the contents of the color attachment of index \a + colorAttachmentIndex of this framebuffer object as a QImage. This method + flips the image from OpenGL coordinates to raster coordinates when \a + flipped is set to \c true. + + \note This overload is only fully functional when multiple render targets are + supported by the OpenGL implementation. When that is not the case, only one + color attachment will be set up. + + \since 5.6 +*/ +QImage QOpenGLFramebufferObject::toImage(bool flipped, int colorAttachmentIndex) const +{ Q_D(const QOpenGLFramebufferObject); if (!d->valid) return QImage(); @@ -1242,6 +1407,11 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped) const return QImage(); } + if (d->colorAttachments.count() <= colorAttachmentIndex) { + qWarning("QOpenGLFramebufferObject::toImage() called for missing color attachment"); + return QImage(); + } + GLuint prevFbo = 0; ctx->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &prevFbo); @@ -1249,16 +1419,33 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped) const const_cast<QOpenGLFramebufferObject *>(this)->bind(); QImage image; + QOpenGLExtraFunctions *extraFuncs = ctx->extraFunctions(); // qt_gl_read_framebuffer doesn't work on a multisample FBO if (format().samples() != 0) { - QOpenGLFramebufferObject temp(size(), QOpenGLFramebufferObjectFormat()); - QRect rect(QPoint(0, 0), size()); - blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect); - - image = temp.toImage(flipped); + if (extraFuncs->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { + QOpenGLFramebufferObject temp(d->colorAttachments[colorAttachmentIndex].size, QOpenGLFramebufferObjectFormat()); + blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect, + GL_COLOR_BUFFER_BIT, GL_NEAREST, + colorAttachmentIndex, 0); + image = temp.toImage(flipped); + } else { + QOpenGLFramebufferObject temp(size(), QOpenGLFramebufferObjectFormat()); + blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect); + image = temp.toImage(flipped); + } } else { - image = qt_gl_read_framebuffer(d->size, format().internalTextureFormat(), true, flipped); + if (extraFuncs->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { + extraFuncs->glReadBuffer(GL_COLOR_ATTACHMENT0 + colorAttachmentIndex); + image = qt_gl_read_framebuffer(d->colorAttachments[colorAttachmentIndex].size, + d->colorAttachments[colorAttachmentIndex].internalFormat, + true, flipped); + extraFuncs->glReadBuffer(GL_COLOR_ATTACHMENT0); + } else { + image = qt_gl_read_framebuffer(d->colorAttachments[0].size, + d->colorAttachments[0].internalFormat, + true, flipped); + } } if (prevFbo != d->fbo()) @@ -1268,19 +1455,6 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped) const } /*! - \fn QImage QOpenGLFramebufferObject::toImage() const - \overload - - Returns the contents of this framebuffer object as a QImage. This method flips - the image from OpenGL coordinates to raster coordinates. -*/ -// ### Qt 6: Remove this method and make it a default argument instead. -QImage QOpenGLFramebufferObject::toImage() const -{ - return toImage(true); -} - -/*! \fn bool QOpenGLFramebufferObject::bindDefault() Switches rendering back to the default, windowing system provided @@ -1366,7 +1540,7 @@ void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachmen #endif d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo()); QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true; - d->initAttachments(current, attachment); + d->initDepthStencilAttachments(current, attachment); } /*! @@ -1428,6 +1602,18 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, buffers, filter); } +/*! \overload + * + Convenience overload to blit between two framebuffer objects. +*/ +void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, + QOpenGLFramebufferObject *source, const QRect &sourceRect, + GLbitfield buffers, + GLenum filter) +{ + blitFramebuffer(target, targetRect, source, sourceRect, buffers, filter, 0, 0); +} + /*! Blits from the \a sourceRect rectangle in the \a source framebuffer object to the \a targetRect rectangle in the \a target framebuffer object. @@ -1456,12 +1642,18 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, \note The scissor test will restrict the blit area if enabled. + When multiple render targets are in use, \a readColorAttachmentIndex and \a + drawColorAttachmentIndex specify the index of the color attachments in the + source and destination framebuffers. + \sa hasOpenGLFramebufferBlit() */ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, - QOpenGLFramebufferObject *source, const QRect &sourceRect, - GLbitfield buffers, - GLenum filter) + QOpenGLFramebufferObject *source, const QRect &sourceRect, + GLbitfield buffers, + GLenum filter, + int readColorAttachmentIndex, + int drawColorAttachmentIndex) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (!ctx) @@ -1489,10 +1681,21 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : defaultFboId); extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : defaultFboId); + if (extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { + extensions.glReadBuffer(GL_COLOR_ATTACHMENT0 + readColorAttachmentIndex); + if (target) { + GLenum drawBuf = GL_COLOR_ATTACHMENT0 + drawColorAttachmentIndex; + extensions.glDrawBuffers(1, &drawBuf); + } + } + extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1, tx0, ty0, tx1, ty1, buffers, filter); + if (extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) + extensions.glReadBuffer(GL_COLOR_ATTACHMENT0); + ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); // sets both READ and DRAW } diff --git a/src/gui/opengl/qopenglframebufferobject.h b/src/gui/opengl/qopenglframebufferobject.h index 4ce0ee26cb..cead4ad10f 100644 --- a/src/gui/opengl/qopenglframebufferobject.h +++ b/src/gui/opengl/qopenglframebufferobject.h @@ -63,15 +63,18 @@ public: QOpenGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D); QOpenGLFramebufferObject(const QSize &size, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0); + GLenum target = GL_TEXTURE_2D, GLenum internalFormat = 0); QOpenGLFramebufferObject(int width, int height, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0); + GLenum target = GL_TEXTURE_2D, GLenum internalFormat = 0); QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format); QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format); virtual ~QOpenGLFramebufferObject(); + void addColorAttachment(const QSize &size, GLenum internalFormat = 0); + void addColorAttachment(int width, int height, GLenum internalFormat = 0); + QOpenGLFramebufferObjectFormat format() const; bool isValid() const; @@ -83,12 +86,19 @@ public: int height() const { return size().height(); } GLuint texture() const; + QVector<GLuint> textures() const; + GLuint takeTexture(); + GLuint takeTexture(int colorAttachmentIndex); + QSize size() const; + QVector<QSize> sizes() const; + QImage toImage() const; QImage toImage(bool flipped) const; - Attachment attachment() const; + QImage toImage(bool flipped, int colorAttachmentIndex) const; + Attachment attachment() const; void setAttachment(Attachment attachment); GLuint handle() const; @@ -100,6 +110,12 @@ public: static bool hasOpenGLFramebufferBlit(); static void blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, QOpenGLFramebufferObject *source, const QRect &sourceRect, + GLbitfield buffers, + GLenum filter, + int readColorAttachmentIndex, + int drawColorAttachmentIndex); + static void blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, + QOpenGLFramebufferObject *source, const QRect &sourceRect, GLbitfield buffers = GL_COLOR_BUFFER_BIT, GLenum filter = GL_NEAREST); static void blitFramebuffer(QOpenGLFramebufferObject *target, diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h index 7f0068dfc4..6c45fda57f 100644 --- a/src/gui/opengl/qopenglframebufferobject_p.h +++ b/src/gui/opengl/qopenglframebufferobject_p.h @@ -102,32 +102,41 @@ public: class QOpenGLFramebufferObjectPrivate { public: - QOpenGLFramebufferObjectPrivate() : fbo_guard(0), texture_guard(0), depth_buffer_guard(0) - , stencil_buffer_guard(0), color_buffer_guard(0) + QOpenGLFramebufferObjectPrivate() : fbo_guard(0), depth_buffer_guard(0) + , stencil_buffer_guard(0) , valid(false) {} ~QOpenGLFramebufferObjectPrivate() {} - void init(QOpenGLFramebufferObject *q, const QSize& sz, + void init(QOpenGLFramebufferObject *q, const QSize &size, QOpenGLFramebufferObject::Attachment attachment, - GLenum internal_format, GLenum texture_target, + GLenum texture_target, GLenum internal_format, GLint samples = 0, bool mipmap = false); - void initTexture(GLenum target, GLenum internal_format, const QSize &size, bool mipmap); - void initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment); + void initTexture(int idx); + void initColorBuffer(int idx, GLint *samples); + void initDepthStencilAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment); bool checkFramebufferStatus(QOpenGLContext *ctx) const; QOpenGLSharedResourceGuard *fbo_guard; - QOpenGLSharedResourceGuard *texture_guard; QOpenGLSharedResourceGuard *depth_buffer_guard; QOpenGLSharedResourceGuard *stencil_buffer_guard; - QOpenGLSharedResourceGuard *color_buffer_guard; GLenum target; - QSize size; + QSize dsSize; QOpenGLFramebufferObjectFormat format; int requestedSamples; uint valid : 1; QOpenGLFramebufferObject::Attachment fbo_attachment; QOpenGLExtensions funcs; + struct ColorAttachment { + ColorAttachment() : internalFormat(0), guard(0) { } + ColorAttachment(const QSize &size, GLenum internalFormat) + : size(size), internalFormat(internalFormat), guard(0) { } + QSize size; + GLenum internalFormat; + QOpenGLSharedResourceGuard *guard; + }; + QVector<ColorAttachment> colorAttachments; + inline GLuint fbo() const { return fbo_guard ? fbo_guard->id() : 0; } }; diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 8ddb693e73..d614ad8401 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -32,12 +32,14 @@ ****************************************************************************/ #include "qopenglfunctions.h" +#include "qopenglextrafunctions.h" #include "qopenglextensions_p.h" #include "qdebug.h" #include <QtGui/private/qopenglcontext_p.h> #include <QtGui/private/qopengl_p.h> #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> +#include <QtCore/qloggingcategory.h> #ifdef Q_OS_IOS #include <dlfcn.h> @@ -49,6 +51,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcGLES3, "qt.opengl.es3") + /*! \class QOpenGLFunctions \brief The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API. @@ -155,6 +159,8 @@ QT_BEGIN_NAMESPACE QOpenGLFunctions funcs(QOpenGLContext::currentContext()); bool npot = funcs.hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); \endcode + + \sa QOpenGLContext, QSurfaceFormat */ /*! @@ -178,6 +184,7 @@ QT_BEGIN_NAMESPACE \value NPOTTextureRepeat Non power of two textures can use GL_REPEAT as wrap parameter. \value FixedFunctionPipeline The fixed function pipeline is available. \value TextureRGFormats The GL_RED and GL_RG texture formats are available. + \value MultipleRenderTargets Multiple color attachments to framebuffer objects are available. */ // Hidden private fields for additional extension data. @@ -251,12 +258,11 @@ QOpenGLFunctions::QOpenGLFunctions(QOpenGLContext *context) } QOpenGLExtensions::QOpenGLExtensions() - : QOpenGLFunctions() { } QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context) - : QOpenGLFunctions(context) + : QOpenGLExtraFunctions(context) { } @@ -270,7 +276,7 @@ static int qt_gl_resolve_features() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (ctx->isOpenGLES()) { - // OpenGL ES 2 + // OpenGL ES int features = QOpenGLFunctions::Multitexture | QOpenGLFunctions::Shaders | QOpenGLFunctions::Buffers | @@ -295,6 +301,8 @@ static int qt_gl_resolve_features() if (!(renderer && strstr(renderer, "Mesa"))) features |= QOpenGLFunctions::TextureRGFormats; } + if (ctx->format().majorVersion() >= 3) + features |= QOpenGLFunctions::MultipleRenderTargets; return features; } else { // OpenGL @@ -303,10 +311,9 @@ static int qt_gl_resolve_features() QOpenGLExtensionMatcher extensions; if (format.majorVersion() >= 3) - features |= QOpenGLFunctions::Framebuffers; - else if (extensions.match("GL_EXT_framebuffer_object") || - extensions.match("GL_ARB_framebuffer_object")) - features |= QOpenGLFunctions::Framebuffers; + features |= QOpenGLFunctions::Framebuffers | QOpenGLFunctions::MultipleRenderTargets; + else if (extensions.match("GL_EXT_framebuffer_object") || extensions.match("GL_ARB_framebuffer_object")) + features |= QOpenGLFunctions::Framebuffers | QOpenGLFunctions::MultipleRenderTargets; if (format.majorVersion() >= 2) { features |= QOpenGLFunctions::BlendColor | @@ -423,11 +430,14 @@ static int qt_gl_resolve_extensions() // We don't match GL_APPLE_texture_format_BGRA8888 here because it has different semantics. if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888")) extensions |= QOpenGLExtensions::BGRATextureFormat; - if (extensionMatcher.match("GL_EXT_discard_framebuffer")) extensions |= QOpenGLExtensions::DiscardFramebuffer; + if (extensionMatcher.match("GL_EXT_texture_norm16")) + extensions |= QOpenGLExtensions::Sized16Formats; } else { - extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer; + extensions |= QOpenGLExtensions::ElementIndexUint + | QOpenGLExtensions::MapBuffer + | QOpenGLExtensions::Sized16Formats; if (format.version() >= qMakePair(1, 2)) extensions |= QOpenGLExtensions::BGRATextureFormat; @@ -2121,6 +2131,9 @@ public: template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10); + template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11> + ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11); + private: FuncType Base::*funcPointerName; FuncType fallbackFuncPointer; @@ -2172,6 +2185,9 @@ public: template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10); + template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11> + void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11); + private: FuncType Base::*funcPointerName; FuncType fallbackFuncPointer; @@ -2421,6 +2437,14 @@ void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } +template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11> +void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) +{ + RESOLVER_COMMON_VOID + + (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); +} + template <typename ReturnType, int Policy, typename Base, typename FuncType> Resolver<Base, FuncType, Policy, ReturnType> functionResolverWithFallback(FuncType Base::*func, FuncType fallback, const char *name, const char *alternate = 0) { @@ -2433,7 +2457,7 @@ Resolver<Base, FuncType, Policy, ReturnType> functionResolver(FuncType Base::*fu return Resolver<Base, FuncType, Policy, ReturnType>(func, 0, name, alternate); } -} +} // namespace #define RESOLVE_FUNC(RETURN_TYPE, POLICY, NAME) \ return functionResolver<RETURN_TYPE, POLICY>(&QOpenGLExtensionsPrivate::NAME, "gl" #NAME) @@ -3201,79 +3225,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribPointer(GLuint indx, GL #endif // !QT_OPENGL_ES_2 -// Functions part of the OpenGL ES 3.0+ standard need special handling. These, -// just like the 2.0 functions, are not guaranteed to be resolvable via -// eglGetProcAddress or similar. Calling them directly is, unlike the 2.0 -// functions, not feasible because one may build the binaries on a GLES3-capable -// system and then deploy on a GLES2-only system that does not have these -// symbols. Until ES3 gets universally available, they have to be dlsym'ed. - -Q_GLOBAL_STATIC(QOpenGLES3Helper, qgles3Helper) - -bool QOpenGLES3Helper::init() -{ -#ifndef Q_OS_IOS -# ifdef Q_OS_WIN -# ifndef QT_DEBUG - m_gl.setFileName(QStringLiteral("libGLESv2")); -# else - m_gl.setFileName(QStringLiteral("libGLESv2d")); -# endif -# else -# ifdef Q_OS_ANDROID - m_gl.setFileName(QStringLiteral("GLESv2")); -# else - m_gl.setFileNameAndVersion(QStringLiteral("GLESv2"), 2); -# endif -# endif // Q_OS_WIN - return m_gl.load(); -#else - return true; -#endif // Q_OS_IOS -} - -QFunctionPointer QOpenGLES3Helper::resolve(const char *name) -{ -#ifdef Q_OS_IOS - return QFunctionPointer(dlsym(RTLD_DEFAULT, name)); -#else - return m_gl.resolve(name); -#endif -} - -QOpenGLES3Helper::QOpenGLES3Helper() -{ - if (init()) { - MapBufferRange = (GLvoid* (QOPENGLF_APIENTRYP)(GLenum, qopengl_GLintptr, qopengl_GLsizeiptr, GLbitfield)) resolve("glMapBufferRange"); - UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP)(GLenum)) resolve("glUnmapBuffer"); - BlitFramebuffer = (void (QOPENGLF_APIENTRYP)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) resolve("glBlitFramebuffer"); - RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glRenderbufferStorageMultisample"); - - GenVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, GLuint *)) resolve("glGenVertexArrays"); - DeleteVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, const GLuint *)) resolve("glDeleteVertexArrays"); - BindVertexArray = (void (QOPENGLF_APIENTRYP)(GLuint)) resolve("glBindVertexArray"); - IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP)(GLuint)) resolve("glIsVertexArray"); - - TexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) resolve("glTexImage3D"); - TexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) resolve("glTexSubImage3D"); - CompressedTexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) resolve("glCompressedTexImage3D"); - CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) resolve("glCompressedTexSubImage3D"); - - TexStorage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei)) resolve("glTexStorage3D"); - TexStorage2D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glTexStorage2D"); - - if (!MapBufferRange || !GenVertexArrays || !TexImage3D || !TexStorage3D) - qFatal("OpenGL ES 3.0 entry points not found"); - } else { - qFatal("Failed to load libGLESv2"); - } -} - -static inline bool isES3() -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - return ctx->isOpenGLES() && ctx->format().majorVersion() >= 3; -} +// Extensions not standard in any ES version static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum access) { @@ -3281,7 +3233,8 @@ static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum // differentiate between glUnmapBufferOES and glUnmapBuffer causes extra // headache. QOpenGLBuffer::map() will handle this automatically, while direct // calls are better off with migrating to the standard glMapBufferRange. - if (isES3()) { + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) { qWarning("QOpenGLFunctions: glMapBuffer is not available in OpenGL ES 3.0 and up. Use glMapBufferRange instead."); return 0; } else { @@ -3289,44 +3242,6 @@ static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum } } -static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access) -{ - if (isES3()) - return qgles3Helper()->MapBufferRange(target, offset, length, access); - else - RESOLVE_FUNC(GLvoid *, 0, MapBufferRange)(target, offset, length, access); -} - -static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target) -{ - if (isES3()) - return qgles3Helper()->UnmapBuffer(target); - else - RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target); -} - -static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - if (isES3()) - qgles3Helper()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - else - RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer) - (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); -} - -static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples, - GLenum internalFormat, - GLsizei width, GLsizei height) -{ - if (isES3()) - qgles3Helper()->RenderbufferStorageMultisample(target, samples, internalFormat, width, height); - else - RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample) - (target, samples, internalFormat, width, height); -} - static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data) { RESOLVE_FUNC_VOID(ResolveEXT, GetBufferSubData) @@ -3567,15 +3482,4129 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) #endif // !QT_OPENGL_ES_2 } -QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx) - : QOpenGLFunctionsPrivate(ctx), - flushVendorChecked(false) +/*! + \class QOpenGLExtraFunctions + \brief The QOpenGLExtraFunctions class provides cross-platform access to the OpenGL ES 3.0 and 3.1 API. + \since 5.6 + \ingroup painting-3D + \inmodule QtGui + + This subclass of QOpenGLFunctions includes the OpenGL ES 3.0 and 3.1 + functions. These will only work when an OpenGL ES 3.0 or 3.1 context, or an + OpenGL context of a version containing the functions in question either in + core or as extension, is in use. This allows developing GLES 3.0 and 3.1 + applications in a cross-platform manner: development can happen on a desktop + platform with OpenGL 3.x or 4.x, deploying to a real GLES 3.1 device later + on will require no or minimal changes to the application. + + \note This class is different from the versioned OpenGL wrappers, for + instance QOpenGLFunctions_3_2_Core. The versioned function wrappers target a + given version and profile of OpenGL. They are therefore not suitable for + cross-OpenGL-OpenGLES development. + */ + +/*! + \fn void QOpenGLExtraFunctions::glBeginQuery(GLenum target, GLuint id) + + Convenience function that calls glBeginQuery(\a target, \a id). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBeginQuery.xml}{glBeginQuery()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBeginTransformFeedback(GLenum primitiveMode) + + Convenience function that calls glBeginTransformFeedback(\a primitiveMode). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBeginTransformFeedback.xml}{glBeginTransformFeedback()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindBufferBase(GLenum target, GLuint index, GLuint buffer) + + Convenience function that calls glBindBufferBase(\a target, \a index, \a buffer). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindBufferBase.xml}{glBindBufferBase()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) + + Convenience function that calls glBindBufferRange(\a target, \a index, \a buffer, \a offset, \a size). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindBufferRange.xml}{glBindBufferRange()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindSampler(GLuint unit, GLuint sampler) + + Convenience function that calls glBindSampler(\a unit, \a sampler). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindSampler.xml}{glBindSampler()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindTransformFeedback(GLenum target, GLuint id) + + Convenience function that calls glBindTransformFeedback(\a target, \a id). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindTransformFeedback.xml}{glBindTransformFeedback()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindVertexArray(GLuint array) + + Convenience function that calls glBindVertexArray(\a array). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindVertexArray.xml}{glBindVertexArray()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) + + Convenience function that calls glBlitFramebuffer(\a srcX0, \a srcY0, \a srcX1, \a srcY1, \a dstX0, \a dstY0, \a dstX1, \a dstY1, \a mask, \a filter). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBlitFramebuffer.xml}{glBlitFramebuffer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) + + Convenience function that calls glClearBufferfi(\a buffer, \a drawbuffer, \a depth, \a stencil). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferfi.xml}{glClearBufferfi()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value) + + Convenience function that calls glClearBufferfv(\a buffer, \a drawbuffer, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferfv.xml}{glClearBufferfv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value) + + Convenience function that calls glClearBufferiv(\a buffer, \a drawbuffer, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferiv.xml}{glClearBufferiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value) + + Convenience function that calls glClearBufferuiv(\a buffer, \a drawbuffer, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClearBufferuiv.xml}{glClearBufferuiv()}. +*/ + +/*! + \fn GLenum QOpenGLExtraFunctions::glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) + + Convenience function that calls glClientWaitSync(\a sync, \a flags, \a timeout). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glClientWaitSync.xml}{glClientWaitSync()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data) + + Convenience function that calls glCompressedTexImage3D(\a target, \a level, \a internalformat, \a width, \a height, \a depth, \a border, \a imageSize, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCompressedTexImage3D.xml}{glCompressedTexImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data) + + Convenience function that calls glCompressedTexSubImage3D(\a target, \a level, \a xoffset, \a yoffset, \a zoffset, \a width, \a height, \a depth, \a format, \a imageSize, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCompressedTexSubImage3D.xml}{glCompressedTexSubImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) + + Convenience function that calls glCopyBufferSubData(\a readTarget, \a writeTarget, \a readOffset, \a writeOffset, \a size). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCopyBufferSubData.xml}{glCopyBufferSubData()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) + + Convenience function that calls glCopyTexSubImage3D(\a target, \a level, \a xoffset, \a yoffset, \a zoffset, \a x, \a y, \a width, \a height). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCopyTexSubImage3D.xml}{glCopyTexSubImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteQueries(GLsizei n, const GLuint * ids) + + Convenience function that calls glDeleteQueries(\a n, \a ids). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteQueries.xml}{glDeleteQueries()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteSamplers(GLsizei count, const GLuint * samplers) + + Convenience function that calls glDeleteSamplers(\a count, \a samplers). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteSamplers.xml}{glDeleteSamplers()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteSync(GLsync sync) + + Convenience function that calls glDeleteSync(\a sync). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteSync.xml}{glDeleteSync()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteTransformFeedbacks(GLsizei n, const GLuint * ids) + + Convenience function that calls glDeleteTransformFeedbacks(\a n, \a ids). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteTransformFeedbacks.xml}{glDeleteTransformFeedbacks()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteVertexArrays(GLsizei n, const GLuint * arrays) + + Convenience function that calls glDeleteVertexArrays(\a n, \a arrays). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteVertexArrays.xml}{glDeleteVertexArrays()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) + + Convenience function that calls glDrawArraysInstanced(\a mode, \a first, \a count, \a instancecount). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawArraysInstanced.xml}{glDrawArraysInstanced()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawBuffers(GLsizei n, const GLenum * bufs) + + Convenience function that calls glDrawBuffers(\a n, \a bufs). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawBuffers.xml}{glDrawBuffers()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount) + + Convenience function that calls glDrawElementsInstanced(\a mode, \a count, \a type, \a indices, \a instancecount). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawElementsInstanced.xml}{glDrawElementsInstanced()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices) + + Convenience function that calls glDrawRangeElements(\a mode, \a start, \a end, \a count, \a type, \a indices). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawRangeElements.xml}{glDrawRangeElements()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glEndQuery(GLenum target) + + Convenience function that calls glEndQuery(\a target). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glEndQuery.xml}{glEndQuery()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glEndTransformFeedback(void) + + Convenience function that calls glEndTransformFeedback(). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glEndTransformFeedback.xml}{glEndTransformFeedback()}. +*/ + +/*! + \fn GLsync QOpenGLExtraFunctions::glFenceSync(GLenum condition, GLbitfield flags) + + Convenience function that calls glFenceSync(\a condition, \a flags). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glFenceSync.xml}{glFenceSync()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) + + Convenience function that calls glFlushMappedBufferRange(\a target, \a offset, \a length). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glFlushMappedBufferRange.xml}{glFlushMappedBufferRange()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) + + Convenience function that calls glFramebufferTextureLayer(\a target, \a attachment, \a texture, \a level, \a layer). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glFramebufferTextureLayer.xml}{glFramebufferTextureLayer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenQueries(GLsizei n, GLuint* ids) + + Convenience function that calls glGenQueries(\a n, \a ids). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenQueries.xml}{glGenQueries()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenSamplers(GLsizei count, GLuint* samplers) + + Convenience function that calls glGenSamplers(\a count, \a samplers). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenSamplers.xml}{glGenSamplers()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenTransformFeedbacks(GLsizei n, GLuint* ids) + + Convenience function that calls glGenTransformFeedbacks(\a n, \a ids). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenTransformFeedbacks.xml}{glGenTransformFeedbacks()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenVertexArrays(GLsizei n, GLuint* arrays) + + Convenience function that calls glGenVertexArrays(\a n, \a arrays). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenVertexArrays.xml}{glGenVertexArrays()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) + + Convenience function that calls glGetActiveUniformBlockName(\a program, \a uniformBlockIndex, \a bufSize, \a length, \a uniformBlockName). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetActiveUniformBlockName.xml}{glGetActiveUniformBlockName()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) + + Convenience function that calls glGetActiveUniformBlockiv(\a program, \a uniformBlockIndex, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetActiveUniformBlockiv.xml}{glGetActiveUniformBlockiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint* params) + + Convenience function that calls glGetActiveUniformsiv(\a program, \a uniformCount, \a uniformIndices, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetActiveUniformsiv.xml}{glGetActiveUniformsiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) + + Convenience function that calls glGetBufferParameteri64v(\a target, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetBufferParameteri64v.xml}{glGetBufferParameteri64v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetBufferPointerv(GLenum target, GLenum pname, void ** params) + + Convenience function that calls glGetBufferPointerv(\a target, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetBufferPointerv.xml}{glGetBufferPointerv()}. +*/ + +/*! + \fn GLint QOpenGLExtraFunctions::glGetFragDataLocation(GLuint program, const GLchar * name) + + Convenience function that calls glGetFragDataLocation(\a program, \a name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetFragDataLocation.xml}{glGetFragDataLocation()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) + + Convenience function that calls glGetInteger64i_v(\a target, \a index, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetInteger64i_v.xml}{glGetInteger64i_v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetInteger64v(GLenum pname, GLint64* data) + + Convenience function that calls glGetInteger64v(\a pname, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetInteger64v.xml}{glGetInteger64v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetIntegeri_v(GLenum target, GLuint index, GLint* data) + + Convenience function that calls glGetIntegeri_v(\a target, \a index, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetIntegeri_v.xml}{glGetIntegeri_v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) + + Convenience function that calls glGetInternalformativ(\a target, \a internalformat, \a pname, \a bufSize, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetInternalformativ.xml}{glGetInternalformativ()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void * binary) + + Convenience function that calls glGetProgramBinary(\a program, \a bufSize, \a length, \a binaryFormat, \a binary). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramBinary.xml}{glGetProgramBinary()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) + + Convenience function that calls glGetQueryObjectuiv(\a id, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetQueryObjectuiv.xml}{glGetQueryObjectuiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetQueryiv(GLenum target, GLenum pname, GLint* params) + + Convenience function that calls glGetQueryiv(\a target, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetQueryiv.xml}{glGetQueryiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) + + Convenience function that calls glGetSamplerParameterfv(\a sampler, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetSamplerParameterfv.xml}{glGetSamplerParameterfv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) + + Convenience function that calls glGetSamplerParameteriv(\a sampler, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetSamplerParameteriv.xml}{glGetSamplerParameteriv()}. +*/ + +/*! + \fn const GLubyte * QOpenGLExtraFunctions::glGetStringi(GLenum name, GLuint index) + + Convenience function that calls glGetStringi(\a name, \a index). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetStringi.xml}{glGetStringi()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) + + Convenience function that calls glGetSynciv(\a sync, \a pname, \a bufSize, \a length, \a values). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetSynciv.xml}{glGetSynciv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) + + Convenience function that calls glGetTransformFeedbackVarying(\a program, \a index, \a bufSize, \a length, \a size, \a type, \a name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetTransformFeedbackVarying.xml}{glGetTransformFeedbackVarying()}. +*/ + +/*! + \fn GLuint QOpenGLExtraFunctions::glGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName) + + Convenience function that calls glGetUniformBlockIndex(\a program, \a uniformBlockName). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetUniformBlockIndex.xml}{glGetUniformBlockIndex()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint* uniformIndices) + + Convenience function that calls glGetUniformIndices(\a program, \a uniformCount, \a uniformNames, \a uniformIndices). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetUniformIndices.xml}{glGetUniformIndices()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetUniformuiv(GLuint program, GLint location, GLuint* params) + + Convenience function that calls glGetUniformuiv(\a program, \a location, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetUniformuiv.xml}{glGetUniformuiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) + + Convenience function that calls glGetVertexAttribIiv(\a index, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetVertexAttribIiv.xml}{glGetVertexAttribIiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) + + Convenience function that calls glGetVertexAttribIuiv(\a index, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetVertexAttribIuiv.xml}{glGetVertexAttribIuiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments) + + Convenience function that calls glInvalidateFramebuffer(\a target, \a numAttachments, \a attachments). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glInvalidateFramebuffer.xml}{glInvalidateFramebuffer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) + + Convenience function that calls glInvalidateSubFramebuffer(\a target, \a numAttachments, \a attachments, \a x, \a y, \a width, \a height). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glInvalidateSubFramebuffer.xml}{glInvalidateSubFramebuffer()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsQuery(GLuint id) + + Convenience function that calls glIsQuery(\a id). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsQuery.xml}{glIsQuery()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsSampler(GLuint sampler) + + Convenience function that calls glIsSampler(\a sampler). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsSampler.xml}{glIsSampler()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsSync(GLsync sync) + + Convenience function that calls glIsSync(\a sync). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsSync.xml}{glIsSync()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsTransformFeedback(GLuint id) + + Convenience function that calls glIsTransformFeedback(\a id). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsTransformFeedback.xml}{glIsTransformFeedback()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsVertexArray(GLuint array) + + Convenience function that calls glIsVertexArray(\a array). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsVertexArray.xml}{glIsVertexArray()}. +*/ + +/*! + \fn void * QOpenGLExtraFunctions::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) + + Convenience function that calls glMapBufferRange(\a target, \a offset, \a length, \a access). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glMapBufferRange.xml}{glMapBufferRange()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glPauseTransformFeedback(void) + + Convenience function that calls glPauseTransformFeedback(). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glPauseTransformFeedback.xml}{glPauseTransformFeedback()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramBinary(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length) + + Convenience function that calls glProgramBinary(\a program, \a binaryFormat, \a binary, \a length). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramBinary.xml}{glProgramBinary()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramParameteri(GLuint program, GLenum pname, GLint value) + + Convenience function that calls glProgramParameteri(\a program, \a pname, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramParameteri.xml}{glProgramParameteri()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glReadBuffer(GLenum src) + + Convenience function that calls glReadBuffer(\a src). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glReadBuffer.xml}{glReadBuffer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) + + Convenience function that calls glRenderbufferStorageMultisample(\a target, \a samples, \a internalformat, \a width, \a height). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glRenderbufferStorageMultisample.xml}{glRenderbufferStorageMultisample()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glResumeTransformFeedback(void) + + Convenience function that calls glResumeTransformFeedback(). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glResumeTransformFeedback.xml}{glResumeTransformFeedback()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) + + Convenience function that calls glSamplerParameterf(\a sampler, \a pname, \a param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameterf.xml}{glSamplerParameterf()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat * param) + + Convenience function that calls glSamplerParameterfv(\a sampler, \a pname, \a param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameterfv.xml}{glSamplerParameterfv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) + + Convenience function that calls glSamplerParameteri(\a sampler, \a pname, \a param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameteri.xml}{glSamplerParameteri()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint * param) + + Convenience function that calls glSamplerParameteriv(\a sampler, \a pname, \a param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSamplerParameteriv.xml}{glSamplerParameteriv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels) + + Convenience function that calls glTexImage3D(\a target, \a level, \a internalformat, \a width, \a height, \a depth, \a border, \a format, \a type, \a pixels). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexImage3D.xml}{glTexImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) + + Convenience function that calls glTexStorage2D(\a target, \a levels, \a internalformat, \a width, \a height). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexStorage2D.xml}{glTexStorage2D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) + + Convenience function that calls glTexStorage3D(\a target, \a levels, \a internalformat, \a width, \a height, \a depth). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexStorage3D.xml}{glTexStorage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels) + + Convenience function that calls glTexSubImage3D(\a target, \a level, \a xoffset, \a yoffset, \a zoffset, \a width, \a height, \a depth, \a format, \a type, \a pixels). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexSubImage3D.xml}{glTexSubImage3D()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode) + + Convenience function that calls glTransformFeedbackVaryings(\a program, \a count, \a varyings, \a bufferMode). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTransformFeedbackVaryings.xml}{glTransformFeedbackVaryings()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform1ui(GLint location, GLuint v0) + + Convenience function that calls glUniform1ui(\a location, \a v0). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform1ui.xml}{glUniform1ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform1uiv(GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glUniform1uiv(\a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform1uiv.xml}{glUniform1uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform2ui(GLint location, GLuint v0, GLuint v1) + + Convenience function that calls glUniform2ui(\a location, \a v0, \a v1). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform2ui.xml}{glUniform2ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform2uiv(GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glUniform2uiv(\a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform2uiv.xml}{glUniform2uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) + + Convenience function that calls glUniform3ui(\a location, \a v0, \a v1, \a v2). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform3ui.xml}{glUniform3ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform3uiv(GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glUniform3uiv(\a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform3uiv.xml}{glUniform3uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) + + Convenience function that calls glUniform4ui(\a location, \a v0, \a v1, \a v2, \a v3). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform4ui.xml}{glUniform4ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniform4uiv(GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glUniform4uiv(\a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniform4uiv.xml}{glUniform4uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) + + Convenience function that calls glUniformBlockBinding(\a program, \a uniformBlockIndex, \a uniformBlockBinding). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformBlockBinding.xml}{glUniformBlockBinding()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix2x3fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix2x3fv.xml}{glUniformMatrix2x3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix2x4fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix2x4fv.xml}{glUniformMatrix2x4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix3x2fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix3x2fv.xml}{glUniformMatrix3x2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix3x4fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix3x4fv.xml}{glUniformMatrix3x4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix4x2fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix4x2fv.xml}{glUniformMatrix4x2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glUniformMatrix4x3fv(\a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUniformMatrix4x3fv.xml}{glUniformMatrix4x3fv()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glUnmapBuffer(GLenum target) + + Convenience function that calls glUnmapBuffer(\a target). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUnmapBuffer.xml}{glUnmapBuffer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribDivisor(GLuint index, GLuint divisor) + + Convenience function that calls glVertexAttribDivisor(\a index, \a divisor). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribDivisor.xml}{glVertexAttribDivisor()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) + + Convenience function that calls glVertexAttribI4i(\a index, \a x, \a y, \a z, \a w). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4i.xml}{glVertexAttribI4i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribI4iv(GLuint index, const GLint * v) + + Convenience function that calls glVertexAttribI4iv(\a index, \a v). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4iv.xml}{glVertexAttribI4iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) + + Convenience function that calls glVertexAttribI4ui(\a index, \a x, \a y, \a z, \a w). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4ui.xml}{glVertexAttribI4ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribI4uiv(GLuint index, const GLuint * v) + + Convenience function that calls glVertexAttribI4uiv(\a index, \a v). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribI4uiv.xml}{glVertexAttribI4uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) + + Convenience function that calls glVertexAttribIPointer(\a index, \a size, \a type, \a stride, \a pointer). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribIPointer.xml}{glVertexAttribIPointer()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) + + Convenience function that calls glWaitSync(\a sync, \a flags, \a timeout). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glWaitSync.xml}{glWaitSync()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glActiveShaderProgram(GLuint pipeline, GLuint program) + + Convenience function that calls glActiveShaderProgram(\a pipeline, \a program). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glActiveShaderProgram.xml}{glActiveShaderProgram()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) + + Convenience function that calls glBindImageTexture(\a unit, \a texture, \a level, \a layered, \a layer, \a access, \a format). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindImageTexture.xml}{glBindImageTexture()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindProgramPipeline(GLuint pipeline) + + Convenience function that calls glBindProgramPipeline(\a pipeline). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindProgramPipeline.xml}{glBindProgramPipeline()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) + + Convenience function that calls glBindVertexBuffer(\a bindingindex, \a buffer, \a offset, \a stride). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glBindVertexBuffer.xml}{glBindVertexBuffer()}. +*/ + +/*! + \fn GLuint QOpenGLExtraFunctions::glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const* strings) + + Convenience function that calls glCreateShaderProgramv(\a type, \a count, \a strings). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glCreateShaderProgramv.xml}{glCreateShaderProgramv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDeleteProgramPipelines(GLsizei n, const GLuint * pipelines) + + Convenience function that calls glDeleteProgramPipelines(\a n, \a pipelines). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDeleteProgramPipelines.xml}{glDeleteProgramPipelines()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) + + Convenience function that calls glDispatchCompute(\a num_groups_x, \a num_groups_y, \a num_groups_z). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDispatchCompute.xml}{glDispatchCompute()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDispatchComputeIndirect(GLintptr indirect) + + Convenience function that calls glDispatchComputeIndirect(\a indirect). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDispatchComputeIndirect.xml}{glDispatchComputeIndirect()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawArraysIndirect(GLenum mode, const void * indirect) + + Convenience function that calls glDrawArraysIndirect(\a mode, \a indirect). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawArraysIndirect.xml}{glDrawArraysIndirect()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect) + + Convenience function that calls glDrawElementsIndirect(\a mode, \a type, \a indirect). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glDrawElementsIndirect.xml}{glDrawElementsIndirect()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glFramebufferParameteri(GLenum target, GLenum pname, GLint param) + + Convenience function that calls glFramebufferParameteri(\a target, \a pname, \a param). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glFramebufferParameteri.xml}{glFramebufferParameteri()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGenProgramPipelines(GLsizei n, GLuint* pipelines) + + Convenience function that calls glGenProgramPipelines(\a n, \a pipelines). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGenProgramPipelines.xml}{glGenProgramPipelines()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetBooleani_v(GLenum target, GLuint index, GLboolean* data) + + Convenience function that calls glGetBooleani_v(\a target, \a index, \a data). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetBooleani_v.xml}{glGetBooleani_v()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params) + + Convenience function that calls glGetFramebufferParameteriv(\a target, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetFramebufferParameteriv.xml}{glGetFramebufferParameteriv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val) + + Convenience function that calls glGetMultisamplefv(\a pname, \a index, \a val). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetMultisamplefv.xml}{glGetMultisamplefv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params) + + Convenience function that calls glGetProgramInterfaceiv(\a program, \a programInterface, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramInterfaceiv.xml}{glGetProgramInterfaceiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) + + Convenience function that calls glGetProgramPipelineInfoLog(\a pipeline, \a bufSize, \a length, \a infoLog). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramPipelineInfoLog.xml}{glGetProgramPipelineInfoLog()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params) + + Convenience function that calls glGetProgramPipelineiv(\a pipeline, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramPipelineiv.xml}{glGetProgramPipelineiv()}. +*/ + +/*! + \fn GLuint QOpenGLExtraFunctions::glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name) + + Convenience function that calls glGetProgramResourceIndex(\a program, \a programInterface, \a name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceIndex.xml}{glGetProgramResourceIndex()}. +*/ + +/*! + \fn GLint QOpenGLExtraFunctions::glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name) + + Convenience function that calls glGetProgramResourceLocation(\a program, \a programInterface, \a name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceLocation.xml}{glGetProgramResourceLocation()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) + + Convenience function that calls glGetProgramResourceName(\a program, \a programInterface, \a index, \a bufSize, \a length, \a name). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceName.xml}{glGetProgramResourceName()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei* length, GLint* params) + + Convenience function that calls glGetProgramResourceiv(\a program, \a programInterface, \a index, \a propCount, \a props, \a bufSize, \a length, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetProgramResourceiv.xml}{glGetProgramResourceiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params) + + Convenience function that calls glGetTexLevelParameterfv(\a target, \a level, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetTexLevelParameterfv.xml}{glGetTexLevelParameterfv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params) + + Convenience function that calls glGetTexLevelParameteriv(\a target, \a level, \a pname, \a params). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glGetTexLevelParameteriv.xml}{glGetTexLevelParameteriv()}. +*/ + +/*! + \fn GLboolean QOpenGLExtraFunctions::glIsProgramPipeline(GLuint pipeline) + + Convenience function that calls glIsProgramPipeline(\a pipeline). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glIsProgramPipeline.xml}{glIsProgramPipeline()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glMemoryBarrier(GLbitfield barriers) + + Convenience function that calls glMemoryBarrier(\a barriers). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glMemoryBarrier.xml}{glMemoryBarrier()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glMemoryBarrierByRegion(GLbitfield barriers) + + Convenience function that calls glMemoryBarrierByRegion(\a barriers). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glMemoryBarrierByRegion.xml}{glMemoryBarrierByRegion()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1f(GLuint program, GLint location, GLfloat v0) + + Convenience function that calls glProgramUniform1f(\a program, \a location, \a v0). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1f.xml}{glProgramUniform1f()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) + + Convenience function that calls glProgramUniform1fv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1fv.xml}{glProgramUniform1fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1i(GLuint program, GLint location, GLint v0) + + Convenience function that calls glProgramUniform1i(\a program, \a location, \a v0). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1i.xml}{glProgramUniform1i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint * value) + + Convenience function that calls glProgramUniform1iv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1iv.xml}{glProgramUniform1iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1ui(GLuint program, GLint location, GLuint v0) + + Convenience function that calls glProgramUniform1ui(\a program, \a location, \a v0). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1ui.xml}{glProgramUniform1ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glProgramUniform1uiv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform1uiv.xml}{glProgramUniform1uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) + + Convenience function that calls glProgramUniform2f(\a program, \a location, \a v0, \a v1). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2f.xml}{glProgramUniform2f()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) + + Convenience function that calls glProgramUniform2fv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2fv.xml}{glProgramUniform2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) + + Convenience function that calls glProgramUniform2i(\a program, \a location, \a v0, \a v1). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2i.xml}{glProgramUniform2i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint * value) + + Convenience function that calls glProgramUniform2iv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2iv.xml}{glProgramUniform2iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) + + Convenience function that calls glProgramUniform2ui(\a program, \a location, \a v0, \a v1). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2ui.xml}{glProgramUniform2ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glProgramUniform2uiv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform2uiv.xml}{glProgramUniform2uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) + + Convenience function that calls glProgramUniform3f(\a program, \a location, \a v0, \a v1, \a v2). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3f.xml}{glProgramUniform3f()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) + + Convenience function that calls glProgramUniform3fv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3fv.xml}{glProgramUniform3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) + + Convenience function that calls glProgramUniform3i(\a program, \a location, \a v0, \a v1, \a v2). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3i.xml}{glProgramUniform3i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint * value) + + Convenience function that calls glProgramUniform3iv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3iv.xml}{glProgramUniform3iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) + + Convenience function that calls glProgramUniform3ui(\a program, \a location, \a v0, \a v1, \a v2). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3ui.xml}{glProgramUniform3ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glProgramUniform3uiv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform3uiv.xml}{glProgramUniform3uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) + + Convenience function that calls glProgramUniform4f(\a program, \a location, \a v0, \a v1, \a v2, \a v3). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4f.xml}{glProgramUniform4f()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) + + Convenience function that calls glProgramUniform4fv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4fv.xml}{glProgramUniform4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) + + Convenience function that calls glProgramUniform4i(\a program, \a location, \a v0, \a v1, \a v2, \a v3). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4i.xml}{glProgramUniform4i()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint * value) + + Convenience function that calls glProgramUniform4iv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4iv.xml}{glProgramUniform4iv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) + + Convenience function that calls glProgramUniform4ui(\a program, \a location, \a v0, \a v1, \a v2, \a v3). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4ui.xml}{glProgramUniform4ui()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) + + Convenience function that calls glProgramUniform4uiv(\a program, \a location, \a count, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniform4uiv.xml}{glProgramUniform4uiv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix2fv(\a program, \a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix2fv.xml}{glProgramUniformMatrix2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix2x3fv(\a program, \a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix2x3fv.xml}{glProgramUniformMatrix2x3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix2x4fv(\a program, \a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix2x4fv.xml}{glProgramUniformMatrix2x4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix3fv(\a program, \a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix3fv.xml}{glProgramUniformMatrix3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix3x2fv(\a program, \a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix3x2fv.xml}{glProgramUniformMatrix3x2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix3x4fv(\a program, \a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix3x4fv.xml}{glProgramUniformMatrix3x4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix4fv(\a program, \a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix4fv.xml}{glProgramUniformMatrix4fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix4x2fv(\a program, \a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix4x2fv.xml}{glProgramUniformMatrix4x2fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + + Convenience function that calls glProgramUniformMatrix4x3fv(\a program, \a location, \a count, \a transpose, \a value). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glProgramUniformMatrix4x3fv.xml}{glProgramUniformMatrix4x3fv()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glSampleMaski(GLuint maskNumber, GLbitfield mask) + + Convenience function that calls glSampleMaski(\a maskNumber, \a mask). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glSampleMaski.xml}{glSampleMaski()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) + + Convenience function that calls glTexStorage2DMultisample(\a target, \a samples, \a internalformat, \a width, \a height, \a fixedsamplelocations). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glTexStorage2DMultisample.xml}{glTexStorage2DMultisample()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) + + Convenience function that calls glUseProgramStages(\a pipeline, \a stages, \a program). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glUseProgramStages.xml}{glUseProgramStages()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glValidateProgramPipeline(GLuint pipeline) + + Convenience function that calls glValidateProgramPipeline(\a pipeline). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glValidateProgramPipeline.xml}{glValidateProgramPipeline()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribBinding(GLuint attribindex, GLuint bindingindex) + + Convenience function that calls glVertexAttribBinding(\a attribindex, \a bindingindex). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribBinding.xml}{glVertexAttribBinding()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) + + Convenience function that calls glVertexAttribFormat(\a attribindex, \a size, \a type, \a normalized, \a relativeoffset). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribFormat.xml}{glVertexAttribFormat()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) + + Convenience function that calls glVertexAttribIFormat(\a attribindex, \a size, \a type, \a relativeoffset). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexAttribIFormat.xml}{glVertexAttribIFormat()}. +*/ + +/*! + \fn void QOpenGLExtraFunctions::glVertexBindingDivisor(GLuint bindingindex, GLuint divisor) + + Convenience function that calls glVertexBindingDivisor(\a bindingindex, \a divisor). + + This function is only available in OpenGL ES 3.x, or OpenGL 3.x or 4.x contexts. When running + with plain OpenGL, the function is only usable when the given profile and version contains the + function either in core or as an extension. + + For more information, see the OpenGL ES 3.x documentation for + \l{http://www.khronos.org/opengles/sdk/docs/man31/glVertexBindingDivisor.xml}{glVertexBindingDivisor()}. +*/ + +/*! + \fn bool QOpenGLExtraFunctions::isInitialized(const QOpenGLExtraFunctionsPrivate *d) + \internal +*/ + +// Functions part of the OpenGL ES 3.0+ standard need special handling. These, just like +// the 2.0 functions, are not guaranteed to be resolvable via eglGetProcAddress or +// similar. (we cannot count on EGL_KHR_(client_)get_all_proc_addresses being available) + +// Calling them directly is, unlike the 2.0 functions, not feasible because one may build +// the binaries on a GLES3-capable system and then deploy on a GLES2-only system that does +// not have these symbols, and vice versa. Until ES3 becomes universally available, they +// have to be dlsym'ed. + +Q_GLOBAL_STATIC(QOpenGLES3Helper, qgles3Helper) + +bool QOpenGLES3Helper::init() { - MapBuffer = qopenglfResolveMapBuffer; - MapBufferRange = qopenglfResolveMapBufferRange; +#ifdef QT_NO_LIBRARY + return false; +#elif !defined(Q_OS_IOS) +# ifdef Q_OS_WIN +# ifndef QT_DEBUG + m_gl.setFileName(QStringLiteral("libGLESv2")); +# else + m_gl.setFileName(QStringLiteral("libGLESv2d")); +# endif +# else +# ifdef Q_OS_ANDROID + m_gl.setFileName(QStringLiteral("GLESv2")); +# else + m_gl.setFileNameAndVersion(QStringLiteral("GLESv2"), 2); +# endif +# endif // Q_OS_WIN + return m_gl.load(); +#else + return true; +#endif // Q_OS_IOS +} + +QFunctionPointer QOpenGLES3Helper::resolve(const char *name) +{ +#ifdef Q_OS_IOS + return QFunctionPointer(dlsym(RTLD_DEFAULT, name)); +#elif !defined(QT_NO_LIBRARY) + return m_gl.resolve(name); +#else + Q_UNUSED(name); + return 0; +#endif +} + +QOpenGLES3Helper::QOpenGLES3Helper() +{ + m_supportedVersion = qMakePair(2, 0); + + if (init()) { + const QPair<int, int> contextVersion = QOpenGLContext::currentContext()->format().version(); + + qCDebug(lcGLES3, "Resolving OpenGL ES 3.0 entry points"); + + BeginQuery = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint)) resolve("glBeginQuery"); + BeginTransformFeedback = (void (QOPENGLF_APIENTRYP) (GLenum)) resolve("glBeginTransformFeedback"); + BindBufferBase = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLuint)) resolve("glBindBufferBase"); + BindBufferRange = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) resolve("glBindBufferRange"); + BindSampler = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glBindSampler"); + BindTransformFeedback = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint)) resolve("glBindTransformFeedback"); + BindVertexArray = (void (QOPENGLF_APIENTRYP) (GLuint)) resolve("glBindVertexArray"); + BlitFramebuffer = (void (QOPENGLF_APIENTRYP) (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) resolve("glBlitFramebuffer"); + ClearBufferfi = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLfloat, GLint)) resolve("glClearBufferfi"); + ClearBufferfv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, const GLfloat *)) resolve("glClearBufferfv"); + ClearBufferiv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, const GLint *)) resolve("glClearBufferiv"); + ClearBufferuiv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, const GLuint *)) resolve("glClearBufferuiv"); + ClientWaitSync = (GLenum (QOPENGLF_APIENTRYP) (GLsync, GLbitfield, GLuint64)) resolve("glClientWaitSync"); + CompressedTexImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const void *)) resolve("glCompressedTexImage3D"); + CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const void *)) resolve("glCompressedTexSubImage3D"); + CopyBufferSubData = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr)) resolve("glCopyBufferSubData"); + CopyTexSubImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) resolve("glCopyTexSubImage3D"); + DeleteQueries = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteQueries"); + DeleteSamplers = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteSamplers"); + DeleteSync = (void (QOPENGLF_APIENTRYP) (GLsync)) resolve("glDeleteSync"); + DeleteTransformFeedbacks = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteTransformFeedbacks"); + DeleteVertexArrays = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteVertexArrays"); + DrawArraysInstanced = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLsizei, GLsizei)) resolve("glDrawArraysInstanced"); + DrawBuffers = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLenum *)) resolve("glDrawBuffers"); + DrawElementsInstanced = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, const void *, GLsizei)) resolve("glDrawElementsInstanced"); + DrawRangeElements = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLuint, GLsizei, GLenum, const void *)) resolve("glDrawRangeElements"); + EndQuery = (void (QOPENGLF_APIENTRYP) (GLenum)) resolve("glEndQuery"); + EndTransformFeedback = (void (QOPENGLF_APIENTRYP) ()) resolve("glEndTransformFeedback"); + FenceSync = (GLsync (QOPENGLF_APIENTRYP) (GLenum, GLbitfield)) resolve("glFenceSync"); + FlushMappedBufferRange = (void (QOPENGLF_APIENTRYP) (GLenum, GLintptr, GLsizeiptr)) resolve("glFlushMappedBufferRange"); + FramebufferTextureLayer = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLuint, GLint, GLint)) resolve("glFramebufferTextureLayer"); + GenQueries = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenQueries"); + GenSamplers = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenSamplers"); + GenTransformFeedbacks = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenTransformFeedbacks"); + GenVertexArrays = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenVertexArrays"); + GetActiveUniformBlockName = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLsizei, GLsizei*, GLchar*)) resolve("glGetActiveUniformBlockName"); + GetActiveUniformBlockiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLenum, GLint*)) resolve("glGetActiveUniformBlockiv"); + GetActiveUniformsiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, const GLuint *, GLenum, GLint*)) resolve("glGetActiveUniformsiv"); + GetBufferParameteri64v = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint64*)) resolve("glGetBufferParameteri64v"); + GetBufferPointerv = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, void **)) resolve("glGetBufferPointerv"); + GetFragDataLocation = (GLint (QOPENGLF_APIENTRYP) (GLuint, const GLchar *)) resolve("glGetFragDataLocation"); + GetInteger64i_v = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLint64*)) resolve("glGetInteger64i_v"); + GetInteger64v = (void (QOPENGLF_APIENTRYP) (GLenum, GLint64*)) resolve("glGetInteger64v"); + GetIntegeri_v = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLint*)) resolve("glGetIntegeri_v"); + GetInternalformativ = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLenum, GLsizei, GLint*)) resolve("glGetInternalformativ"); + GetProgramBinary = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, GLsizei*, GLenum*, void *)) resolve("glGetProgramBinary"); + GetQueryObjectuiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint*)) resolve("glGetQueryObjectuiv"); + GetQueryiv = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint*)) resolve("glGetQueryiv"); + GetSamplerParameterfv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLfloat*)) resolve("glGetSamplerParameterfv"); + GetSamplerParameteriv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint*)) resolve("glGetSamplerParameteriv"); + GetStringi = (const GLubyte * (QOPENGLF_APIENTRYP) (GLenum, GLuint)) resolve("glGetStringi"); + GetSynciv = (void (QOPENGLF_APIENTRYP) (GLsync, GLenum, GLsizei, GLsizei*, GLint*)) resolve("glGetSynciv"); + GetTransformFeedbackVarying = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLsizei, GLsizei*, GLsizei*, GLenum*, GLchar*)) resolve("glGetTransformFeedbackVarying"); + GetUniformBlockIndex = (GLuint (QOPENGLF_APIENTRYP) (GLuint, const GLchar *)) resolve("glGetUniformBlockIndex"); + GetUniformIndices = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, const GLchar *const*, GLuint*)) resolve("glGetUniformIndices"); + GetUniformuiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint*)) resolve("glGetUniformuiv"); + GetVertexAttribIiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint*)) resolve("glGetVertexAttribIiv"); + GetVertexAttribIuiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint*)) resolve("glGetVertexAttribIuiv"); + InvalidateFramebuffer = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, const GLenum *)) resolve("glInvalidateFramebuffer"); + InvalidateSubFramebuffer = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, const GLenum *, GLint, GLint, GLsizei, GLsizei)) resolve("glInvalidateSubFramebuffer"); + IsQuery = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsQuery"); + IsSampler = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsSampler"); + IsSync = (GLboolean (QOPENGLF_APIENTRYP) (GLsync)) resolve("glIsSync"); + IsTransformFeedback = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsTransformFeedback"); + IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsVertexArray"); + MapBufferRange = (void * (QOPENGLF_APIENTRYP) (GLenum, GLintptr, GLsizeiptr, GLbitfield)) resolve("glMapBufferRange"); + PauseTransformFeedback = (void (QOPENGLF_APIENTRYP) ()) resolve("glPauseTransformFeedback"); + ProgramBinary = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, const void *, GLsizei)) resolve("glProgramBinary"); + ProgramParameteri = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint)) resolve("glProgramParameteri"); + ReadBuffer = (void (QOPENGLF_APIENTRYP) (GLenum)) resolve("glReadBuffer"); + RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glRenderbufferStorageMultisample"); + ResumeTransformFeedback = (void (QOPENGLF_APIENTRYP) ()) resolve("glResumeTransformFeedback"); + SamplerParameterf = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLfloat)) resolve("glSamplerParameterf"); + SamplerParameterfv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLfloat *)) resolve("glSamplerParameterfv"); + SamplerParameteri = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint)) resolve("glSamplerParameteri"); + SamplerParameteriv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLint *)) resolve("glSamplerParameteriv"); + TexImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const void *)) resolve("glTexImage3D"); + TexStorage2D = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glTexStorage2D"); + TexStorage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei)) resolve("glTexStorage3D"); + TexSubImage3D = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void *)) resolve("glTexSubImage3D"); + TransformFeedbackVaryings = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, const GLchar *const*, GLenum)) resolve("glTransformFeedbackVaryings"); + Uniform1ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint)) resolve("glUniform1ui"); + Uniform1uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform1uiv"); + Uniform2ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint, GLuint)) resolve("glUniform2ui"); + Uniform2uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform2uiv"); + Uniform3ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint, GLuint, GLuint)) resolve("glUniform3ui"); + Uniform3uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform3uiv"); + Uniform4ui = (void (QOPENGLF_APIENTRYP) (GLint, GLuint, GLuint, GLuint, GLuint)) resolve("glUniform4ui"); + Uniform4uiv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, const GLuint *)) resolve("glUniform4uiv"); + UniformBlockBinding = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLuint)) resolve("glUniformBlockBinding"); + UniformMatrix2x3fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix2x3fv"); + UniformMatrix2x4fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix2x4fv"); + UniformMatrix3x2fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix3x2fv"); + UniformMatrix3x4fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix3x4fv"); + UniformMatrix4x2fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix4x2fv"); + UniformMatrix4x3fv = (void (QOPENGLF_APIENTRYP) (GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glUniformMatrix4x3fv"); + UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP) (GLenum)) resolve("glUnmapBuffer"); + VertexAttribDivisor = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glVertexAttribDivisor"); + VertexAttribI4i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint, GLint)) resolve("glVertexAttribI4i"); + VertexAttribI4iv = (void (QOPENGLF_APIENTRYP) (GLuint, const GLint *)) resolve("glVertexAttribI4iv"); + VertexAttribI4ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLuint, GLuint, GLuint)) resolve("glVertexAttribI4ui"); + VertexAttribI4uiv = (void (QOPENGLF_APIENTRYP) (GLuint, const GLuint *)) resolve("glVertexAttribI4uiv"); + VertexAttribIPointer = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLenum, GLsizei, const void *)) resolve("glVertexAttribIPointer"); + WaitSync = (void (QOPENGLF_APIENTRYP) (GLsync, GLbitfield, GLuint64)) resolve("glWaitSync"); + + if (!BeginQuery || !BlitFramebuffer || !GenTransformFeedbacks || !GenVertexArrays || !MapBufferRange + || !RenderbufferStorageMultisample || !TexStorage2D || !WaitSync) { + qWarning("OpenGL ES 3.0 entry points not found. This is odd because the driver returned a context of version %d.%d", + contextVersion.first, contextVersion.second); + return; + } + m_supportedVersion = qMakePair(3, 0); + + if (contextVersion >= qMakePair(3, 1)) { + qCDebug(lcGLES3, "Resolving OpenGL ES 3.1 entry points"); + + ActiveShaderProgram = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glActiveShaderProgram"); + BindImageTexture = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLint, GLboolean, GLint, GLenum, GLenum)) resolve("glBindImageTexture"); + BindProgramPipeline = (void (QOPENGLF_APIENTRYP) (GLuint)) resolve("glBindProgramPipeline"); + BindVertexBuffer = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLintptr, GLsizei)) resolve("glBindVertexBuffer"); + CreateShaderProgramv = (GLuint (QOPENGLF_APIENTRYP) (GLenum, GLsizei, const GLchar *const*)) resolve("glCreateShaderProgramv"); + DeleteProgramPipelines = (void (QOPENGLF_APIENTRYP) (GLsizei, const GLuint *)) resolve("glDeleteProgramPipelines"); + DispatchCompute = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint, GLuint)) resolve("glDispatchCompute"); + DispatchComputeIndirect = (void (QOPENGLF_APIENTRYP) (GLintptr)) resolve("glDispatchComputeIndirect"); + DrawArraysIndirect = (void (QOPENGLF_APIENTRYP) (GLenum, const void *)) resolve("glDrawArraysIndirect"); + DrawElementsIndirect = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, const void *)) resolve("glDrawElementsIndirect"); + FramebufferParameteri = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint)) resolve("glFramebufferParameteri"); + GenProgramPipelines = (void (QOPENGLF_APIENTRYP) (GLsizei, GLuint*)) resolve("glGenProgramPipelines"); + GetBooleani_v = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLboolean*)) resolve("glGetBooleani_v"); + GetFramebufferParameteriv = (void (QOPENGLF_APIENTRYP) (GLenum, GLenum, GLint*)) resolve("glGetFramebufferParameteriv"); + GetMultisamplefv = (void (QOPENGLF_APIENTRYP) (GLenum, GLuint, GLfloat*)) resolve("glGetMultisamplefv"); + GetProgramInterfaceiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLenum, GLint*)) resolve("glGetProgramInterfaceiv"); + GetProgramPipelineInfoLog = (void (QOPENGLF_APIENTRYP) (GLuint, GLsizei, GLsizei*, GLchar*)) resolve("glGetProgramPipelineInfoLog"); + GetProgramPipelineiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLint*)) resolve("glGetProgramPipelineiv"); + GetProgramResourceIndex = (GLuint (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLchar *)) resolve("glGetProgramResourceIndex"); + GetProgramResourceLocation = (GLint (QOPENGLF_APIENTRYP) (GLuint, GLenum, const GLchar *)) resolve("glGetProgramResourceLocation"); + GetProgramResourceName = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint, GLsizei, GLsizei*, GLchar*)) resolve("glGetProgramResourceName"); + GetProgramResourceiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLenum, GLuint, GLsizei, const GLenum *, GLsizei, GLsizei*, GLint*)) resolve("glGetProgramResourceiv"); + GetTexLevelParameterfv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLenum, GLfloat*)) resolve("glGetTexLevelParameterfv"); + GetTexLevelParameteriv = (void (QOPENGLF_APIENTRYP) (GLenum, GLint, GLenum, GLint*)) resolve("glGetTexLevelParameteriv"); + IsProgramPipeline = (GLboolean (QOPENGLF_APIENTRYP) (GLuint)) resolve("glIsProgramPipeline"); + MemoryBarrierFunc = (void (QOPENGLF_APIENTRYP) (GLbitfield)) resolve("glMemoryBarrier"); + MemoryBarrierByRegion = (void (QOPENGLF_APIENTRYP) (GLbitfield)) resolve("glMemoryBarrierByRegion"); + ProgramUniform1f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat)) resolve("glProgramUniform1f"); + ProgramUniform1fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform1fv"); + ProgramUniform1i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint)) resolve("glProgramUniform1i"); + ProgramUniform1iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform1iv"); + ProgramUniform1ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint)) resolve("glProgramUniform1ui"); + ProgramUniform1uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform1uiv"); + ProgramUniform2f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat, GLfloat)) resolve("glProgramUniform2f"); + ProgramUniform2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform2fv"); + ProgramUniform2i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint)) resolve("glProgramUniform2i"); + ProgramUniform2iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform2iv"); + ProgramUniform2ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint, GLuint)) resolve("glProgramUniform2ui"); + ProgramUniform2uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform2uiv"); + ProgramUniform3f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat, GLfloat, GLfloat)) resolve("glProgramUniform3f"); + ProgramUniform3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform3fv"); + ProgramUniform3i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint, GLint)) resolve("glProgramUniform3i"); + ProgramUniform3iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform3iv"); + ProgramUniform3ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint, GLuint, GLuint)) resolve("glProgramUniform3ui"); + ProgramUniform3uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform3uiv"); + ProgramUniform4f = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat)) resolve("glProgramUniform4f"); + ProgramUniform4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLfloat *)) resolve("glProgramUniform4fv"); + ProgramUniform4i = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLint, GLint, GLint, GLint)) resolve("glProgramUniform4i"); + ProgramUniform4iv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLint *)) resolve("glProgramUniform4iv"); + ProgramUniform4ui = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLuint, GLuint, GLuint, GLuint)) resolve("glProgramUniform4ui"); + ProgramUniform4uiv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, const GLuint *)) resolve("glProgramUniform4uiv"); + ProgramUniformMatrix2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix2fv"); + ProgramUniformMatrix2x3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix2x3fv"); + ProgramUniformMatrix2x4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix2x4fv"); + ProgramUniformMatrix3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix3fv"); + ProgramUniformMatrix3x2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix3x2fv"); + ProgramUniformMatrix3x4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix3x4fv"); + ProgramUniformMatrix4fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix4fv"); + ProgramUniformMatrix4x2fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix4x2fv"); + ProgramUniformMatrix4x3fv = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) resolve("glProgramUniformMatrix4x3fv"); + SampleMaski = (void (QOPENGLF_APIENTRYP) (GLuint, GLbitfield)) resolve("glSampleMaski"); + TexStorage2DMultisample = (void (QOPENGLF_APIENTRYP) (GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean)) resolve("glTexStorage2DMultisample"); + UseProgramStages = (void (QOPENGLF_APIENTRYP) (GLuint, GLbitfield, GLuint)) resolve("glUseProgramStages"); + ValidateProgramPipeline = (void (QOPENGLF_APIENTRYP) (GLuint)) resolve("glValidateProgramPipeline"); + VertexAttribBinding = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glVertexAttribBinding"); + VertexAttribFormat = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLenum, GLboolean, GLuint)) resolve("glVertexAttribFormat"); + VertexAttribIFormat = (void (QOPENGLF_APIENTRYP) (GLuint, GLint, GLenum, GLuint)) resolve("glVertexAttribIFormat"); + VertexBindingDivisor = (void (QOPENGLF_APIENTRYP) (GLuint, GLuint)) resolve("glVertexBindingDivisor"); + + if (!ActiveShaderProgram || !BindImageTexture || !DispatchCompute || !DrawArraysIndirect + || !GenProgramPipelines || !MemoryBarrierFunc) { + qWarning("OpenGL ES 3.1 entry points not found. This is odd because the driver returned a context of version %d.%d", + contextVersion.first, contextVersion.second); + return; + } + m_supportedVersion = qMakePair(3, 1); + } + } else { + qFatal("Failed to load libGLESv2"); + } +} + +// GLES 3.0 and 3.1 + +// Checks for true OpenGL ES 3.x. OpenGL with GL_ARB_ES3_compatibility +// does not count because there the plain resolvers work anyhow. +static inline bool isES3(int minor) +{ + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + + const bool libMatches = QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES; + const bool contextMatches = ctx->isOpenGLES() && ctx->format().version() >= qMakePair(3, minor); + + // Resolving happens whenever qgles3Helper() is called first. So do it only + // when the driver gives a 3.0+ context. + if (libMatches && contextMatches) + return qgles3Helper()->supportedVersion() >= qMakePair(3, minor); + + return false; +} + +// Go through the dlsym-based helper for real ES 3, resolve using +// wglGetProcAddress or similar when on plain OpenGL. + +static void QOPENGLF_APIENTRY qopenglfResolveBeginQuery(GLenum target, GLuint id) +{ + if (isES3(0)) + qgles3Helper()->BeginQuery(target, id); + else + RESOLVE_FUNC_VOID(0, BeginQuery)(target, id); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBeginTransformFeedback(GLenum primitiveMode) +{ + if (isES3(0)) + qgles3Helper()->BeginTransformFeedback(primitiveMode); + else + RESOLVE_FUNC_VOID(0, BeginTransformFeedback)(primitiveMode); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindBufferBase(GLenum target, GLuint index, GLuint buffer) +{ + if (isES3(0)) + qgles3Helper()->BindBufferBase(target, index, buffer); + else + RESOLVE_FUNC_VOID(0, BindBufferBase)(target, index, buffer); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +{ + if (isES3(0)) + qgles3Helper()->BindBufferRange(target, index, buffer, offset, size); + else + RESOLVE_FUNC_VOID(0, BindBufferRange)(target, index, buffer, offset, size); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindSampler(GLuint unit, GLuint sampler) +{ + if (isES3(0)) + qgles3Helper()->BindSampler(unit, sampler); + else + RESOLVE_FUNC_VOID(0, BindSampler)(unit, sampler); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindTransformFeedback(GLenum target, GLuint id) +{ + if (isES3(0)) + qgles3Helper()->BindTransformFeedback(target, id); + else + RESOLVE_FUNC_VOID(0, BindTransformFeedback)(target, id); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindVertexArray(GLuint array) +{ + if (isES3(0)) + qgles3Helper()->BindVertexArray(array); + else + RESOLVE_FUNC_VOID(0, BindVertexArray)(array); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +{ + if (isES3(0)) + qgles3Helper()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + else + RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer) + (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +static void QOPENGLF_APIENTRY qopenglfResolveClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +{ + if (isES3(0)) + qgles3Helper()->ClearBufferfi(buffer, drawbuffer, depth, stencil); + else + RESOLVE_FUNC_VOID(0, ClearBufferfi)(buffer, drawbuffer, depth, stencil); +} + +static void QOPENGLF_APIENTRY qopenglfResolveClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->ClearBufferfv(buffer, drawbuffer, value); + else + RESOLVE_FUNC_VOID(0, ClearBufferfv)(buffer, drawbuffer, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value) +{ + if (isES3(0)) + qgles3Helper()->ClearBufferiv(buffer, drawbuffer, value); + else + RESOLVE_FUNC_VOID(0, ClearBufferiv)(buffer, drawbuffer, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->ClearBufferuiv(buffer, drawbuffer, value); + else + RESOLVE_FUNC_VOID(0, ClearBufferuiv)(buffer, drawbuffer, value); +} + +static GLenum QOPENGLF_APIENTRY qopenglfResolveClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + if (isES3(0)) + return qgles3Helper()->ClientWaitSync(sync, flags, timeout); + else + RESOLVE_FUNC(GLenum, 0, ClientWaitSync)(sync, flags, timeout); +} + +static void QOPENGLF_APIENTRY qopenglfResolveCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data) +{ + if (isES3(0)) + qgles3Helper()->CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data); + else + RESOLVE_FUNC_VOID(0, CompressedTexImage3D)(target, level, internalformat, width, height, depth, border, imageSize, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data) +{ + if (isES3(0)) + qgles3Helper()->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + else + RESOLVE_FUNC_VOID(0, CompressedTexSubImage3D)(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +{ + if (isES3(0)) + qgles3Helper()->CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); + else + RESOLVE_FUNC_VOID(0, CopyBufferSubData)(readTarget, writeTarget, readOffset, writeOffset, size); +} + +static void QOPENGLF_APIENTRY qopenglfResolveCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + if (isES3(0)) + qgles3Helper()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); + else + RESOLVE_FUNC_VOID(0, CopyTexSubImage3D)(target, level, xoffset, yoffset, zoffset, x, y, width, height); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteQueries(GLsizei n, const GLuint * ids) +{ + if (isES3(0)) + qgles3Helper()->DeleteQueries(n, ids); + else + RESOLVE_FUNC_VOID(0, DeleteQueries)(n, ids); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteSamplers(GLsizei count, const GLuint * samplers) +{ + if (isES3(0)) + qgles3Helper()->DeleteSamplers(count, samplers); + else + RESOLVE_FUNC_VOID(0, DeleteSamplers)(count, samplers); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteSync(GLsync sync) +{ + if (isES3(0)) + qgles3Helper()->DeleteSync(sync); + else + RESOLVE_FUNC_VOID(0, DeleteSync)(sync); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteTransformFeedbacks(GLsizei n, const GLuint * ids) +{ + if (isES3(0)) + qgles3Helper()->DeleteTransformFeedbacks(n, ids); + else + RESOLVE_FUNC_VOID(0, DeleteTransformFeedbacks)(n, ids); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteVertexArrays(GLsizei n, const GLuint * arrays) +{ + if (isES3(0)) + qgles3Helper()->DeleteVertexArrays(n, arrays); + else + RESOLVE_FUNC_VOID(0, DeleteVertexArrays)(n, arrays); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) +{ + if (isES3(0)) + qgles3Helper()->DrawArraysInstanced(mode, first, count, instancecount); + else + RESOLVE_FUNC_VOID(0, DrawArraysInstanced)(mode, first, count, instancecount); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawBuffers(GLsizei n, const GLenum * bufs) +{ + if (isES3(0)) + qgles3Helper()->DrawBuffers(n, bufs); + else + RESOLVE_FUNC_VOID(0, DrawBuffers)(n, bufs); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount) +{ + if (isES3(0)) + qgles3Helper()->DrawElementsInstanced(mode, count, type, indices, instancecount); + else + RESOLVE_FUNC_VOID(0, DrawElementsInstanced)(mode, count, type, indices, instancecount); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices) +{ + if (isES3(0)) + qgles3Helper()->DrawRangeElements(mode, start, end, count, type, indices); + else + RESOLVE_FUNC_VOID(0, DrawRangeElements)(mode, start, end, count, type, indices); +} + +static void QOPENGLF_APIENTRY qopenglfResolveEndQuery(GLenum target) +{ + if (isES3(0)) + qgles3Helper()->EndQuery(target); + else + RESOLVE_FUNC_VOID(0, EndQuery)(target); +} + +static void QOPENGLF_APIENTRY qopenglfResolveEndTransformFeedback() +{ + if (isES3(0)) + qgles3Helper()->EndTransformFeedback(); + else + RESOLVE_FUNC_VOID(0, EndTransformFeedback)(); +} + +static GLsync QOPENGLF_APIENTRY qopenglfResolveFenceSync(GLenum condition, GLbitfield flags) +{ + if (isES3(0)) + return qgles3Helper()->FenceSync(condition, flags); + else + RESOLVE_FUNC(GLsync, 0, FenceSync)(condition, flags); +} + +static void QOPENGLF_APIENTRY qopenglfResolveFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +{ + if (isES3(0)) + qgles3Helper()->FlushMappedBufferRange(target, offset, length); + else + RESOLVE_FUNC_VOID(0, FlushMappedBufferRange)(target, offset, length); +} + +static void QOPENGLF_APIENTRY qopenglfResolveFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) +{ + if (isES3(0)) + qgles3Helper()->FramebufferTextureLayer(target, attachment, texture, level, layer); + else + RESOLVE_FUNC_VOID(0, FramebufferTextureLayer)(target, attachment, texture, level, layer); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenQueries(GLsizei n, GLuint* ids) +{ + if (isES3(0)) + qgles3Helper()->GenQueries(n, ids); + else + RESOLVE_FUNC_VOID(0, GenQueries)(n, ids); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenSamplers(GLsizei count, GLuint* samplers) +{ + if (isES3(0)) + qgles3Helper()->GenSamplers(count, samplers); + else + RESOLVE_FUNC_VOID(0, GenSamplers)(count, samplers); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenTransformFeedbacks(GLsizei n, GLuint* ids) +{ + if (isES3(0)) + qgles3Helper()->GenTransformFeedbacks(n, ids); + else + RESOLVE_FUNC_VOID(0, GenTransformFeedbacks)(n, ids); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenVertexArrays(GLsizei n, GLuint* arrays) +{ + if (isES3(0)) + qgles3Helper()->GenVertexArrays(n, arrays); + else + RESOLVE_FUNC_VOID(0, GenVertexArrays)(n, arrays); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) +{ + if (isES3(0)) + qgles3Helper()->GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName); + else + RESOLVE_FUNC_VOID(0, GetActiveUniformBlockName)(program, uniformBlockIndex, bufSize, length, uniformBlockName); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params); + else + RESOLVE_FUNC_VOID(0, GetActiveUniformBlockiv)(program, uniformBlockIndex, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params); + else + RESOLVE_FUNC_VOID(0, GetActiveUniformsiv)(program, uniformCount, uniformIndices, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) +{ + if (isES3(0)) + qgles3Helper()->GetBufferParameteri64v(target, pname, params); + else + RESOLVE_FUNC_VOID(0, GetBufferParameteri64v)(target, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetBufferPointerv(GLenum target, GLenum pname, void ** params) +{ + if (isES3(0)) + qgles3Helper()->GetBufferPointerv(target, pname, params); + else + RESOLVE_FUNC_VOID(0, GetBufferPointerv)(target, pname, params); +} + +static GLint QOPENGLF_APIENTRY qopenglfResolveGetFragDataLocation(GLuint program, const GLchar * name) +{ + if (isES3(0)) + return qgles3Helper()->GetFragDataLocation(program, name); + else + RESOLVE_FUNC(GLint, 0, GetFragDataLocation)(program, name); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetInteger64i_v(GLenum target, GLuint index, GLint64* data) +{ + if (isES3(0)) + qgles3Helper()->GetInteger64i_v(target, index, data); + else + RESOLVE_FUNC_VOID(0, GetInteger64i_v)(target, index, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetInteger64v(GLenum pname, GLint64* data) +{ + if (isES3(0)) + qgles3Helper()->GetInteger64v(pname, data); + else + RESOLVE_FUNC_VOID(0, GetInteger64v)(pname, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetIntegeri_v(GLenum target, GLuint index, GLint* data) +{ + if (isES3(0)) + qgles3Helper()->GetIntegeri_v(target, index, data); + else + RESOLVE_FUNC_VOID(0, GetIntegeri_v)(target, index, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetInternalformativ(target, internalformat, pname, bufSize, params); + else + RESOLVE_FUNC_VOID(0, GetInternalformativ)(target, internalformat, pname, bufSize, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void * binary) +{ + if (isES3(0)) + qgles3Helper()->GetProgramBinary(program, bufSize, length, binaryFormat, binary); + else + RESOLVE_FUNC_VOID(0, GetProgramBinary)(program, bufSize, length, binaryFormat, binary); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) +{ + if (isES3(0)) + qgles3Helper()->GetQueryObjectuiv(id, pname, params); + else + RESOLVE_FUNC_VOID(0, GetQueryObjectuiv)(id, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetQueryiv(GLenum target, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetQueryiv(target, pname, params); + else + RESOLVE_FUNC_VOID(0, GetQueryiv)(target, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) +{ + if (isES3(0)) + qgles3Helper()->GetSamplerParameterfv(sampler, pname, params); + else + RESOLVE_FUNC_VOID(0, GetSamplerParameterfv)(sampler, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetSamplerParameteriv(sampler, pname, params); + else + RESOLVE_FUNC_VOID(0, GetSamplerParameteriv)(sampler, pname, params); +} + +static const GLubyte * QOPENGLF_APIENTRY qopenglfResolveGetStringi(GLenum name, GLuint index) +{ + if (isES3(0)) + return qgles3Helper()->GetStringi(name, index); + else + RESOLVE_FUNC(const GLubyte *, 0, GetStringi)(name, index); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) +{ + if (isES3(0)) + qgles3Helper()->GetSynciv(sync, pname, bufSize, length, values); + else + RESOLVE_FUNC_VOID(0, GetSynciv)(sync, pname, bufSize, length, values); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) +{ + if (isES3(0)) + qgles3Helper()->GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); + else + RESOLVE_FUNC_VOID(0, GetTransformFeedbackVarying)(program, index, bufSize, length, size, type, name); +} + +static GLuint QOPENGLF_APIENTRY qopenglfResolveGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName) +{ + if (isES3(0)) + return qgles3Helper()->GetUniformBlockIndex(program, uniformBlockName); + else + RESOLVE_FUNC(GLuint, 0, GetUniformBlockIndex)(program, uniformBlockName); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint* uniformIndices) +{ + if (isES3(0)) + qgles3Helper()->GetUniformIndices(program, uniformCount, uniformNames, uniformIndices); + else + RESOLVE_FUNC_VOID(0, GetUniformIndices)(program, uniformCount, uniformNames, uniformIndices); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetUniformuiv(GLuint program, GLint location, GLuint* params) +{ + if (isES3(0)) + qgles3Helper()->GetUniformuiv(program, location, params); + else + RESOLVE_FUNC_VOID(0, GetUniformuiv)(program, location, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) +{ + if (isES3(0)) + qgles3Helper()->GetVertexAttribIiv(index, pname, params); + else + RESOLVE_FUNC_VOID(0, GetVertexAttribIiv)(index, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) +{ + if (isES3(0)) + qgles3Helper()->GetVertexAttribIuiv(index, pname, params); + else + RESOLVE_FUNC_VOID(0, GetVertexAttribIuiv)(index, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments) +{ + if (isES3(0)) + qgles3Helper()->InvalidateFramebuffer(target, numAttachments, attachments); + else + RESOLVE_FUNC_VOID(0, InvalidateFramebuffer)(target, numAttachments, attachments); +} + +static void QOPENGLF_APIENTRY qopenglfResolveInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) +{ + if (isES3(0)) + qgles3Helper()->InvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); + else + RESOLVE_FUNC_VOID(0, InvalidateSubFramebuffer)(target, numAttachments, attachments, x, y, width, height); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsQuery(GLuint id) +{ + if (isES3(0)) + return qgles3Helper()->IsQuery(id); + else + RESOLVE_FUNC(GLboolean, 0, IsQuery)(id); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsSampler(GLuint sampler) +{ + if (isES3(0)) + return qgles3Helper()->IsSampler(sampler); + else + RESOLVE_FUNC(GLboolean, 0, IsSampler)(sampler); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsSync(GLsync sync) +{ + if (isES3(0)) + return qgles3Helper()->IsSync(sync); + else + RESOLVE_FUNC(GLboolean, 0, IsSync)(sync); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsTransformFeedback(GLuint id) +{ + if (isES3(0)) + return qgles3Helper()->IsTransformFeedback(id); + else + RESOLVE_FUNC(GLboolean, 0, IsTransformFeedback)(id); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsVertexArray(GLuint array) +{ + if (isES3(0)) + return qgles3Helper()->IsVertexArray(array); + else + RESOLVE_FUNC(GLboolean, 0, IsVertexArray)(array); +} + +static void * QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +{ + if (isES3(0)) + return qgles3Helper()->MapBufferRange(target, offset, length, access); + else + RESOLVE_FUNC(void *, 0, MapBufferRange)(target, offset, length, access); +} + +static void QOPENGLF_APIENTRY qopenglfResolvePauseTransformFeedback() +{ + if (isES3(0)) + qgles3Helper()->PauseTransformFeedback(); + else + RESOLVE_FUNC_VOID(0, PauseTransformFeedback)(); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramBinary(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length) +{ + if (isES3(0)) + qgles3Helper()->ProgramBinary(program, binaryFormat, binary, length); + else + RESOLVE_FUNC_VOID(0, ProgramBinary)(program, binaryFormat, binary, length); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramParameteri(GLuint program, GLenum pname, GLint value) +{ + if (isES3(0)) + qgles3Helper()->ProgramParameteri(program, pname, value); + else + RESOLVE_FUNC_VOID(0, ProgramParameteri)(program, pname, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveReadBuffer(GLenum src) +{ + if (isES3(0)) + qgles3Helper()->ReadBuffer(src); + else + RESOLVE_FUNC_VOID(0, ReadBuffer)(src); +} + +static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +{ + if (isES3(0)) + qgles3Helper()->RenderbufferStorageMultisample(target, samples, internalformat, width, height); + else + RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample) + (target, samples, internalformat, width, height); +} + +static void QOPENGLF_APIENTRY qopenglfResolveResumeTransformFeedback() +{ + if (isES3(0)) + qgles3Helper()->ResumeTransformFeedback(); + else + RESOLVE_FUNC_VOID(0, ResumeTransformFeedback)(); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) +{ + if (isES3(0)) + qgles3Helper()->SamplerParameterf(sampler, pname, param); + else + RESOLVE_FUNC_VOID(0, SamplerParameterf)(sampler, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat * param) +{ + if (isES3(0)) + qgles3Helper()->SamplerParameterfv(sampler, pname, param); + else + RESOLVE_FUNC_VOID(0, SamplerParameterfv)(sampler, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameteri(GLuint sampler, GLenum pname, GLint param) +{ + if (isES3(0)) + qgles3Helper()->SamplerParameteri(sampler, pname, param); + else + RESOLVE_FUNC_VOID(0, SamplerParameteri)(sampler, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSamplerParameteriv(GLuint sampler, GLenum pname, const GLint * param) +{ + if (isES3(0)) + qgles3Helper()->SamplerParameteriv(sampler, pname, param); + else + RESOLVE_FUNC_VOID(0, SamplerParameteriv)(sampler, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels) +{ + if (isES3(0)) + qgles3Helper()->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); + else + RESOLVE_FUNC_VOID(0, TexImage3D)(target, level, internalformat, width, height, depth, border, format, type, pixels); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +{ + if (isES3(0)) + qgles3Helper()->TexStorage2D(target, levels, internalformat, width, height); + else + RESOLVE_FUNC_VOID(0, TexStorage2D)(target, levels, internalformat, width, height); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + if (isES3(0)) + qgles3Helper()->TexStorage3D(target, levels, internalformat, width, height, depth); + else + RESOLVE_FUNC_VOID(0, TexStorage3D)(target, levels, internalformat, width, height, depth); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels) +{ + if (isES3(0)) + qgles3Helper()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + else + RESOLVE_FUNC_VOID(0, TexSubImage3D)(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode) +{ + if (isES3(0)) + qgles3Helper()->TransformFeedbackVaryings(program, count, varyings, bufferMode); + else + RESOLVE_FUNC_VOID(0, TransformFeedbackVaryings)(program, count, varyings, bufferMode); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform1ui(GLint location, GLuint v0) +{ + if (isES3(0)) + qgles3Helper()->Uniform1ui(location, v0); + else + RESOLVE_FUNC_VOID(0, Uniform1ui)(location, v0); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform1uiv(GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->Uniform1uiv(location, count, value); + else + RESOLVE_FUNC_VOID(0, Uniform1uiv)(location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform2ui(GLint location, GLuint v0, GLuint v1) +{ + if (isES3(0)) + qgles3Helper()->Uniform2ui(location, v0, v1); + else + RESOLVE_FUNC_VOID(0, Uniform2ui)(location, v0, v1); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform2uiv(GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->Uniform2uiv(location, count, value); + else + RESOLVE_FUNC_VOID(0, Uniform2uiv)(location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + if (isES3(0)) + qgles3Helper()->Uniform3ui(location, v0, v1, v2); + else + RESOLVE_FUNC_VOID(0, Uniform3ui)(location, v0, v1, v2); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform3uiv(GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->Uniform3uiv(location, count, value); + else + RESOLVE_FUNC_VOID(0, Uniform3uiv)(location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + if (isES3(0)) + qgles3Helper()->Uniform4ui(location, v0, v1, v2, v3); + else + RESOLVE_FUNC_VOID(0, Uniform4ui)(location, v0, v1, v2, v3); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniform4uiv(GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(0)) + qgles3Helper()->Uniform4uiv(location, count, value); + else + RESOLVE_FUNC_VOID(0, Uniform4uiv)(location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +{ + if (isES3(0)) + qgles3Helper()->UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + else + RESOLVE_FUNC_VOID(0, UniformBlockBinding)(program, uniformBlockIndex, uniformBlockBinding); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix2x3fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix2x3fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix2x4fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix2x4fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix3x2fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix3x2fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix3x4fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix3x4fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix4x2fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix4x2fv)(location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(0)) + qgles3Helper()->UniformMatrix4x3fv(location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, UniformMatrix4x3fv)(location, count, transpose, value); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target) +{ + if (isES3(0)) + return qgles3Helper()->UnmapBuffer(target); + else + RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribDivisor(GLuint index, GLuint divisor) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribDivisor(index, divisor); + else + RESOLVE_FUNC_VOID(0, VertexAttribDivisor)(index, divisor); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribI4i(index, x, y, z, w); + else + RESOLVE_FUNC_VOID(0, VertexAttribI4i)(index, x, y, z, w); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4iv(GLuint index, const GLint * v) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribI4iv(index, v); + else + RESOLVE_FUNC_VOID(0, VertexAttribI4iv)(index, v); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribI4ui(index, x, y, z, w); + else + RESOLVE_FUNC_VOID(0, VertexAttribI4ui)(index, x, y, z, w); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribI4uiv(GLuint index, const GLuint * v) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribI4uiv(index, v); + else + RESOLVE_FUNC_VOID(0, VertexAttribI4uiv)(index, v); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) +{ + if (isES3(0)) + qgles3Helper()->VertexAttribIPointer(index, size, type, stride, pointer); + else + RESOLVE_FUNC_VOID(0, VertexAttribIPointer)(index, size, type, stride, pointer); +} + +static void QOPENGLF_APIENTRY qopenglfResolveWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + if (isES3(0)) + qgles3Helper()->WaitSync(sync, flags, timeout); + else + RESOLVE_FUNC_VOID(0, WaitSync)(sync, flags, timeout); +} + +static void QOPENGLF_APIENTRY qopenglfResolveActiveShaderProgram(GLuint pipeline, GLuint program) +{ + if (isES3(1)) + qgles3Helper()->ActiveShaderProgram(pipeline, program); + else + RESOLVE_FUNC_VOID(0, ActiveShaderProgram)(pipeline, program); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) +{ + if (isES3(1)) + qgles3Helper()->BindImageTexture(unit, texture, level, layered, layer, access, format); + else + RESOLVE_FUNC_VOID(0, BindImageTexture)(unit, texture, level, layered, layer, access, format); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindProgramPipeline(GLuint pipeline) +{ + if (isES3(1)) + qgles3Helper()->BindProgramPipeline(pipeline); + else + RESOLVE_FUNC_VOID(0, BindProgramPipeline)(pipeline); +} + +static void QOPENGLF_APIENTRY qopenglfResolveBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) +{ + if (isES3(1)) + qgles3Helper()->BindVertexBuffer(bindingindex, buffer, offset, stride); + else + RESOLVE_FUNC_VOID(0, BindVertexBuffer)(bindingindex, buffer, offset, stride); +} + +static GLuint QOPENGLF_APIENTRY qopenglfResolveCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const* strings) +{ + if (isES3(1)) + return qgles3Helper()->CreateShaderProgramv(type, count, strings); + else + RESOLVE_FUNC(GLuint, 0, CreateShaderProgramv)(type, count, strings); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDeleteProgramPipelines(GLsizei n, const GLuint * pipelines) +{ + if (isES3(1)) + qgles3Helper()->DeleteProgramPipelines(n, pipelines); + else + RESOLVE_FUNC_VOID(0, DeleteProgramPipelines)(n, pipelines); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) +{ + if (isES3(1)) + qgles3Helper()->DispatchCompute(num_groups_x, num_groups_y, num_groups_z); + else + RESOLVE_FUNC_VOID(0, DispatchCompute)(num_groups_x, num_groups_y, num_groups_z); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDispatchComputeIndirect(GLintptr indirect) +{ + if (isES3(1)) + qgles3Helper()->DispatchComputeIndirect(indirect); + else + RESOLVE_FUNC_VOID(0, DispatchComputeIndirect)(indirect); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawArraysIndirect(GLenum mode, const void * indirect) +{ + if (isES3(1)) + qgles3Helper()->DrawArraysIndirect(mode, indirect); + else + RESOLVE_FUNC_VOID(0, DrawArraysIndirect)(mode, indirect); +} + +static void QOPENGLF_APIENTRY qopenglfResolveDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect) +{ + if (isES3(1)) + qgles3Helper()->DrawElementsIndirect(mode, type, indirect); + else + RESOLVE_FUNC_VOID(0, DrawElementsIndirect)(mode, type, indirect); +} + +static void QOPENGLF_APIENTRY qopenglfResolveFramebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + if (isES3(1)) + qgles3Helper()->FramebufferParameteri(target, pname, param); + else + RESOLVE_FUNC_VOID(0, FramebufferParameteri)(target, pname, param); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGenProgramPipelines(GLsizei n, GLuint* pipelines) +{ + if (isES3(1)) + qgles3Helper()->GenProgramPipelines(n, pipelines); + else + RESOLVE_FUNC_VOID(0, GenProgramPipelines)(n, pipelines); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetBooleani_v(GLenum target, GLuint index, GLboolean* data) +{ + if (isES3(1)) + qgles3Helper()->GetBooleani_v(target, index, data); + else + RESOLVE_FUNC_VOID(0, GetBooleani_v)(target, index, data); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetFramebufferParameteriv(target, pname, params); + else + RESOLVE_FUNC_VOID(0, GetFramebufferParameteriv)(target, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val) +{ + if (isES3(1)) + qgles3Helper()->GetMultisamplefv(pname, index, val); + else + RESOLVE_FUNC_VOID(0, GetMultisamplefv)(pname, index, val); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetProgramInterfaceiv(program, programInterface, pname, params); + else + RESOLVE_FUNC_VOID(0, GetProgramInterfaceiv)(program, programInterface, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) +{ + if (isES3(1)) + qgles3Helper()->GetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog); + else + RESOLVE_FUNC_VOID(0, GetProgramPipelineInfoLog)(pipeline, bufSize, length, infoLog); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetProgramPipelineiv(pipeline, pname, params); + else + RESOLVE_FUNC_VOID(0, GetProgramPipelineiv)(pipeline, pname, params); +} + +static GLuint QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name) +{ + if (isES3(1)) + return qgles3Helper()->GetProgramResourceIndex(program, programInterface, name); + else + RESOLVE_FUNC(GLuint, 0, GetProgramResourceIndex)(program, programInterface, name); +} + +static GLint QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name) +{ + if (isES3(1)) + return qgles3Helper()->GetProgramResourceLocation(program, programInterface, name); + else + RESOLVE_FUNC(GLint, 0, GetProgramResourceLocation)(program, programInterface, name); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) +{ + if (isES3(1)) + qgles3Helper()->GetProgramResourceName(program, programInterface, index, bufSize, length, name); + else + RESOLVE_FUNC_VOID(0, GetProgramResourceName)(program, programInterface, index, bufSize, length, name); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei* length, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params); + else + RESOLVE_FUNC_VOID(0, GetProgramResourceiv)(program, programInterface, index, propCount, props, bufSize, length, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params) +{ + if (isES3(1)) + qgles3Helper()->GetTexLevelParameterfv(target, level, pname, params); + else + RESOLVE_FUNC_VOID(0, GetTexLevelParameterfv)(target, level, pname, params); +} + +static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params) +{ + if (isES3(1)) + qgles3Helper()->GetTexLevelParameteriv(target, level, pname, params); + else + RESOLVE_FUNC_VOID(0, GetTexLevelParameteriv)(target, level, pname, params); +} + +static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsProgramPipeline(GLuint pipeline) +{ + if (isES3(1)) + return qgles3Helper()->IsProgramPipeline(pipeline); + else + RESOLVE_FUNC(GLboolean, 0, IsProgramPipeline)(pipeline); +} + +static void QOPENGLF_APIENTRY qopenglfResolveMemoryBarrier(GLbitfield barriers) +{ + if (isES3(1)) + qgles3Helper()->MemoryBarrierFunc(barriers); + else + RESOLVE_FUNC_VOID(0, MemoryBarrierFunc)(barriers); +} + +static void QOPENGLF_APIENTRY qopenglfResolveMemoryBarrierByRegion(GLbitfield barriers) +{ + if (isES3(1)) + qgles3Helper()->MemoryBarrierByRegion(barriers); + else + RESOLVE_FUNC_VOID(0, MemoryBarrierByRegion)(barriers); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1f(program, location, v0); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1f)(program, location, v0); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1fv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1fv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1i(program, location, v0); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1i)(program, location, v0); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1iv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1iv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1ui(GLuint program, GLint location, GLuint v0) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1ui(program, location, v0); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1ui)(program, location, v0); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform1uiv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform1uiv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2f(program, location, v0, v1); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2f)(program, location, v0, v1); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2fv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2fv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2i(program, location, v0, v1); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2i)(program, location, v0, v1); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2iv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2iv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2ui(program, location, v0, v1); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2ui)(program, location, v0, v1); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform2uiv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform2uiv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3f(program, location, v0, v1, v2); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3f)(program, location, v0, v1, v2); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3fv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3fv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3i(program, location, v0, v1, v2); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3i)(program, location, v0, v1, v2); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3iv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3iv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3ui(program, location, v0, v1, v2); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3ui)(program, location, v0, v1, v2); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform3uiv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform3uiv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4f(program, location, v0, v1, v2, v3); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4f)(program, location, v0, v1, v2, v3); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4fv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4fv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4i(program, location, v0, v1, v2, v3); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4i)(program, location, v0, v1, v2, v3); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4iv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4iv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4ui(program, location, v0, v1, v2, v3); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4ui)(program, location, v0, v1, v2, v3); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniform4uiv(program, location, count, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniform4uiv)(program, location, count, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix2fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix2fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix2x3fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix2x3fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix2x4fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix2x4fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix3fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix3fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix3x2fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix3x2fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix3x4fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix3x4fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix4fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix4fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix4x2fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix4x2fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + if (isES3(1)) + qgles3Helper()->ProgramUniformMatrix4x3fv(program, location, count, transpose, value); + else + RESOLVE_FUNC_VOID(0, ProgramUniformMatrix4x3fv)(program, location, count, transpose, value); +} + +static void QOPENGLF_APIENTRY qopenglfResolveSampleMaski(GLuint maskNumber, GLbitfield mask) +{ + if (isES3(1)) + qgles3Helper()->SampleMaski(maskNumber, mask); + else + RESOLVE_FUNC_VOID(0, SampleMaski)(maskNumber, mask); +} + +static void QOPENGLF_APIENTRY qopenglfResolveTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +{ + if (isES3(1)) + qgles3Helper()->TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); + else + RESOLVE_FUNC_VOID(0, TexStorage2DMultisample)(target, samples, internalformat, width, height, fixedsamplelocations); +} + +static void QOPENGLF_APIENTRY qopenglfResolveUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) +{ + if (isES3(1)) + qgles3Helper()->UseProgramStages(pipeline, stages, program); + else + RESOLVE_FUNC_VOID(0, UseProgramStages)(pipeline, stages, program); +} + +static void QOPENGLF_APIENTRY qopenglfResolveValidateProgramPipeline(GLuint pipeline) +{ + if (isES3(1)) + qgles3Helper()->ValidateProgramPipeline(pipeline); + else + RESOLVE_FUNC_VOID(0, ValidateProgramPipeline)(pipeline); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribBinding(GLuint attribindex, GLuint bindingindex) +{ + if (isES3(1)) + qgles3Helper()->VertexAttribBinding(attribindex, bindingindex); + else + RESOLVE_FUNC_VOID(0, VertexAttribBinding)(attribindex, bindingindex); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) +{ + if (isES3(1)) + qgles3Helper()->VertexAttribFormat(attribindex, size, type, normalized, relativeoffset); + else + RESOLVE_FUNC_VOID(0, VertexAttribFormat)(attribindex, size, type, normalized, relativeoffset); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +{ + if (isES3(1)) + qgles3Helper()->VertexAttribIFormat(attribindex, size, type, relativeoffset); + else + RESOLVE_FUNC_VOID(0, VertexAttribIFormat)(attribindex, size, type, relativeoffset); +} + +static void QOPENGLF_APIENTRY qopenglfResolveVertexBindingDivisor(GLuint bindingindex, GLuint divisor) +{ + if (isES3(1)) + qgles3Helper()->VertexBindingDivisor(bindingindex, divisor); + else + RESOLVE_FUNC_VOID(0, VertexBindingDivisor)(bindingindex, divisor); +} + +/*! + Constructs a default function resolver. The resolver cannot be used until + \l {QOpenGLFunctions::}{initializeOpenGLFunctions()} is called to specify + the context. +*/ +QOpenGLExtraFunctions::QOpenGLExtraFunctions() +{ +} + +/*! + Constructs a function resolver for context. If \a context is null, then + the resolver will be created for the current QOpenGLContext. + + The context or another context in the group must be current. + + An object constructed in this way can only be used with context and other + contexts that share with it. Use \l {QOpenGLFunctions::} + {initializeOpenGLFunctions()} to change the object's context association. +*/ +QOpenGLExtraFunctions::QOpenGLExtraFunctions(QOpenGLContext *context) + : QOpenGLFunctions(context) +{ +} + +QOpenGLExtraFunctionsPrivate::QOpenGLExtraFunctionsPrivate(QOpenGLContext *ctx) + : QOpenGLFunctionsPrivate(ctx) +{ + ReadBuffer = qopenglfResolveReadBuffer; + DrawRangeElements = qopenglfResolveDrawRangeElements; + TexImage3D = qopenglfResolveTexImage3D; + TexSubImage3D = qopenglfResolveTexSubImage3D; + CopyTexSubImage3D = qopenglfResolveCopyTexSubImage3D; + CompressedTexImage3D = qopenglfResolveCompressedTexImage3D; + CompressedTexSubImage3D = qopenglfResolveCompressedTexSubImage3D; + GenQueries = qopenglfResolveGenQueries; + DeleteQueries = qopenglfResolveDeleteQueries; + IsQuery = qopenglfResolveIsQuery; + BeginQuery = qopenglfResolveBeginQuery; + EndQuery = qopenglfResolveEndQuery; + GetQueryiv = qopenglfResolveGetQueryiv; + GetQueryObjectuiv = qopenglfResolveGetQueryObjectuiv; UnmapBuffer = qopenglfResolveUnmapBuffer; + GetBufferPointerv = qopenglfResolveGetBufferPointerv; + DrawBuffers = qopenglfResolveDrawBuffers; + UniformMatrix2x3fv = qopenglfResolveUniformMatrix2x3fv; + UniformMatrix3x2fv = qopenglfResolveUniformMatrix3x2fv; + UniformMatrix2x4fv = qopenglfResolveUniformMatrix2x4fv; + UniformMatrix4x2fv = qopenglfResolveUniformMatrix4x2fv; + UniformMatrix3x4fv = qopenglfResolveUniformMatrix3x4fv; + UniformMatrix4x3fv = qopenglfResolveUniformMatrix4x3fv; BlitFramebuffer = qopenglfResolveBlitFramebuffer; RenderbufferStorageMultisample = qopenglfResolveRenderbufferStorageMultisample; + FramebufferTextureLayer = qopenglfResolveFramebufferTextureLayer; + MapBufferRange = qopenglfResolveMapBufferRange; + FlushMappedBufferRange = qopenglfResolveFlushMappedBufferRange; + BindVertexArray = qopenglfResolveBindVertexArray; + DeleteVertexArrays = qopenglfResolveDeleteVertexArrays; + GenVertexArrays = qopenglfResolveGenVertexArrays; + IsVertexArray = qopenglfResolveIsVertexArray; + GetIntegeri_v = qopenglfResolveGetIntegeri_v; + BeginTransformFeedback = qopenglfResolveBeginTransformFeedback; + EndTransformFeedback = qopenglfResolveEndTransformFeedback; + BindBufferRange = qopenglfResolveBindBufferRange; + BindBufferBase = qopenglfResolveBindBufferBase; + TransformFeedbackVaryings = qopenglfResolveTransformFeedbackVaryings; + GetTransformFeedbackVarying = qopenglfResolveGetTransformFeedbackVarying; + VertexAttribIPointer = qopenglfResolveVertexAttribIPointer; + GetVertexAttribIiv = qopenglfResolveGetVertexAttribIiv; + GetVertexAttribIuiv = qopenglfResolveGetVertexAttribIuiv; + VertexAttribI4i = qopenglfResolveVertexAttribI4i; + VertexAttribI4ui = qopenglfResolveVertexAttribI4ui; + VertexAttribI4iv = qopenglfResolveVertexAttribI4iv; + VertexAttribI4uiv = qopenglfResolveVertexAttribI4uiv; + GetUniformuiv = qopenglfResolveGetUniformuiv; + GetFragDataLocation = qopenglfResolveGetFragDataLocation; + Uniform1ui = qopenglfResolveUniform1ui; + Uniform2ui = qopenglfResolveUniform2ui; + Uniform3ui = qopenglfResolveUniform3ui; + Uniform4ui = qopenglfResolveUniform4ui; + Uniform1uiv = qopenglfResolveUniform1uiv; + Uniform2uiv = qopenglfResolveUniform2uiv; + Uniform3uiv = qopenglfResolveUniform3uiv; + Uniform4uiv = qopenglfResolveUniform4uiv; + ClearBufferiv = qopenglfResolveClearBufferiv; + ClearBufferuiv = qopenglfResolveClearBufferuiv; + ClearBufferfv = qopenglfResolveClearBufferfv; + ClearBufferfi = qopenglfResolveClearBufferfi; + GetStringi = qopenglfResolveGetStringi; + CopyBufferSubData = qopenglfResolveCopyBufferSubData; + GetUniformIndices = qopenglfResolveGetUniformIndices; + GetActiveUniformsiv = qopenglfResolveGetActiveUniformsiv; + GetUniformBlockIndex = qopenglfResolveGetUniformBlockIndex; + GetActiveUniformBlockiv = qopenglfResolveGetActiveUniformBlockiv; + GetActiveUniformBlockName = qopenglfResolveGetActiveUniformBlockName; + UniformBlockBinding = qopenglfResolveUniformBlockBinding; + DrawArraysInstanced = qopenglfResolveDrawArraysInstanced; + DrawElementsInstanced = qopenglfResolveDrawElementsInstanced; + FenceSync = qopenglfResolveFenceSync; + IsSync = qopenglfResolveIsSync; + DeleteSync = qopenglfResolveDeleteSync; + ClientWaitSync = qopenglfResolveClientWaitSync; + WaitSync = qopenglfResolveWaitSync; + GetInteger64v = qopenglfResolveGetInteger64v; + GetSynciv = qopenglfResolveGetSynciv; + GetInteger64i_v = qopenglfResolveGetInteger64i_v; + GetBufferParameteri64v = qopenglfResolveGetBufferParameteri64v; + GenSamplers = qopenglfResolveGenSamplers; + DeleteSamplers = qopenglfResolveDeleteSamplers; + IsSampler = qopenglfResolveIsSampler; + BindSampler = qopenglfResolveBindSampler; + SamplerParameteri = qopenglfResolveSamplerParameteri; + SamplerParameteriv = qopenglfResolveSamplerParameteriv; + SamplerParameterf = qopenglfResolveSamplerParameterf; + SamplerParameterfv = qopenglfResolveSamplerParameterfv; + GetSamplerParameteriv = qopenglfResolveGetSamplerParameteriv; + GetSamplerParameterfv = qopenglfResolveGetSamplerParameterfv; + VertexAttribDivisor = qopenglfResolveVertexAttribDivisor; + BindTransformFeedback = qopenglfResolveBindTransformFeedback; + DeleteTransformFeedbacks = qopenglfResolveDeleteTransformFeedbacks; + GenTransformFeedbacks = qopenglfResolveGenTransformFeedbacks; + IsTransformFeedback = qopenglfResolveIsTransformFeedback; + PauseTransformFeedback = qopenglfResolvePauseTransformFeedback; + ResumeTransformFeedback = qopenglfResolveResumeTransformFeedback; + GetProgramBinary = qopenglfResolveGetProgramBinary; + ProgramBinary = qopenglfResolveProgramBinary; + ProgramParameteri = qopenglfResolveProgramParameteri; + InvalidateFramebuffer = qopenglfResolveInvalidateFramebuffer; + InvalidateSubFramebuffer = qopenglfResolveInvalidateSubFramebuffer; + TexStorage2D = qopenglfResolveTexStorage2D; + TexStorage3D = qopenglfResolveTexStorage3D; + GetInternalformativ = qopenglfResolveGetInternalformativ; + + DispatchCompute = qopenglfResolveDispatchCompute; + DispatchComputeIndirect = qopenglfResolveDispatchComputeIndirect; + DrawArraysIndirect = qopenglfResolveDrawArraysIndirect; + DrawElementsIndirect = qopenglfResolveDrawElementsIndirect; + FramebufferParameteri = qopenglfResolveFramebufferParameteri; + GetFramebufferParameteriv = qopenglfResolveGetFramebufferParameteriv; + GetProgramInterfaceiv = qopenglfResolveGetProgramInterfaceiv; + GetProgramResourceIndex = qopenglfResolveGetProgramResourceIndex; + GetProgramResourceName = qopenglfResolveGetProgramResourceName; + GetProgramResourceiv = qopenglfResolveGetProgramResourceiv; + GetProgramResourceLocation = qopenglfResolveGetProgramResourceLocation; + UseProgramStages = qopenglfResolveUseProgramStages; + ActiveShaderProgram = qopenglfResolveActiveShaderProgram; + CreateShaderProgramv = qopenglfResolveCreateShaderProgramv; + BindProgramPipeline = qopenglfResolveBindProgramPipeline; + DeleteProgramPipelines = qopenglfResolveDeleteProgramPipelines; + GenProgramPipelines = qopenglfResolveGenProgramPipelines; + IsProgramPipeline = qopenglfResolveIsProgramPipeline; + GetProgramPipelineiv = qopenglfResolveGetProgramPipelineiv; + ProgramUniform1i = qopenglfResolveProgramUniform1i; + ProgramUniform2i = qopenglfResolveProgramUniform2i; + ProgramUniform3i = qopenglfResolveProgramUniform3i; + ProgramUniform4i = qopenglfResolveProgramUniform4i; + ProgramUniform1ui = qopenglfResolveProgramUniform1ui; + ProgramUniform2ui = qopenglfResolveProgramUniform2ui; + ProgramUniform3ui = qopenglfResolveProgramUniform3ui; + ProgramUniform4ui = qopenglfResolveProgramUniform4ui; + ProgramUniform1f = qopenglfResolveProgramUniform1f; + ProgramUniform2f = qopenglfResolveProgramUniform2f; + ProgramUniform3f = qopenglfResolveProgramUniform3f; + ProgramUniform4f = qopenglfResolveProgramUniform4f; + ProgramUniform1iv = qopenglfResolveProgramUniform1iv; + ProgramUniform2iv = qopenglfResolveProgramUniform2iv; + ProgramUniform3iv = qopenglfResolveProgramUniform3iv; + ProgramUniform4iv = qopenglfResolveProgramUniform4iv; + ProgramUniform1uiv = qopenglfResolveProgramUniform1uiv; + ProgramUniform2uiv = qopenglfResolveProgramUniform2uiv; + ProgramUniform3uiv = qopenglfResolveProgramUniform3uiv; + ProgramUniform4uiv = qopenglfResolveProgramUniform4uiv; + ProgramUniform1fv = qopenglfResolveProgramUniform1fv; + ProgramUniform2fv = qopenglfResolveProgramUniform2fv; + ProgramUniform3fv = qopenglfResolveProgramUniform3fv; + ProgramUniform4fv = qopenglfResolveProgramUniform4fv; + ProgramUniformMatrix2fv = qopenglfResolveProgramUniformMatrix2fv; + ProgramUniformMatrix3fv = qopenglfResolveProgramUniformMatrix3fv; + ProgramUniformMatrix4fv = qopenglfResolveProgramUniformMatrix4fv; + ProgramUniformMatrix2x3fv = qopenglfResolveProgramUniformMatrix2x3fv; + ProgramUniformMatrix3x2fv = qopenglfResolveProgramUniformMatrix3x2fv; + ProgramUniformMatrix2x4fv = qopenglfResolveProgramUniformMatrix2x4fv; + ProgramUniformMatrix4x2fv = qopenglfResolveProgramUniformMatrix4x2fv; + ProgramUniformMatrix3x4fv = qopenglfResolveProgramUniformMatrix3x4fv; + ProgramUniformMatrix4x3fv = qopenglfResolveProgramUniformMatrix4x3fv; + ValidateProgramPipeline = qopenglfResolveValidateProgramPipeline; + GetProgramPipelineInfoLog = qopenglfResolveGetProgramPipelineInfoLog; + BindImageTexture = qopenglfResolveBindImageTexture; + GetBooleani_v = qopenglfResolveGetBooleani_v; + MemoryBarrierFunc = qopenglfResolveMemoryBarrier; + MemoryBarrierByRegion = qopenglfResolveMemoryBarrierByRegion; + TexStorage2DMultisample = qopenglfResolveTexStorage2DMultisample; + GetMultisamplefv = qopenglfResolveGetMultisamplefv; + SampleMaski = qopenglfResolveSampleMaski; + GetTexLevelParameteriv = qopenglfResolveGetTexLevelParameteriv; + GetTexLevelParameterfv = qopenglfResolveGetTexLevelParameterfv; + BindVertexBuffer = qopenglfResolveBindVertexBuffer; + VertexAttribFormat = qopenglfResolveVertexAttribFormat; + VertexAttribIFormat = qopenglfResolveVertexAttribIFormat; + VertexAttribBinding = qopenglfResolveVertexAttribBinding; + VertexBindingDivisor = qopenglfResolveVertexBindingDivisor; +} + +QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx) + : QOpenGLExtraFunctionsPrivate(ctx), + flushVendorChecked(false) +{ + MapBuffer = qopenglfResolveMapBuffer; GetBufferSubData = qopenglfResolveGetBufferSubData; DiscardFramebuffer = qopenglfResolveDiscardFramebuffer; } diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h index b7cb4e53e9..e295f68e44 100644 --- a/src/gui/opengl/qopenglfunctions.h +++ b/src/gui/opengl/qopenglfunctions.h @@ -241,7 +241,8 @@ public: NPOTTextures = 0x1000, NPOTTextureRepeat = 0x2000, FixedFunctionPipeline = 0x4000, - TextureRGFormats = 0x8000 + TextureRGFormats = 0x8000, + MultipleRenderTargets = 0x10000 }; Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature) @@ -402,7 +403,7 @@ public: protected: QOpenGLFunctionsPrivate *d_ptr; - static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; } + static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != Q_NULLPTR; } }; Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLFunctions::OpenGLFeatures) diff --git a/src/gui/opengl/qopenglgradientcache.cpp b/src/gui/opengl/qopenglgradientcache.cpp index ab493fa85c..13bad9aabb 100644 --- a/src/gui/opengl/qopenglgradientcache.cpp +++ b/src/gui/opengl/qopenglgradientcache.cpp @@ -34,8 +34,14 @@ #include "qopenglgradientcache_p.h" #include <private/qdrawhelper_p.h> #include <private/qopenglcontext_p.h> +#include <private/qrgba64_p.h> #include <QtCore/qmutex.h> -#include <QtGui/qopenglfunctions.h> +#include "qopenglfunctions.h" +#include "qopenglextensions_p.h" + +#ifndef GL_RGBA16 +#define GL_RGBA16 0x805B +#endif QT_BEGIN_NAMESPACE @@ -137,17 +143,79 @@ GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient } CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); - uint buffer[1024]; - generateGradientColorTable(gradient, buffer, paletteSize(), opacity); funcs->glGenTextures(1, &cache_entry.texId); funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId); - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1, - 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + if (static_cast<QOpenGLExtensions *>(funcs)->hasOpenGLExtension(QOpenGLExtensions::Sized16Formats)) { + QRgba64 buffer[1024]; + generateGradientColorTable(gradient, buffer, paletteSize(), opacity); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, paletteSize(), 1, + 0, GL_RGBA, GL_UNSIGNED_SHORT, buffer); + } else { + uint buffer[1024]; + generateGradientColorTable(gradient, buffer, paletteSize(), opacity); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1, + 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + } return cache.insert(hash_val, cache_entry).value().texId; } //TODO: Let GL generate the texture using an FBO +void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, QRgba64 *colorTable, int size, qreal opacity) const +{ + int pos = 0; + QGradientStops s = gradient.stops(); + QVector<QRgba64> colors(s.size()); + + for (int i = 0; i < s.size(); ++i) + colors[i] = s[i].second.rgba64(); + + bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation); + + uint alpha = qRound(opacity * 256); + QRgba64 current_color = combineAlpha256(colors[0], alpha); + qreal incr = 1.0 / qreal(size); + qreal fpos = 1.5 * incr; + colorTable[pos++] = qPremultiply(current_color); + + while (fpos <= s.first().first) { + colorTable[pos] = colorTable[pos - 1]; + pos++; + fpos += incr; + } + + if (colorInterpolation) + current_color = qPremultiply(current_color); + + for (int i = 0; i < s.size() - 1; ++i) { + qreal delta = 1/(s[i+1].first - s[i].first); + QRgba64 next_color = combineAlpha256(colors[i+1], alpha); + if (colorInterpolation) + next_color = qPremultiply(next_color); + + while (fpos < s[i+1].first && pos < size) { + int dist = int(256 * ((fpos - s[i].first) * delta)); + int idist = 256 - dist; + if (colorInterpolation) + colorTable[pos] = interpolate256(current_color, idist, next_color, dist); + else + colorTable[pos] = qPremultiply(interpolate256(current_color, idist, next_color, dist)); + ++pos; + fpos += incr; + } + current_color = next_color; + } + + Q_ASSERT(s.size() > 0); + + QRgba64 last_color = qPremultiply(combineAlpha256(colors[s.size() - 1], alpha)); + for (;pos < size; ++pos) + colorTable[pos] = last_color; + + // Make sure the last color stop is represented at the end of the table + colorTable[size-1] = last_color; +} + void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const { int pos = 0; diff --git a/src/gui/opengl/qopenglgradientcache_p.h b/src/gui/opengl/qopenglgradientcache_p.h index bcdf3f4fcf..f2cc082250 100644 --- a/src/gui/opengl/qopenglgradientcache_p.h +++ b/src/gui/opengl/qopenglgradientcache_p.h @@ -50,6 +50,7 @@ #include <private/qopenglcontext_p.h> #include <QtCore/qmutex.h> #include <QGradient> +#include <qrgba64.h> QT_BEGIN_NAMESPACE @@ -58,7 +59,7 @@ class QOpenGL2GradientCache : public QOpenGLSharedResource struct CacheInfo { inline CacheInfo(QGradientStops s, qreal op, QGradient::InterpolationMode mode) : - stops(s), opacity(op), interpolationMode(mode) {} + stops(qMove(s)), opacity(op), interpolationMode(mode) {} GLuint texId; QGradientStops stops; @@ -83,6 +84,9 @@ public: private: inline int maxCacheSize() const { return 60; } inline void generateGradientColorTable(const QGradient& gradient, + QRgba64 *colorTable, + int size, qreal opacity) const; + inline void generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const; GLuint addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity); diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp index c0657feaa0..17a32774d8 100644 --- a/src/gui/opengl/qopenglpaintdevice.cpp +++ b/src/gui/opengl/qopenglpaintdevice.cpp @@ -169,6 +169,10 @@ QOpenGLPaintDevicePrivate::QOpenGLPaintDevicePrivate(const QSize &sz) { } +QOpenGLPaintDevicePrivate::~QOpenGLPaintDevicePrivate() +{ +} + class QOpenGLEngineThreadStorage { public: @@ -271,6 +275,9 @@ int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const return qRound(d_ptr->dpmy * 0.0254); case PdmDevicePixelRatio: return d_ptr->devicePixelRatio; + case PdmDevicePixelRatioScaled: + return d_ptr->devicePixelRatio * QPaintDevice::devicePixelRatioFScale(); + default: qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric); return 0; diff --git a/src/gui/opengl/qopenglpaintdevice_p.h b/src/gui/opengl/qopenglpaintdevice_p.h index 57d93ee80a..54ea09240d 100644 --- a/src/gui/opengl/qopenglpaintdevice_p.h +++ b/src/gui/opengl/qopenglpaintdevice_p.h @@ -56,7 +56,7 @@ class Q_GUI_EXPORT QOpenGLPaintDevicePrivate { public: QOpenGLPaintDevicePrivate(const QSize &size); - virtual ~QOpenGLPaintDevicePrivate() { } + virtual ~QOpenGLPaintDevicePrivate(); static QOpenGLPaintDevicePrivate *get(QOpenGLPaintDevice *dev) { return dev->d_func(); } diff --git a/src/gui/opengl/qopenglpixeltransferoptions.h b/src/gui/opengl/qopenglpixeltransferoptions.h index bf726813bd..cb4697ec7c 100644 --- a/src/gui/opengl/qopenglpixeltransferoptions.h +++ b/src/gui/opengl/qopenglpixeltransferoptions.h @@ -49,15 +49,14 @@ class Q_GUI_EXPORT QOpenGLPixelTransferOptions public: QOpenGLPixelTransferOptions(); QOpenGLPixelTransferOptions(const QOpenGLPixelTransferOptions &); - QOpenGLPixelTransferOptions &operator=(const QOpenGLPixelTransferOptions &); - ~QOpenGLPixelTransferOptions(); - #ifdef Q_COMPILER_RVALUE_REFS - QOpenGLPixelTransferOptions &operator=(QOpenGLPixelTransferOptions &&other) + QOpenGLPixelTransferOptions &operator=(QOpenGLPixelTransferOptions &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif + QOpenGLPixelTransferOptions &operator=(const QOpenGLPixelTransferOptions &); + ~QOpenGLPixelTransferOptions(); - void swap(QOpenGLPixelTransferOptions &other) + void swap(QOpenGLPixelTransferOptions &other) Q_DECL_NOTHROW { data.swap(other.data); } void setAlignment(int alignment); diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index 04b796ddb0..9714aa4bec 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -1783,7 +1783,7 @@ void QOpenGLShaderProgram::setAttributeBuffer Q_UNUSED(d); if (location != -1) { d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride, - reinterpret_cast<const void *>(offset)); + reinterpret_cast<const void *>(qintptr(offset))); } } diff --git a/src/gui/opengl/qopenglshaderprogram.h b/src/gui/opengl/qopenglshaderprogram.h index 9f5957e612..b959954718 100644 --- a/src/gui/opengl/qopenglshaderprogram.h +++ b/src/gui/opengl/qopenglshaderprogram.h @@ -66,7 +66,7 @@ public: }; Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit) - explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = 0); + explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = Q_NULLPTR); virtual ~QOpenGLShader(); QOpenGLShader::ShaderType shaderType() const; @@ -83,7 +83,7 @@ public: GLuint shaderId() const; - static bool hasOpenGLShaders(ShaderType type, QOpenGLContext *context = 0); + static bool hasOpenGLShaders(ShaderType type, QOpenGLContext *context = Q_NULLPTR); private: friend class QOpenGLShaderProgram; @@ -101,7 +101,7 @@ class Q_GUI_EXPORT QOpenGLShaderProgram : public QObject { Q_OBJECT public: - explicit QOpenGLShaderProgram(QObject *parent = 0); + explicit QOpenGLShaderProgram(QObject *parent = Q_NULLPTR); virtual ~QOpenGLShaderProgram(); bool addShader(QOpenGLShader *shader); @@ -288,7 +288,7 @@ public: void setUniformValueArray(const char *name, const QMatrix4x3 *values, int count); void setUniformValueArray(const char *name, const QMatrix4x4 *values, int count); - static bool hasOpenGLShaderPrograms(QOpenGLContext *context = 0); + static bool hasOpenGLShaderPrograms(QOpenGLContext *context = Q_NULLPTR); private Q_SLOTS: void shaderDestroyed(); diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 5271826015..301b2ad13d 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -401,6 +401,9 @@ static bool isSizedTextureFormat(QOpenGLTexture::TextureFormat internalFormat) case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: return true; + case QOpenGLTexture::RGB8_ETC1: + return false; + case QOpenGLTexture::DepthFormat: case QOpenGLTexture::AlphaFormat: @@ -442,20 +445,23 @@ static bool isTextureTargetMultisample(QOpenGLTexture::Target target) return false; } -void QOpenGLTexturePrivate::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) +bool QOpenGLTexturePrivate::isUsingImmutableStorage() const { - // Resolve the actual number of mipmap levels we can use - mipLevels = evaluateMipLevels(); - // Use immutable storage whenever possible, falling back to mutable // Note that if multisample textures are not supported at all, we'll still fail into // the mutable storage allocation - const bool useImmutableStorage = isSizedTextureFormat(format) + return isSizedTextureFormat(format) && (isTextureTargetMultisample(target) ? features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage) : features.testFlag(QOpenGLTexture::ImmutableStorage)); +} + +void QOpenGLTexturePrivate::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) +{ + // Resolve the actual number of mipmap levels we can use + mipLevels = evaluateMipLevels(); - if (useImmutableStorage) + if (isUsingImmutableStorage()) allocateImmutableStorage(); else allocateMutableStorage(pixelFormat, pixelType); @@ -663,6 +669,7 @@ static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpen case QOpenGLTexture::SRGB_Alpha_DXT3: case QOpenGLTexture::SRGB_Alpha_DXT5: case QOpenGLTexture::SRGB_BP_UNorm: + case QOpenGLTexture::RGB8_ETC1: return QOpenGLTexture::RGBA; case QOpenGLTexture::R11_EAC_UNorm: @@ -840,6 +847,7 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: case QOpenGLTexture::RGBA8_ETC2_EAC: case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: + case QOpenGLTexture::RGB8_ETC1: return QOpenGLTexture::UInt8; case QOpenGLTexture::DepthFormat: @@ -857,8 +865,133 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe return QOpenGLTexture::NoPixelType; } +static bool isCompressedFormat(QOpenGLTexture::TextureFormat internalFormat) +{ + switch (internalFormat) { + case QOpenGLTexture::NoFormat: + + case QOpenGLTexture::R8_UNorm: + case QOpenGLTexture::RG8_UNorm: + case QOpenGLTexture::RGB8_UNorm: + case QOpenGLTexture::RGBA8_UNorm: + case QOpenGLTexture::R16_UNorm: + case QOpenGLTexture::RG16_UNorm: + case QOpenGLTexture::RGB16_UNorm: + case QOpenGLTexture::RGBA16_UNorm: + case QOpenGLTexture::R8_SNorm: + case QOpenGLTexture::RG8_SNorm: + case QOpenGLTexture::RGB8_SNorm: + case QOpenGLTexture::RGBA8_SNorm: + case QOpenGLTexture::R16_SNorm: + case QOpenGLTexture::RG16_SNorm: + case QOpenGLTexture::RGB16_SNorm: + case QOpenGLTexture::RGBA16_SNorm: + case QOpenGLTexture::R8U: + case QOpenGLTexture::RG8U: + case QOpenGLTexture::RGB8U: + case QOpenGLTexture::RGBA8U: + case QOpenGLTexture::R16U: + case QOpenGLTexture::RG16U: + case QOpenGLTexture::RGB16U: + case QOpenGLTexture::RGBA16U: + case QOpenGLTexture::R32U: + case QOpenGLTexture::RG32U: + case QOpenGLTexture::RGB32U: + case QOpenGLTexture::RGBA32U: + case QOpenGLTexture::R8I: + case QOpenGLTexture::RG8I: + case QOpenGLTexture::RGB8I: + case QOpenGLTexture::RGBA8I: + case QOpenGLTexture::R16I: + case QOpenGLTexture::RG16I: + case QOpenGLTexture::RGB16I: + case QOpenGLTexture::RGBA16I: + case QOpenGLTexture::R32I: + case QOpenGLTexture::RG32I: + case QOpenGLTexture::RGB32I: + case QOpenGLTexture::RGBA32I: + case QOpenGLTexture::R16F: + case QOpenGLTexture::RG16F: + case QOpenGLTexture::RGB16F: + case QOpenGLTexture::RGBA16F: + case QOpenGLTexture::R32F: + case QOpenGLTexture::RG32F: + case QOpenGLTexture::RGB32F: + case QOpenGLTexture::RGBA32F: + case QOpenGLTexture::RGB9E5: + case QOpenGLTexture::RG11B10F: + case QOpenGLTexture::RG3B2: + case QOpenGLTexture::R5G6B5: + case QOpenGLTexture::RGB5A1: + case QOpenGLTexture::RGBA4: + case QOpenGLTexture::RGB10A2: + + case QOpenGLTexture::D16: + case QOpenGLTexture::D24: + case QOpenGLTexture::D32: + case QOpenGLTexture::D32F: + + case QOpenGLTexture::D24S8: + case QOpenGLTexture::D32FS8X24: + + case QOpenGLTexture::S8: + return false; + + case QOpenGLTexture::RGB_DXT1: + case QOpenGLTexture::RGBA_DXT1: + case QOpenGLTexture::RGBA_DXT3: + case QOpenGLTexture::RGBA_DXT5: + case QOpenGLTexture::R_ATI1N_UNorm: + case QOpenGLTexture::R_ATI1N_SNorm: + case QOpenGLTexture::RG_ATI2N_UNorm: + case QOpenGLTexture::RG_ATI2N_SNorm: + case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT: + case QOpenGLTexture::RGB_BP_SIGNED_FLOAT: + case QOpenGLTexture::RGB_BP_UNorm: + case QOpenGLTexture::SRGB8: + case QOpenGLTexture::SRGB8_Alpha8: + case QOpenGLTexture::SRGB_DXT1: + case QOpenGLTexture::SRGB_Alpha_DXT1: + case QOpenGLTexture::SRGB_Alpha_DXT3: + case QOpenGLTexture::SRGB_Alpha_DXT5: + case QOpenGLTexture::SRGB_BP_UNorm: + case QOpenGLTexture::R11_EAC_UNorm: + case QOpenGLTexture::R11_EAC_SNorm: + case QOpenGLTexture::RG11_EAC_UNorm: + case QOpenGLTexture::RG11_EAC_SNorm: + case QOpenGLTexture::RGB8_ETC2: + case QOpenGLTexture::SRGB8_ETC2: + case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: + case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: + case QOpenGLTexture::RGBA8_ETC2_EAC: + case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: + case QOpenGLTexture::RGB8_ETC1: + return true; + + case QOpenGLTexture::DepthFormat: + case QOpenGLTexture::AlphaFormat: + case QOpenGLTexture::RGBFormat: + case QOpenGLTexture::RGBAFormat: + case QOpenGLTexture::LuminanceFormat: + case QOpenGLTexture::LuminanceAlphaFormat: + return false; + } + + Q_UNREACHABLE(); + return false; +} + void QOpenGLTexturePrivate::allocateMutableStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) { + // There is no way to allocate mutable storage for compressed textures in in + // versions older than OpenGL 3.1 and OpenGL ES 3.0, because the older specs + // do not mandate accepting null data pointers for glCompressedTexImage*D, + // unlike glTexImage*D (which in turn does not accept compressed formats). + if (isCompressedFormat(format)) { + storageAllocated = true; + return; + } + switch (target) { case QOpenGLTexture::TargetBuffer: // Buffer textures get their storage from an external OpenGL buffer @@ -1196,86 +1329,121 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe int dataSize, const void *data, const QOpenGLPixelTransferOptions * const options) { + if (!isCompressedFormat(format)) { + qWarning("Cannot set compressed data for non-compressed format 0x%x", format); + return; + } + + const bool needsFullSpec = !isUsingImmutableStorage(); // was allocateStorage() a no-op? + switch (target) { case QOpenGLTexture::Target1D: Q_UNUSED(layer); Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel, - 0, mipLevelSize( mipLevel, dimensions[0] ), - format, dataSize, data, options); + if (needsFullSpec) { + texFuncs->glCompressedTextureImage1D(textureId, target, bindingTarget, mipLevel, + format, + mipLevelSize(mipLevel, dimensions[0]), + 0, dataSize, data, options); + } else { + texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel, + 0, mipLevelSize( mipLevel, dimensions[0] ), + format, dataSize, data, options); + } break; case QOpenGLTexture::Target1DArray: Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, - 0, layer, - mipLevelSize(mipLevel, dimensions[0]), - 1, - format, dataSize, data, options); + if (!needsFullSpec) { + texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, + 0, layer, + mipLevelSize(mipLevel, dimensions[0]), + 1, + format, dataSize, data, options); + } break; case QOpenGLTexture::Target2D: Q_UNUSED(layer); Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, - 0, 0, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - format, dataSize, data, options); + if (needsFullSpec) { + texFuncs->glCompressedTextureImage2D(textureId, target, bindingTarget, mipLevel, + format, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + 0, dataSize, data, options); + } else { + texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, + 0, 0, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + format, dataSize, data, options); + } break; case QOpenGLTexture::Target2DArray: Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, - 0, 0, layer, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - 1, - format, dataSize, data, options); + if (!needsFullSpec) { + texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + 0, 0, layer, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + 1, + format, dataSize, data, options); + } break; case QOpenGLTexture::Target3D: Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, - 0, 0, layer, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - mipLevelSize(mipLevel, dimensions[2]), - format, dataSize, data, options); + if (needsFullSpec) { + texFuncs->glCompressedTextureImage3D(textureId, target, bindingTarget, mipLevel, + format, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + mipLevelSize(mipLevel, dimensions[2]), + 0, dataSize, data, options); + } else { + texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + 0, 0, layer, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + mipLevelSize(mipLevel, dimensions[2]), + format, dataSize, data, options); + } break; case QOpenGLTexture::TargetCubeMap: Q_UNUSED(layer); - texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel, - 0, 0, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - format, dataSize, data, options); + if (needsFullSpec) { + texFuncs->glCompressedTextureImage2D(textureId, cubeFace, bindingTarget, mipLevel, + format, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + 0, dataSize, data, options); + } else { + texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel, + 0, 0, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + format, dataSize, data, options); + } break; case QOpenGLTexture::TargetCubeMapArray: { int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX; int layerFace = 6 * layer + faceIndex; - texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, - 0, 0, layerFace, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - 1, - format, dataSize, data, options); + if (!needsFullSpec) { + texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + 0, 0, layerFace, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + 1, + format, dataSize, data, options); + } break; } case QOpenGLTexture::TargetRectangle: - Q_UNUSED(mipLevel); - Q_UNUSED(layer); - Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, 0, - 0, 0, - dimensions[0], - dimensions[1], - format, dataSize, data, options); - break; - case QOpenGLTexture::Target2DMultisample: case QOpenGLTexture::Target2DMultisampleArray: case QOpenGLTexture::TargetBuffer: @@ -1857,6 +2025,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target \value SRGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 \value RGBA8_ETC2_EAC Equivalent to GL_COMPRESSED_RGBA8_ETC2_EAC \value SRGB8_Alpha8_ETC2_EAC Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC + \value RGB8_ETC1 Equivalent to GL_ETC1_RGB8_OES \value SRGB8 Equivalent to GL_SRGB8 \value SRGB8_Alpha8 Equivalent to GL_SRGB8_ALPHA8 @@ -2394,6 +2563,7 @@ void QOpenGLTexture::setFormat(TextureFormat format) case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: case QOpenGLTexture::RGBA8_ETC2_EAC: case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: + case QOpenGLTexture::RGB8_ETC1: case RG3B2: case R5G6B5: case RGB5A1: @@ -3458,6 +3628,8 @@ QPair<int, int> QOpenGLTexture::mipLevelRange() const The automatic mipmap generation is enabled by default. + \note Mipmap generation is not supported for compressed textures with OpenGL ES 2.0. + \sa isAutoMipMapGenerationEnabled(), generateMipMaps() */ void QOpenGLTexture::setAutoMipMapGenerationEnabled(bool enabled) @@ -3483,6 +3655,9 @@ bool QOpenGLTexture::isAutoMipMapGenerationEnabled() const have disabled automatic mipmap generation then you need to call this function or the overload to create the mipmap chain. + \note Mipmap generation is not supported for compressed textures with OpenGL + ES 2.0. + \sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels() */ void QOpenGLTexture::generateMipMaps() @@ -3490,6 +3665,11 @@ void QOpenGLTexture::generateMipMaps() Q_D(QOpenGLTexture); Q_ASSERT(d->texFuncs); Q_ASSERT(d->textureId); + if (isCompressedFormat(d->format)) { + if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) + if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3) + return; + } d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget); } @@ -3510,6 +3690,11 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel) Q_D(QOpenGLTexture); Q_ASSERT(d->texFuncs); Q_ASSERT(d->textureId); + if (isCompressedFormat(d->format)) { + if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) + if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3) + return; + } int oldBaseLevel; if (resetBaseLevel) oldBaseLevel = mipBaseLevel(); diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h index 3017aac737..ec52a192fa 100644 --- a/src/gui/opengl/qopengltexture.h +++ b/src/gui/opengl/qopengltexture.h @@ -196,6 +196,7 @@ public: SRGB8_PunchThrough_Alpha1_ETC2 = 0x9277, // GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 RGBA8_ETC2_EAC = 0x9278, // GL_COMPRESSED_RGBA8_ETC2_EAC SRGB8_Alpha8_ETC2_EAC = 0x9279, // GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC + RGB8_ETC1 = 0x8D64, // GL_ETC1_RGB8_OES // sRGB formats SRGB8 = 0x8C41, // GL_SRGB8 @@ -409,54 +410,54 @@ public: #if QT_DEPRECATED_SINCE(5, 3) QT_DEPRECATED void setData(int mipLevel, int layer, CubeMapFace cubeFace, PixelFormat sourceFormat, PixelType sourceType, - void *data, const QOpenGLPixelTransferOptions * const options = 0); + void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setData(int mipLevel, int layer, PixelFormat sourceFormat, PixelType sourceType, - void *data, const QOpenGLPixelTransferOptions * const options = 0); + void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setData(int mipLevel, PixelFormat sourceFormat, PixelType sourceType, - void *data, const QOpenGLPixelTransferOptions * const options = 0); + void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setData(PixelFormat sourceFormat, PixelType sourceType, - void *data, const QOpenGLPixelTransferOptions * const options = 0); + void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); #endif // QT_DEPRECATED_SINCE(5, 3) void setData(int mipLevel, int layer, CubeMapFace cubeFace, PixelFormat sourceFormat, PixelType sourceType, - const void *data, const QOpenGLPixelTransferOptions * const options = 0); + const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setData(int mipLevel, int layer, PixelFormat sourceFormat, PixelType sourceType, - const void *data, const QOpenGLPixelTransferOptions * const options = 0); + const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setData(int mipLevel, PixelFormat sourceFormat, PixelType sourceType, - const void *data, const QOpenGLPixelTransferOptions * const options = 0); + const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setData(PixelFormat sourceFormat, PixelType sourceType, - const void *data, const QOpenGLPixelTransferOptions * const options = 0); + const void *data, const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); // Compressed data upload // ### Qt 6: remove the non-const void * overloads #if QT_DEPRECATED_SINCE(5, 3) QT_DEPRECATED void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace, int dataSize, void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setCompressedData(int mipLevel, int layer, int dataSize, void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setCompressedData(int mipLevel, int dataSize, void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); QT_DEPRECATED void setCompressedData(int dataSize, void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); #endif // QT_DEPRECATED_SINCE(5, 3) void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace, int dataSize, const void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setCompressedData(int mipLevel, int layer, int dataSize, const void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setCompressedData(int mipLevel, int dataSize, const void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); void setCompressedData(int dataSize, const void *data, - const QOpenGLPixelTransferOptions * const options = 0); + const QOpenGLPixelTransferOptions * const options = Q_NULLPTR); // Helpful overloads for setData void setData(const QImage& image, MipMapGeneration genMipMaps = GenerateMipMaps); diff --git a/src/gui/opengl/qopengltexture_p.h b/src/gui/opengl/qopengltexture_p.h index be4bf0e93c..ac9d44db42 100644 --- a/src/gui/opengl/qopengltexture_p.h +++ b/src/gui/opengl/qopengltexture_p.h @@ -117,6 +117,8 @@ public: return std::floor(double(qMax(1, baseLevelSize >> mipLevel))); } + bool isUsingImmutableStorage() const; + QOpenGLTexture *q_ptr; QOpenGLContext *context; QOpenGLTexture::Target target; diff --git a/src/gui/opengl/qopengltexturehelper_p.h b/src/gui/opengl/qopengltexturehelper_p.h index 5a56516b49..d659fcedfb 100644 --- a/src/gui/opengl/qopengltexturehelper_p.h +++ b/src/gui/opengl/qopengltexturehelper_p.h @@ -253,23 +253,48 @@ public: inline void glCompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, - GLint border, GLsizei imageSize, const GLvoid *bits) + GLint border, GLsizei imageSize, const GLvoid *bits, + const QOpenGLPixelTransferOptions * const options = 0) { - (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits); + if (options) { + QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions(); + setPixelUploadOptions(*options); + (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits); + setPixelUploadOptions(oldOptions); + } else { + (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits); + } } inline void glCompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, - GLint border, GLsizei imageSize, const GLvoid *bits) + GLint border, GLsizei imageSize, const GLvoid *bits, + const QOpenGLPixelTransferOptions * const options = 0) + { - (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits); + if (options) { + QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions(); + setPixelUploadOptions(*options); + (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits); + setPixelUploadOptions(oldOptions); + } else { + (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits); + } } inline void glCompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLsizei imageSize, const GLvoid *bits) + GLint border, GLsizei imageSize, const GLvoid *bits, + const QOpenGLPixelTransferOptions * const options = 0) { - (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits); + if (options) { + QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions(); + setPixelUploadOptions(*options); + (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits); + setPixelUploadOptions(oldOptions); + } else { + (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits); + } } private: diff --git a/src/gui/opengl/qopengltimerquery.h b/src/gui/opengl/qopengltimerquery.h index 7e46250546..ad111dc03c 100644 --- a/src/gui/opengl/qopengltimerquery.h +++ b/src/gui/opengl/qopengltimerquery.h @@ -50,7 +50,7 @@ class Q_GUI_EXPORT QOpenGLTimerQuery : public QObject Q_OBJECT public: - explicit QOpenGLTimerQuery(QObject *parent = 0); + explicit QOpenGLTimerQuery(QObject *parent = Q_NULLPTR); ~QOpenGLTimerQuery(); bool create(); @@ -78,7 +78,7 @@ class Q_GUI_EXPORT QOpenGLTimeMonitor : public QObject Q_OBJECT public: - explicit QOpenGLTimeMonitor(QObject *parent = 0); + explicit QOpenGLTimeMonitor(QObject *parent = Q_NULLPTR); ~QOpenGLTimeMonitor(); void setSampleCount(int sampleCount); diff --git a/src/gui/opengl/qopenglversionfunctions.h b/src/gui/opengl/qopenglversionfunctions.h index fcf665f97e..a5d5677938 100644 --- a/src/gui/opengl/qopenglversionfunctions.h +++ b/src/gui/opengl/qopenglversionfunctions.h @@ -47,7 +47,10 @@ #ifndef QT_NO_OPENGL +#if QT_DEPRECATED_SINCE(5, 5) #include <QtCore/qhash.h> +#endif +#include <QtCore/qhashfunctions.h> #include <QtCore/qpair.h> #include <QtGui/qopengl.h> @@ -120,7 +123,7 @@ class QAbstractOpenGLFunctionsPrivate { public: QAbstractOpenGLFunctionsPrivate() - : owningContext(0), + : owningContext(Q_NULLPTR), initialized(false) {} diff --git a/src/gui/opengl/qopenglvertexarrayobject.h b/src/gui/opengl/qopenglvertexarrayobject.h index 3e01d31202..e8ebf41071 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.h +++ b/src/gui/opengl/qopenglvertexarrayobject.h @@ -50,7 +50,7 @@ class Q_GUI_EXPORT QOpenGLVertexArrayObject : public QObject Q_OBJECT public: - explicit QOpenGLVertexArrayObject(QObject* parent = 0); + explicit QOpenGLVertexArrayObject(QObject* parent = Q_NULLPTR); ~QOpenGLVertexArrayObject(); bool create(); diff --git a/src/gui/opengl/qtriangulatingstroker.cpp b/src/gui/opengl/qtriangulatingstroker.cpp index cfbf8a75c5..5967bd6e89 100644 --- a/src/gui/opengl/qtriangulatingstroker.cpp +++ b/src/gui/opengl/qtriangulatingstroker.cpp @@ -127,7 +127,7 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, co m_roundness = 1; } else if (cosmetic) { m_curvyness_add = realWidth / 2; - m_curvyness_mul = CURVE_FLATNESS; + m_curvyness_mul = float(CURVE_FLATNESS); m_roundness = qMax<int>(4, realWidth * CURVE_FLATNESS); } else { m_curvyness_add = m_width; @@ -543,7 +543,7 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c curvynessMul = CURVE_FLATNESS / m_inv_scale; } else if (cosmetic) { curvynessAdd= width / 2; - curvynessMul= CURVE_FLATNESS; + curvynessMul= float(CURVE_FLATNESS); } else { curvynessAdd = width * m_inv_scale; curvynessMul = CURVE_FLATNESS / m_inv_scale; |