/****************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
**
** This file was generated by glgen version 0.1
** Command line was: glgen
**
** glgen is Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
**
** This is an auto-generated file.
** Do not edit! All changes made to it will be lost.
**
****************************************************************************/

#ifndef QOPENGLVERSIONFUNCTIONS_H
#define QOPENGLVERSIONFUNCTIONS_H

#include <QtOpenGL/qtopenglglobal.h>

#ifndef QT_NO_OPENGL

#include <QtCore/qhashfunctions.h>
#include <QtCore/qpair.h>
#include <QtGui/qopengl.h>

// MemoryBarrier is a macro on some architectures on Windows
#ifdef Q_OS_WIN
#pragma push_macro("MemoryBarrier")
#undef MemoryBarrier
#endif

QT_BEGIN_NAMESPACE

class QOpenGLContext;

#if 0
// silence syncqt warnings
#pragma qt_class(QOpenGLVersionFunctions)
#pragma qt_sync_stop_processing
#endif

struct QOpenGLVersionStatus
{
    enum OpenGLStatus {
        CoreStatus,
        DeprecatedStatus,
        InvalidStatus
    };

    constexpr QOpenGLVersionStatus()
        : version(0, 0),
          status(InvalidStatus)
    {}

    constexpr QOpenGLVersionStatus(int majorVersion, int minorVersion, QOpenGLVersionStatus::OpenGLStatus functionStatus)
        : version(majorVersion, minorVersion),
          status(functionStatus)
    {}

    QPair<int, int> version;
    OpenGLStatus status;

    friend constexpr bool operator==(const QOpenGLVersionStatus &lhs, const QOpenGLVersionStatus &rhs) noexcept
    {
        return lhs.status == rhs.status && lhs.version == rhs.version;
    }

    friend constexpr bool operator!=(const QOpenGLVersionStatus &lhs, const QOpenGLVersionStatus &rhs) noexcept
    {
        return !(lhs == rhs);
    }
};

inline size_t qHash(const QOpenGLVersionStatus &v, size_t seed = 0) noexcept
{
    return qHash(static_cast<int>(v.status * 1000)
               + v.version.first * 100 + v.version.second * 10, seed);
}

#define QT_OPENGL_DECLARE_FUNCTIONS(ret, name, args) \
    ret (QOPENGLF_APIENTRYP name)args;
#define QT_OPENGL_COUNT_FUNCTIONS(ret, name, args) +1

#define QT_OPENGL_DECLARE(FUNCTIONS) \
public: \
    struct Functions { \
        FUNCTIONS(QT_OPENGL_DECLARE_FUNCTIONS) \
    }; \
    union { \
        QFunctionPointer functions[FUNCTIONS(QT_OPENGL_COUNT_FUNCTIONS)]; \
        Functions f; \
    }; \
private: \
    void init()

class QOpenGLVersionFunctionsBackend
{
public:
#define QT_OPENGL_VERSIONS(F) \
        F(1_0_Core) \
        F(1_1_Core) \
        F(1_2_Core) \
        F(1_3_Core) \
        F(1_4_Core) \
        F(1_5_Core) \
        F(2_0_Core) \
        F(2_1_Core) \
        F(3_0_Core) \
        F(3_1_Core) \
        F(3_2_Core) \
        F(3_3_Core) \
        F(4_0_Core) \
        F(4_1_Core) \
        F(4_2_Core) \
        F(4_3_Core) \
        F(4_4_Core) \
        F(4_5_Core) \
        F(1_0_Deprecated) \
        F(1_1_Deprecated) \
        F(1_2_Deprecated) \
        F(1_3_Deprecated) \
        F(1_4_Deprecated) \
        F(2_0_Deprecated) \
        F(3_0_Deprecated) \
        F(3_3_Deprecated) \
        F(4_5_Deprecated) \

#define VERSION_ENUM(X) OpenGL_##X,
    enum Version {
        QT_OPENGL_VERSIONS(VERSION_ENUM)
        OpenGLVersionBackendCount
    };
#undef VERSION_ENUM

    QOpenGLVersionFunctionsBackend(QOpenGLContext *ctx)
        : context(ctx)
    {}

    QOpenGLContext *context;
    QAtomicInt refs;
};

class QOpenGLVersionFunctionsStorage
{
public:
    QOpenGLVersionFunctionsStorage();
    ~QOpenGLVersionFunctionsStorage();

    QOpenGLVersionFunctionsBackend *backend(QOpenGLContext *context, QOpenGLVersionFunctionsBackend::Version v);

    QOpenGLVersionFunctionsBackend **backends;
};

class QAbstractOpenGLFunctions;

class QAbstractOpenGLFunctionsPrivate
{
public:
    QAbstractOpenGLFunctionsPrivate()
        : owningContext(nullptr),
          initialized(false)
    {}

    static QOpenGLVersionFunctionsBackend *functionsBackend(QOpenGLContext *context, QOpenGLVersionFunctionsBackend::Version v);
    static void insertExternalFunctions(QOpenGLContext *context, QAbstractOpenGLFunctions *f);
    static void removeExternalFunctions(QOpenGLContext *context, QAbstractOpenGLFunctions *f);

    static QAbstractOpenGLFunctionsPrivate *get(QAbstractOpenGLFunctions *q);

    QOpenGLContext *owningContext;
    bool initialized;
};

class Q_OPENGL_EXPORT QAbstractOpenGLFunctions
{
public:
    virtual ~QAbstractOpenGLFunctions();

    virtual bool initializeOpenGLFunctions();

    Q_DISABLE_COPY(QAbstractOpenGLFunctions)
    Q_DECLARE_PRIVATE(QAbstractOpenGLFunctions)

protected:
    QAbstractOpenGLFunctions();
    QAbstractOpenGLFunctionsPrivate *d_ptr;

    bool isInitialized() const;

    void setOwningContext(const QOpenGLContext *context);
    QOpenGLContext *owningContext() const;

    friend class QOpenGLVersionFunctionsFactory;
};

inline QAbstractOpenGLFunctionsPrivate *QAbstractOpenGLFunctionsPrivate::get(QAbstractOpenGLFunctions *q)
{
    return q->d_func();
}

#if !QT_CONFIG(opengles2)

class QOpenGLFunctions_1_0_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_0_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_0_Core; }

    // OpenGL 1.0 core functions
#define QT_OPENGL_1_0_FUNCTIONS(F) \
    F(void, Viewport, (GLint x, GLint y, GLsizei width, GLsizei height)) \
    F(void, DepthRange, (GLdouble nearVal, GLdouble farVal)) \
    F(GLboolean, IsEnabled, (GLenum cap)) \
    F(void, GetTexLevelParameteriv, (GLenum target, GLint level, GLenum pname, GLint *params)) \
    F(void, GetTexLevelParameterfv, (GLenum target, GLint level, GLenum pname, GLfloat *params)) \
    F(void, GetTexParameteriv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, GetTexParameterfv, (GLenum target, GLenum pname, GLfloat *params)) \
    F(void, GetTexImage, (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)) \
    F(const GLubyte *, GetString, (GLenum name)) \
    F(void, GetIntegerv, (GLenum pname, GLint *data)) \
    F(void, GetFloatv, (GLenum pname, GLfloat *data)) \
    F(GLenum, GetError, ()) \
    F(void, GetDoublev, (GLenum pname, GLdouble *data)) \
    F(void, GetBooleanv, (GLenum pname, GLboolean *data)) \
    F(void, ReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)) \
    F(void, ReadBuffer, (GLenum src)) \
    F(void, PixelStorei, (GLenum pname, GLint param)) \
    F(void, PixelStoref, (GLenum pname, GLfloat param)) \
    F(void, DepthFunc, (GLenum func)) \
    F(void, StencilOp, (GLenum fail, GLenum zfail, GLenum zpass)) \
    F(void, StencilFunc, (GLenum func, GLint ref, GLuint mask)) \
    F(void, LogicOp, (GLenum opcode)) \
    F(void, BlendFunc, (GLenum sfactor, GLenum dfactor)) \
    F(void, Flush, ()) \
    F(void, Finish, ()) \
    F(void, Enable, (GLenum cap)) \
    F(void, Disable, (GLenum cap)) \
    F(void, DepthMask, (GLboolean flag)) \
    F(void, ColorMask, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) \
    F(void, StencilMask, (GLuint mask)) \
    F(void, ClearDepth, (GLdouble depth)) \
    F(void, ClearStencil, (GLint s)) \
    F(void, ClearColor, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) \
    F(void, Clear, (GLbitfield mask)) \
    F(void, DrawBuffer, (GLenum buf)) \
    F(void, TexImage2D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) \
    F(void, TexImage1D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) \
    F(void, TexParameteriv, (GLenum target, GLenum pname, const GLint *params)) \
    F(void, TexParameteri, (GLenum target, GLenum pname, GLint param)) \
    F(void, TexParameterfv, (GLenum target, GLenum pname, const GLfloat *params)) \
    F(void, TexParameterf, (GLenum target, GLenum pname, GLfloat param)) \
    F(void, Scissor, (GLint x, GLint y, GLsizei width, GLsizei height)) \
    F(void, PolygonMode, (GLenum face, GLenum mode)) \
    F(void, PointSize, (GLfloat size)) \
    F(void, LineWidth, (GLfloat width)) \
    F(void, Hint, (GLenum target, GLenum mode)) \
    F(void, FrontFace, (GLenum mode)) \
    F(void, CullFace, (GLenum mode)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_0_FUNCTIONS);
};

class QOpenGLFunctions_1_1_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_1_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_1_Core; }

    // OpenGL 1.1 core functions
#define QT_OPENGL_1_1_FUNCTIONS(F) \
    F(void, Indexubv, (const GLubyte *c)) \
    F(void, Indexub, (GLubyte c)) \
    F(GLboolean, IsTexture, (GLuint texture)) \
    F(void, GenTextures, (GLsizei n, GLuint *textures)) \
    F(void, DeleteTextures, (GLsizei n, const GLuint *textures)) \
    F(void, BindTexture, (GLenum target, GLuint texture)) \
    F(void, TexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) \
    F(void, TexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)) \
    F(void, CopyTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)) \
    F(void, CopyTexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)) \
    F(void, CopyTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)) \
    F(void, CopyTexImage1D, (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border)) \
    F(void, PolygonOffset, (GLfloat factor, GLfloat units)) \
    F(void, GetPointerv, (GLenum pname, GLvoid* *params)) \
    F(void, DrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)) \
    F(void, DrawArrays, (GLenum mode, GLint first, GLsizei count)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_1_FUNCTIONS);
};

class QOpenGLFunctions_1_2_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_2_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_2_Core; }

    // OpenGL 1.2 core functions
#define QT_OPENGL_1_2_FUNCTIONS(F) \
    F(void, CopyTexSubImage3D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)) \
    F(void, TexSubImage3D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)) \
    F(void, TexImage3D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) \
    F(void, DrawRangeElements, (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)) \
    F(void, BlendEquation, (GLenum mode)) \
    F(void, BlendColor, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_2_FUNCTIONS);
};

class QOpenGLFunctions_1_3_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_3_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_3_Core; }

    // OpenGL 1.3 core functions
#define QT_OPENGL_1_3_FUNCTIONS(F) \
    F(void, GetCompressedTexImage, (GLenum target, GLint level, GLvoid *img)) \
    F(void, CompressedTexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data)) \
    F(void, CompressedTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)) \
    F(void, CompressedTexSubImage3D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data)) \
    F(void, CompressedTexImage1D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data)) \
    F(void, CompressedTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)) \
    F(void, CompressedTexImage3D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data)) \
    F(void, SampleCoverage, (GLfloat value, GLboolean invert)) \
    F(void, ActiveTexture, (GLenum texture)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_3_FUNCTIONS);
};

class QOpenGLFunctions_1_4_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_4_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_4_Core; }

    // OpenGL 1.4 core functions
#define QT_OPENGL_1_4_FUNCTIONS(F) \
    F(void, PointParameteriv, (GLenum pname, const GLint *params)) \
    F(void, PointParameteri, (GLenum pname, GLint param)) \
    F(void, PointParameterfv, (GLenum pname, const GLfloat *params)) \
    F(void, PointParameterf, (GLenum pname, GLfloat param)) \
    F(void, MultiDrawElements, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount)) \
    F(void, MultiDrawArrays, (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount)) \
    F(void, BlendFuncSeparate, (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_4_FUNCTIONS);
};

class QOpenGLFunctions_1_5_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_5_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_5_Core; }

    // OpenGL 1.5 core functions
#define QT_OPENGL_1_5_FUNCTIONS(F) \
    F(void, GetBufferPointerv, (GLenum target, GLenum pname, GLvoid* *params)) \
    F(void, GetBufferParameteriv, (GLenum target, GLenum pname, GLint *params)) \
    F(GLboolean, UnmapBuffer, (GLenum target)) \
    F(GLvoid*, MapBuffer, (GLenum target, GLenum access)) \
    F(void, GetBufferSubData, (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data)) \
    F(void, BufferSubData, (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)) \
    F(void, BufferData, (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)) \
    F(GLboolean, IsBuffer, (GLuint buffer)) \
    F(void, GenBuffers, (GLsizei n, GLuint *buffers)) \
    F(void, DeleteBuffers, (GLsizei n, const GLuint *buffers)) \
    F(void, BindBuffer, (GLenum target, GLuint buffer)) \
    F(void, GetQueryObjectuiv, (GLuint id, GLenum pname, GLuint *params)) \
    F(void, GetQueryObjectiv, (GLuint id, GLenum pname, GLint *params)) \
    F(void, GetQueryiv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, EndQuery, (GLenum target)) \
    F(void, BeginQuery, (GLenum target, GLuint id)) \
    F(GLboolean, IsQuery, (GLuint id)) \
    F(void, DeleteQueries, (GLsizei n, const GLuint *ids)) \
    F(void, GenQueries, (GLsizei n, GLuint *ids)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_5_FUNCTIONS);
};

class QOpenGLFunctions_2_0_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_2_0_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_2_0_Core; }

    // OpenGL 2.0 core functions
#define QT_OPENGL_2_0_FUNCTIONS(F) \
    F(void, VertexAttribPointer, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer)) \
    F(void, ValidateProgram, (GLuint program)) \
    F(void, UniformMatrix4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, UniformMatrix3fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, UniformMatrix2fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, Uniform4iv, (GLint location, GLsizei count, const GLint *value)) \
    F(void, Uniform3iv, (GLint location, GLsizei count, const GLint *value)) \
    F(void, Uniform2iv, (GLint location, GLsizei count, const GLint *value)) \
    F(void, Uniform1iv, (GLint location, GLsizei count, const GLint *value)) \
    F(void, Uniform4fv, (GLint location, GLsizei count, const GLfloat *value)) \
    F(void, Uniform3fv, (GLint location, GLsizei count, const GLfloat *value)) \
    F(void, Uniform2fv, (GLint location, GLsizei count, const GLfloat *value)) \
    F(void, Uniform1fv, (GLint location, GLsizei count, const GLfloat *value)) \
    F(void, Uniform4i, (GLint location, GLint v0, GLint v1, GLint v2, GLint v3)) \
    F(void, Uniform3i, (GLint location, GLint v0, GLint v1, GLint v2)) \
    F(void, Uniform2i, (GLint location, GLint v0, GLint v1)) \
    F(void, Uniform1i, (GLint location, GLint v0)) \
    F(void, Uniform4f, (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)) \
    F(void, Uniform3f, (GLint location, GLfloat v0, GLfloat v1, GLfloat v2)) \
    F(void, Uniform2f, (GLint location, GLfloat v0, GLfloat v1)) \
    F(void, Uniform1f, (GLint location, GLfloat v0)) \
    F(void, UseProgram, (GLuint program)) \
    F(void, ShaderSource, (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length)) \
    F(void, LinkProgram, (GLuint program)) \
    F(GLboolean, IsShader, (GLuint shader)) \
    F(GLboolean, IsProgram, (GLuint program)) \
    F(void, GetVertexAttribPointerv, (GLuint index, GLenum pname, GLvoid* *pointer)) \
    F(void, GetVertexAttribiv, (GLuint index, GLenum pname, GLint *params)) \
    F(void, GetVertexAttribfv, (GLuint index, GLenum pname, GLfloat *params)) \
    F(void, GetVertexAttribdv, (GLuint index, GLenum pname, GLdouble *params)) \
    F(void, GetUniformiv, (GLuint program, GLint location, GLint *params)) \
    F(void, GetUniformfv, (GLuint program, GLint location, GLfloat *params)) \
    F(GLint, GetUniformLocation, (GLuint program, const GLchar *name)) \
    F(void, GetShaderSource, (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source)) \
    F(void, GetShaderInfoLog, (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)) \
    F(void, GetShaderiv, (GLuint shader, GLenum pname, GLint *params)) \
    F(void, GetProgramInfoLog, (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)) \
    F(void, GetProgramiv, (GLuint program, GLenum pname, GLint *params)) \
    F(GLint, GetAttribLocation, (GLuint program, const GLchar *name)) \
    F(void, GetAttachedShaders, (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders)) \
    F(void, GetActiveUniform, (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)) \
    F(void, GetActiveAttrib, (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)) \
    F(void, EnableVertexAttribArray, (GLuint index)) \
    F(void, DisableVertexAttribArray, (GLuint index)) \
    F(void, DetachShader, (GLuint program, GLuint shader)) \
    F(void, DeleteShader, (GLuint shader)) \
    F(void, DeleteProgram, (GLuint program)) \
    F(GLuint, CreateShader, (GLenum type)) \
    F(GLuint, CreateProgram, ()) \
    F(void, CompileShader, (GLuint shader)) \
    F(void, BindAttribLocation, (GLuint program, GLuint index, const GLchar *name)) \
    F(void, AttachShader, (GLuint program, GLuint shader)) \
    F(void, StencilMaskSeparate, (GLenum face, GLuint mask)) \
    F(void, StencilFuncSeparate, (GLenum face, GLenum func, GLint ref, GLuint mask)) \
    F(void, StencilOpSeparate, (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)) \
    F(void, DrawBuffers, (GLsizei n, const GLenum *bufs)) \
    F(void, BlendEquationSeparate, (GLenum modeRGB, GLenum modeAlpha)) \
    F(void, VertexAttrib4usv, (GLuint index, const GLushort *v)) \
    F(void, VertexAttrib4uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttrib4ubv, (GLuint index, const GLubyte *v)) \
    F(void, VertexAttrib4sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib4s, (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)) \
    F(void, VertexAttrib4iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttrib4fv, (GLuint index, const GLfloat *v)) \
    F(void, VertexAttrib4f, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)) \
    F(void, VertexAttrib4dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttrib4d, (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) \
    F(void, VertexAttrib4bv, (GLuint index, const GLbyte *v)) \
    F(void, VertexAttrib4Nusv, (GLuint index, const GLushort *v)) \
    F(void, VertexAttrib4Nuiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttrib4Nubv, (GLuint index, const GLubyte *v)) \
    F(void, VertexAttrib4Nub, (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)) \
    F(void, VertexAttrib4Nsv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib4Niv, (GLuint index, const GLint *v)) \
    F(void, VertexAttrib4Nbv, (GLuint index, const GLbyte *v)) \
    F(void, VertexAttrib3sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib3s, (GLuint index, GLshort x, GLshort y, GLshort z)) \
    F(void, VertexAttrib3fv, (GLuint index, const GLfloat *v)) \
    F(void, VertexAttrib3f, (GLuint index, GLfloat x, GLfloat y, GLfloat z)) \
    F(void, VertexAttrib3dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttrib3d, (GLuint index, GLdouble x, GLdouble y, GLdouble z)) \
    F(void, VertexAttrib2sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib2s, (GLuint index, GLshort x, GLshort y)) \
    F(void, VertexAttrib2fv, (GLuint index, const GLfloat *v)) \
    F(void, VertexAttrib2f, (GLuint index, GLfloat x, GLfloat y)) \
    F(void, VertexAttrib2dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttrib2d, (GLuint index, GLdouble x, GLdouble y)) \
    F(void, VertexAttrib1sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib1s, (GLuint index, GLshort x)) \
    F(void, VertexAttrib1fv, (GLuint index, const GLfloat *v)) \
    F(void, VertexAttrib1f, (GLuint index, GLfloat x)) \
    F(void, VertexAttrib1dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttrib1d, (GLuint index, GLdouble x)) \

    QT_OPENGL_DECLARE(QT_OPENGL_2_0_FUNCTIONS);
};

class QOpenGLFunctions_2_1_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_2_1_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_2_1_Core; }

    // OpenGL 2.1 core functions
#define QT_OPENGL_2_1_FUNCTIONS(F) \
    F(void, UniformMatrix4x3fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, UniformMatrix3x4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, UniformMatrix4x2fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, UniformMatrix2x4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, UniformMatrix3x2fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, UniformMatrix2x3fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \

    QT_OPENGL_DECLARE(QT_OPENGL_2_1_FUNCTIONS);
};

class QOpenGLFunctions_3_0_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_3_0_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_3_0_Core; }

    // OpenGL 3.0 core functions
#define QT_OPENGL_3_0_FUNCTIONS(F) \
    F(GLboolean, IsVertexArray, (GLuint array)) \
    F(void, GenVertexArrays, (GLsizei n, GLuint *arrays)) \
    F(void, DeleteVertexArrays, (GLsizei n, const GLuint *arrays)) \
    F(void, BindVertexArray, (GLuint array)) \
    F(void, FlushMappedBufferRange, (GLenum target, GLintptr offset, GLsizeiptr length)) \
    F(GLvoid *, MapBufferRange, (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)) \
    F(void, FramebufferTextureLayer, (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)) \
    F(void, RenderbufferStorageMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)) \
    F(void, BlitFramebuffer, (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)) \
    F(void, GenerateMipmap, (GLenum target)) \
    F(void, GetFramebufferAttachmentParameteriv, (GLenum target, GLenum attachment, GLenum pname, GLint *params)) \
    F(void, FramebufferRenderbuffer, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)) \
    F(void, FramebufferTexture3D, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)) \
    F(void, FramebufferTexture2D, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)) \
    F(void, FramebufferTexture1D, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)) \
    F(GLenum, CheckFramebufferStatus, (GLenum target)) \
    F(void, GenFramebuffers, (GLsizei n, GLuint *framebuffers)) \
    F(void, DeleteFramebuffers, (GLsizei n, const GLuint *framebuffers)) \
    F(void, BindFramebuffer, (GLenum target, GLuint framebuffer)) \
    F(GLboolean, IsFramebuffer, (GLuint framebuffer)) \
    F(void, GetRenderbufferParameteriv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, RenderbufferStorage, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height)) \
    F(void, GenRenderbuffers, (GLsizei n, GLuint *renderbuffers)) \
    F(void, DeleteRenderbuffers, (GLsizei n, const GLuint *renderbuffers)) \
    F(void, BindRenderbuffer, (GLenum target, GLuint renderbuffer)) \
    F(GLboolean, IsRenderbuffer, (GLuint renderbuffer)) \
    F(const GLubyte *, GetStringi, (GLenum name, GLuint index)) \
    F(void, ClearBufferfi, (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)) \
    F(void, ClearBufferfv, (GLenum buffer, GLint drawbuffer, const GLfloat *value)) \
    F(void, ClearBufferuiv, (GLenum buffer, GLint drawbuffer, const GLuint *value)) \
    F(void, ClearBufferiv, (GLenum buffer, GLint drawbuffer, const GLint *value)) \
    F(void, GetTexParameterIuiv, (GLenum target, GLenum pname, GLuint *params)) \
    F(void, GetTexParameterIiv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, TexParameterIuiv, (GLenum target, GLenum pname, const GLuint *params)) \
    F(void, TexParameterIiv, (GLenum target, GLenum pname, const GLint *params)) \
    F(void, Uniform4uiv, (GLint location, GLsizei count, const GLuint *value)) \
    F(void, Uniform3uiv, (GLint location, GLsizei count, const GLuint *value)) \
    F(void, Uniform2uiv, (GLint location, GLsizei count, const GLuint *value)) \
    F(void, Uniform1uiv, (GLint location, GLsizei count, const GLuint *value)) \
    F(void, Uniform4ui, (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)) \
    F(void, Uniform3ui, (GLint location, GLuint v0, GLuint v1, GLuint v2)) \
    F(void, Uniform2ui, (GLint location, GLuint v0, GLuint v1)) \
    F(void, Uniform1ui, (GLint location, GLuint v0)) \
    F(GLint, GetFragDataLocation, (GLuint program, const GLchar *name)) \
    F(void, BindFragDataLocation, (GLuint program, GLuint color, const GLchar *name)) \
    F(void, GetUniformuiv, (GLuint program, GLint location, GLuint *params)) \
    F(void, GetVertexAttribIuiv, (GLuint index, GLenum pname, GLuint *params)) \
    F(void, GetVertexAttribIiv, (GLuint index, GLenum pname, GLint *params)) \
    F(void, VertexAttribIPointer, (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) \
    F(void, EndConditionalRender, ()) \
    F(void, BeginConditionalRender, (GLuint id, GLenum mode)) \
    F(void, ClampColor, (GLenum target, GLenum clamp)) \
    F(void, GetTransformFeedbackVarying, (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name)) \
    F(void, TransformFeedbackVaryings, (GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode)) \
    F(void, BindBufferBase, (GLenum target, GLuint index, GLuint buffer)) \
    F(void, BindBufferRange, (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)) \
    F(void, EndTransformFeedback, ()) \
    F(void, BeginTransformFeedback, (GLenum primitiveMode)) \
    F(GLboolean, IsEnabledi, (GLenum target, GLuint index)) \
    F(void, Disablei, (GLenum target, GLuint index)) \
    F(void, Enablei, (GLenum target, GLuint index)) \
    F(void, GetIntegeri_v,(GLenum target, GLuint index, GLint *data)) \
    F(void, GetBooleani_v,(GLenum target, GLuint index, GLboolean *data)) \
    F(void, ColorMaski, (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)) \
    F(void, VertexAttribI4usv, (GLuint index, const GLushort *v)) \
    F(void, VertexAttribI4ubv, (GLuint index, const GLubyte *v)) \
    F(void, VertexAttribI4sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttribI4bv, (GLuint index, const GLbyte *v)) \
    F(void, VertexAttribI4uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttribI3uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttribI2uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttribI1uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttribI4iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttribI3iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttribI2iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttribI1iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttribI4ui, (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)) \
    F(void, VertexAttribI3ui, (GLuint index, GLuint x, GLuint y, GLuint z)) \
    F(void, VertexAttribI2ui, (GLuint index, GLuint x, GLuint y)) \
    F(void, VertexAttribI1ui, (GLuint index, GLuint x)) \
    F(void, VertexAttribI4i, (GLuint index, GLint x, GLint y, GLint z, GLint w)) \
    F(void, VertexAttribI3i, (GLuint index, GLint x, GLint y, GLint z)) \
    F(void, VertexAttribI2i, (GLuint index, GLint x, GLint y)) \
    F(void, VertexAttribI1i, (GLuint index, GLint x)) \

    QT_OPENGL_DECLARE(QT_OPENGL_3_0_FUNCTIONS);
};

class QOpenGLFunctions_3_1_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_3_1_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_3_1_Core; }

    // OpenGL 3.1 core functions
#define QT_OPENGL_3_1_FUNCTIONS(F) \
    F(void, CopyBufferSubData, (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)) \
    F(void, UniformBlockBinding, (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)) \
    F(void, GetActiveUniformBlockName, (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName)) \
    F(void, GetActiveUniformBlockiv, (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params)) \
    F(GLuint, GetUniformBlockIndex, (GLuint program, const GLchar *uniformBlockName)) \
    F(void, GetActiveUniformName, (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName)) \
    F(void, GetActiveUniformsiv, (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params)) \
    F(void, GetUniformIndices, (GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices)) \
    F(void, PrimitiveRestartIndex, (GLuint index)) \
    F(void, TexBuffer, (GLenum target, GLenum internalformat, GLuint buffer)) \
    F(void, DrawElementsInstanced, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount)) \
    F(void, DrawArraysInstanced, (GLenum mode, GLint first, GLsizei count, GLsizei instancecount)) \

    QT_OPENGL_DECLARE(QT_OPENGL_3_1_FUNCTIONS);
};

class QOpenGLFunctions_3_2_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_3_2_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_3_2_Core; }

    // OpenGL 3.2 core functions
#define QT_OPENGL_3_2_FUNCTIONS(F) \
    F(void, SampleMaski, (GLuint maskNumber, GLbitfield mask)) \
    F(void, GetMultisamplefv, (GLenum pname, GLuint index, GLfloat *val)) \
    F(void, TexImage3DMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)) \
    F(void, TexImage2DMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)) \
    F(void, GetSynciv, (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)) \
    F(void, GetInteger64v, (GLenum pname, GLint64 *data)) \
    F(void, WaitSync, (GLsync sync, GLbitfield flags, GLuint64 timeout)) \
    F(GLenum, ClientWaitSync, (GLsync sync, GLbitfield flags, GLuint64 timeout)) \
    F(void, DeleteSync, (GLsync sync)) \
    F(GLboolean, IsSync, (GLsync sync)) \
    F(GLsync, FenceSync, (GLenum condition, GLbitfield flags)) \
    F(void, ProvokingVertex, (GLenum mode)) \
    F(void, MultiDrawElementsBaseVertex, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount, const GLint *basevertex)) \
    F(void, DrawElementsInstancedBaseVertex, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount, GLint basevertex)) \
    F(void, DrawRangeElementsBaseVertex, (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)) \
    F(void, DrawElementsBaseVertex, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)) \
    F(void, FramebufferTexture, (GLenum target, GLenum attachment, GLuint texture, GLint level)) \
    F(void, GetBufferParameteri64v, (GLenum target, GLenum pname, GLint64 *params)) \
    F(void, GetInteger64i_v,(GLenum target, GLuint index, GLint64 *data))

    QT_OPENGL_DECLARE(QT_OPENGL_3_2_FUNCTIONS);
};

class QOpenGLFunctions_3_3_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_3_3_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_3_3_Core; }

    // OpenGL 3.3 core functions
#define QT_OPENGL_3_3_FUNCTIONS(F) \
    F(void, VertexAttribP4uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) \
    F(void, VertexAttribP4ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) \
    F(void, VertexAttribP3uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) \
    F(void, VertexAttribP3ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) \
    F(void, VertexAttribP2uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) \
    F(void, VertexAttribP2ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) \
    F(void, VertexAttribP1uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) \
    F(void, VertexAttribP1ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) \
    F(void, SecondaryColorP3uiv, (GLenum type, const GLuint *color)) \
    F(void, SecondaryColorP3ui, (GLenum type, GLuint color)) \
    F(void, ColorP4uiv, (GLenum type, const GLuint *color)) \
    F(void, ColorP4ui, (GLenum type, GLuint color)) \
    F(void, ColorP3uiv, (GLenum type, const GLuint *color)) \
    F(void, ColorP3ui, (GLenum type, GLuint color)) \
    F(void, NormalP3uiv, (GLenum type, const GLuint *coords)) \
    F(void, NormalP3ui, (GLenum type, GLuint coords)) \
    F(void, MultiTexCoordP4uiv, (GLenum texture, GLenum type, const GLuint *coords)) \
    F(void, MultiTexCoordP4ui, (GLenum texture, GLenum type, GLuint coords)) \
    F(void, MultiTexCoordP3uiv, (GLenum texture, GLenum type, const GLuint *coords)) \
    F(void, MultiTexCoordP3ui, (GLenum texture, GLenum type, GLuint coords)) \
    F(void, MultiTexCoordP2uiv, (GLenum texture, GLenum type, const GLuint *coords)) \
    F(void, MultiTexCoordP2ui, (GLenum texture, GLenum type, GLuint coords)) \
    F(void, MultiTexCoordP1uiv, (GLenum texture, GLenum type, const GLuint *coords)) \
    F(void, MultiTexCoordP1ui, (GLenum texture, GLenum type, GLuint coords)) \
    F(void, TexCoordP4uiv, (GLenum type, const GLuint *coords)) \
    F(void, TexCoordP4ui, (GLenum type, GLuint coords)) \
    F(void, TexCoordP3uiv, (GLenum type, const GLuint *coords)) \
    F(void, TexCoordP3ui, (GLenum type, GLuint coords)) \
    F(void, TexCoordP2uiv, (GLenum type, const GLuint *coords)) \
    F(void, TexCoordP2ui, (GLenum type, GLuint coords)) \
    F(void, TexCoordP1uiv, (GLenum type, const GLuint *coords)) \
    F(void, TexCoordP1ui, (GLenum type, GLuint coords)) \
    F(void, VertexP4uiv, (GLenum type, const GLuint *value)) \
    F(void, VertexP4ui, (GLenum type, GLuint value)) \
    F(void, VertexP3uiv, (GLenum type, const GLuint *value)) \
    F(void, VertexP3ui, (GLenum type, GLuint value)) \
    F(void, VertexP2uiv, (GLenum type, const GLuint *value)) \
    F(void, VertexP2ui, (GLenum type, GLuint value)) \
    F(void, GetQueryObjectui64v, (GLuint id, GLenum pname, GLuint64 *params)) \
    F(void, GetQueryObjecti64v, (GLuint id, GLenum pname, GLint64 *params)) \
    F(void, QueryCounter, (GLuint id, GLenum target)) \
    F(void, GetSamplerParameterIuiv, (GLuint sampler, GLenum pname, GLuint *params)) \
    F(void, GetSamplerParameterfv, (GLuint sampler, GLenum pname, GLfloat *params)) \
    F(void, GetSamplerParameterIiv, (GLuint sampler, GLenum pname, GLint *params)) \
    F(void, GetSamplerParameteriv, (GLuint sampler, GLenum pname, GLint *params)) \
    F(void, SamplerParameterIuiv, (GLuint sampler, GLenum pname, const GLuint *param)) \
    F(void, SamplerParameterIiv, (GLuint sampler, GLenum pname, const GLint *param)) \
    F(void, SamplerParameterfv, (GLuint sampler, GLenum pname, const GLfloat *param)) \
    F(void, SamplerParameterf, (GLuint sampler, GLenum pname, GLfloat param)) \
    F(void, SamplerParameteriv, (GLuint sampler, GLenum pname, const GLint *param)) \
    F(void, SamplerParameteri, (GLuint sampler, GLenum pname, GLint param)) \
    F(void, BindSampler, (GLuint unit, GLuint sampler)) \
    F(GLboolean, IsSampler, (GLuint sampler)) \
    F(void, DeleteSamplers, (GLsizei count, const GLuint *samplers)) \
    F(void, GenSamplers, (GLsizei count, GLuint *samplers)) \
    F(GLint, GetFragDataIndex, (GLuint program, const GLchar *name)) \
    F(void, BindFragDataLocationIndexed, (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name)) \
    F(void, VertexAttribDivisor, (GLuint index, GLuint divisor)) \

    QT_OPENGL_DECLARE(QT_OPENGL_3_3_FUNCTIONS);
};

class QOpenGLFunctions_4_0_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_4_0_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_4_0_Core; }

    // OpenGL 4.0 core functions
#define QT_OPENGL_4_0_FUNCTIONS(F) \
    F(void, GetQueryIndexediv, (GLenum target, GLuint index, GLenum pname, GLint *params)) \
    F(void, EndQueryIndexed, (GLenum target, GLuint index)) \
    F(void, BeginQueryIndexed, (GLenum target, GLuint index, GLuint id)) \
    F(void, DrawTransformFeedbackStream, (GLenum mode, GLuint id, GLuint stream)) \
    F(void, DrawTransformFeedback, (GLenum mode, GLuint id)) \
    F(void, ResumeTransformFeedback, ()) \
    F(void, PauseTransformFeedback, ()) \
    F(GLboolean, IsTransformFeedback, (GLuint id)) \
    F(void, GenTransformFeedbacks, (GLsizei n, GLuint *ids)) \
    F(void, DeleteTransformFeedbacks, (GLsizei n, const GLuint *ids)) \
    F(void, BindTransformFeedback, (GLenum target, GLuint id)) \
    F(void, PatchParameterfv, (GLenum pname, const GLfloat *values)) \
    F(void, PatchParameteri, (GLenum pname, GLint value)) \
    F(void, GetProgramStageiv, (GLuint program, GLenum shadertype, GLenum pname, GLint *values)) \
    F(void, GetUniformSubroutineuiv, (GLenum shadertype, GLint location, GLuint *params)) \
    F(void, UniformSubroutinesuiv, (GLenum shadertype, GLsizei count, const GLuint *indices)) \
    F(void, GetActiveSubroutineName, (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)) \
    F(void, GetActiveSubroutineUniformName, (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)) \
    F(void, GetActiveSubroutineUniformiv, (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values)) \
    F(GLuint, GetSubroutineIndex, (GLuint program, GLenum shadertype, const GLchar *name)) \
    F(GLint, GetSubroutineUniformLocation, (GLuint program, GLenum shadertype, const GLchar *name)) \
    F(void, GetUniformdv, (GLuint program, GLint location, GLdouble *params)) \
    F(void, UniformMatrix4x3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, UniformMatrix4x2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, UniformMatrix3x4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, UniformMatrix3x2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, UniformMatrix2x4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, UniformMatrix2x3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, UniformMatrix4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, UniformMatrix3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, UniformMatrix2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, Uniform4dv, (GLint location, GLsizei count, const GLdouble *value)) \
    F(void, Uniform3dv, (GLint location, GLsizei count, const GLdouble *value)) \
    F(void, Uniform2dv, (GLint location, GLsizei count, const GLdouble *value)) \
    F(void, Uniform1dv, (GLint location, GLsizei count, const GLdouble *value)) \
    F(void, Uniform4d, (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) \
    F(void, Uniform3d, (GLint location, GLdouble x, GLdouble y, GLdouble z)) \
    F(void, Uniform2d, (GLint location, GLdouble x, GLdouble y)) \
    F(void, Uniform1d, (GLint location, GLdouble x)) \
    F(void, DrawElementsIndirect, (GLenum mode, GLenum type, const GLvoid *indirect)) \
    F(void, DrawArraysIndirect, (GLenum mode, const GLvoid *indirect)) \
    F(void, BlendFuncSeparatei, (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)) \
    F(void, BlendFunci, (GLuint buf, GLenum src, GLenum dst)) \
    F(void, BlendEquationSeparatei, (GLuint buf, GLenum modeRGB, GLenum modeAlpha)) \
    F(void, BlendEquationi, (GLuint buf, GLenum mode)) \
    F(void, MinSampleShading, (GLfloat value)) \

    QT_OPENGL_DECLARE(QT_OPENGL_4_0_FUNCTIONS);
};

class QOpenGLFunctions_4_1_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_4_1_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_4_1_Core; }

    // OpenGL 4.1 core functions
#define QT_OPENGL_4_1_FUNCTIONS(F) \
    F(void, GetDoublei_v, (GLenum target, GLuint index, GLdouble *data)) \
    F(void, GetFloati_v,(GLenum target, GLuint index, GLfloat *data)) \
    F(void, DepthRangeIndexed, (GLuint index, GLdouble n, GLdouble f)) \
    F(void, DepthRangeArrayv, (GLuint first, GLsizei count, const GLdouble *v)) \
    F(void, ScissorIndexedv, (GLuint index, const GLint *v)) \
    F(void, ScissorIndexed, (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height)) \
    F(void, ScissorArrayv, (GLuint first, GLsizei count, const GLint *v)) \
    F(void, ViewportIndexedfv, (GLuint index, const GLfloat *v)) \
    F(void, ViewportIndexedf, (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h)) \
    F(void, ViewportArrayv, (GLuint first, GLsizei count, const GLfloat *v)) \
    F(void, GetVertexAttribLdv, (GLuint index, GLenum pname, GLdouble *params)) \
    F(void, VertexAttribLPointer, (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) \
    F(void, VertexAttribL4dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttribL3dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttribL2dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttribL1dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttribL4d, (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) \
    F(void, VertexAttribL3d, (GLuint index, GLdouble x, GLdouble y, GLdouble z)) \
    F(void, VertexAttribL2d, (GLuint index, GLdouble x, GLdouble y)) \
    F(void, VertexAttribL1d, (GLuint index, GLdouble x)) \
    F(void, GetProgramPipelineInfoLog, (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog)) \
    F(void, ValidateProgramPipeline, (GLuint pipeline)) \
    F(void, ProgramUniformMatrix4x3dv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, ProgramUniformMatrix3x4dv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, ProgramUniformMatrix4x2dv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, ProgramUniformMatrix2x4dv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, ProgramUniformMatrix3x2dv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, ProgramUniformMatrix2x3dv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, ProgramUniformMatrix4x3fv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, ProgramUniformMatrix3x4fv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, ProgramUniformMatrix4x2fv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, ProgramUniformMatrix2x4fv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, ProgramUniformMatrix3x2fv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, ProgramUniformMatrix2x3fv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, ProgramUniformMatrix4dv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, ProgramUniformMatrix3dv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, ProgramUniformMatrix2dv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) \
    F(void, ProgramUniformMatrix4fv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, ProgramUniformMatrix3fv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, ProgramUniformMatrix2fv, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) \
    F(void, ProgramUniform4uiv, (GLuint program, GLint location, GLsizei count, const GLuint *value)) \
    F(void, ProgramUniform4ui, (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)) \
    F(void, ProgramUniform4dv, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) \
    F(void, ProgramUniform4d, (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3)) \
    F(void, ProgramUniform4fv, (GLuint program, GLint location, GLsizei count, const GLfloat *value)) \
    F(void, ProgramUniform4f, (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)) \
    F(void, ProgramUniform4iv, (GLuint program, GLint location, GLsizei count, const GLint *value)) \
    F(void, ProgramUniform4i, (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)) \
    F(void, ProgramUniform3uiv, (GLuint program, GLint location, GLsizei count, const GLuint *value)) \
    F(void, ProgramUniform3ui, (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)) \
    F(void, ProgramUniform3dv, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) \
    F(void, ProgramUniform3d, (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2)) \
    F(void, ProgramUniform3fv, (GLuint program, GLint location, GLsizei count, const GLfloat *value)) \
    F(void, ProgramUniform3f, (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)) \
    F(void, ProgramUniform3iv, (GLuint program, GLint location, GLsizei count, const GLint *value)) \
    F(void, ProgramUniform3i, (GLuint program, GLint location, GLint v0, GLint v1, GLint v2)) \
    F(void, ProgramUniform2uiv, (GLuint program, GLint location, GLsizei count, const GLuint *value)) \
    F(void, ProgramUniform2ui, (GLuint program, GLint location, GLuint v0, GLuint v1)) \
    F(void, ProgramUniform2dv, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) \
    F(void, ProgramUniform2d, (GLuint program, GLint location, GLdouble v0, GLdouble v1)) \
    F(void, ProgramUniform2fv, (GLuint program, GLint location, GLsizei count, const GLfloat *value)) \
    F(void, ProgramUniform2f, (GLuint program, GLint location, GLfloat v0, GLfloat v1)) \
    F(void, ProgramUniform2iv, (GLuint program, GLint location, GLsizei count, const GLint *value)) \
    F(void, ProgramUniform2i, (GLuint program, GLint location, GLint v0, GLint v1)) \
    F(void, ProgramUniform1uiv, (GLuint program, GLint location, GLsizei count, const GLuint *value)) \
    F(void, ProgramUniform1ui, (GLuint program, GLint location, GLuint v0)) \
    F(void, ProgramUniform1dv, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) \
    F(void, ProgramUniform1d, (GLuint program, GLint location, GLdouble v0)) \
    F(void, ProgramUniform1fv, (GLuint program, GLint location, GLsizei count, const GLfloat *value)) \
    F(void, ProgramUniform1f, (GLuint program, GLint location, GLfloat v0)) \
    F(void, ProgramUniform1iv, (GLuint program, GLint location, GLsizei count, const GLint *value)) \
    F(void, ProgramUniform1i, (GLuint program, GLint location, GLint v0)) \
    F(void, GetProgramPipelineiv, (GLuint pipeline, GLenum pname, GLint *params)) \
    F(GLboolean, IsProgramPipeline, (GLuint pipeline)) \
    F(void, GenProgramPipelines, (GLsizei n, GLuint *pipelines)) \
    F(void, DeleteProgramPipelines, (GLsizei n, const GLuint *pipelines)) \
    F(void, BindProgramPipeline, (GLuint pipeline)) \
    F(GLuint, CreateShaderProgramv, (GLenum type, GLsizei count, const GLchar* const *strings)) \
    F(void, ActiveShaderProgram, (GLuint pipeline, GLuint program)) \
    F(void, UseProgramStages, (GLuint pipeline, GLbitfield stages, GLuint program)) \
    F(void, ProgramParameteri, (GLuint program, GLenum pname, GLint value)) \
    F(void, ProgramBinary, (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length)) \
    F(void, GetProgramBinary, (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary)) \
    F(void, ClearDepthf, (GLfloat dd)) \
    F(void, DepthRangef, (GLfloat n, GLfloat f)) \
    F(void, GetShaderPrecisionFormat, (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision)) \
    F(void, ShaderBinary, (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length)) \
    F(void, ReleaseShaderCompiler, ()) \

    QT_OPENGL_DECLARE(QT_OPENGL_4_1_FUNCTIONS);
};

class QOpenGLFunctions_4_2_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_4_2_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_4_2_Core; }

    // OpenGL 4.2 core functions
#define QT_OPENGL_4_2_FUNCTIONS(F) \
    F(void, TexStorage3D, (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)) \
    F(void, TexStorage2D, (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)) \
    F(void, TexStorage1D, (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)) \
    F(void, MemoryBarrier, (GLbitfield barriers)) \
    F(void, BindImageTexture, (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format)) \
    F(void, GetActiveAtomicCounterBufferiv, (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params)) \
    F(void, GetInternalformativ, (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params)) \
    F(void, DrawTransformFeedbackStreamInstanced, (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount)) \
    F(void, DrawTransformFeedbackInstanced, (GLenum mode, GLuint id, GLsizei instancecount)) \
    F(void, DrawElementsInstancedBaseVertexBaseInstance, (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance)) \
    F(void, DrawElementsInstancedBaseInstance, (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance)) \
    F(void, DrawArraysInstancedBaseInstance, (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance)) \

    QT_OPENGL_DECLARE(QT_OPENGL_4_2_FUNCTIONS);
};

class QOpenGLFunctions_4_3_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_4_3_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_4_3_Core; }

    // OpenGL 4.3 core functions
#define QT_OPENGL_4_3_FUNCTIONS(F) \
    F(void, TexStorage3DMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)) \
    F(void, TexStorage2DMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)) \
    F(void, TexBufferRange, (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)) \
    F(void, ShaderStorageBlockBinding, (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding)) \
    F(GLint, GetProgramResourceLocationIndex, (GLuint program, GLenum programInterface, const GLchar *name)) \
    F(GLint, GetProgramResourceLocation, (GLuint program, GLenum programInterface, const GLchar *name)) \
    F(void, GetProgramResourceiv, (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params)) \
    F(void, GetProgramResourceName, (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name)) \
    F(GLuint, GetProgramResourceIndex, (GLuint program, GLenum programInterface, const GLchar *name)) \
    F(void, GetProgramInterfaceiv, (GLuint program, GLenum programInterface, GLenum pname, GLint *params)) \
    F(void, MultiDrawElementsIndirect, (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride)) \
    F(void, MultiDrawArraysIndirect, (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride)) \
    F(void, InvalidateSubFramebuffer, (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)) \
    F(void, InvalidateFramebuffer, (GLenum target, GLsizei numAttachments, const GLenum *attachments)) \
    F(void, InvalidateBufferData, (GLuint buffer)) \
    F(void, InvalidateBufferSubData, (GLuint buffer, GLintptr offset, GLsizeiptr length)) \
    F(void, InvalidateTexImage, (GLuint texture, GLint level)) \
    F(void, InvalidateTexSubImage, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)) \
    F(void, GetInternalformati64v, (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params)) \
    F(void, GetFramebufferParameteriv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, FramebufferParameteri, (GLenum target, GLenum pname, GLint param)) \
    F(void, VertexBindingDivisor, (GLuint bindingindex, GLuint divisor)) \
    F(void, VertexAttribBinding, (GLuint attribindex, GLuint bindingindex)) \
    F(void, VertexAttribLFormat, (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)) \
    F(void, VertexAttribIFormat, (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)) \
    F(void, VertexAttribFormat, (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)) \
    F(void, BindVertexBuffer, (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)) \
    F(void, TextureView, (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers)) \
    F(void, CopyImageSubData, (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)) \
    F(void, DispatchComputeIndirect, (GLintptr indirect)) \
    F(void, DispatchCompute, (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)) \
    F(void, ClearBufferSubData, (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data)) \
    F(void, ClearBufferData, (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data)) \
    F(void, GetObjectPtrLabel, (const GLvoid *ptr, GLsizei bufSize, GLsizei *length, GLchar *label)) \
    F(void, ObjectPtrLabel, (const GLvoid *ptr, GLsizei length, const GLchar *label)) \
    F(void, GetObjectLabel, (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)) \
    F(void, ObjectLabel, (GLenum identifier, GLuint name, GLsizei length, const GLchar *label)) \
    F(void, PopDebugGroup, ()) \
    F(void, PushDebugGroup, (GLenum source, GLuint id, GLsizei length, const GLchar *message)) \
    F(GLuint, GetDebugMessageLog, (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog)) \
    F(void, DebugMessageCallback, (GLDEBUGPROC callback, const GLvoid *userParam)) \
    F(void, DebugMessageInsert, (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf)) \
    F(void, DebugMessageControl, (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled)) \

    QT_OPENGL_DECLARE(QT_OPENGL_4_3_FUNCTIONS);
};

class QOpenGLFunctions_4_4_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_4_4_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_4_4_Core; }

    // OpenGL 4.4 core functions
#define QT_OPENGL_4_4_FUNCTIONS(F) \
    F(void, BindVertexBuffers, (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides)) \
    F(void, BindImageTextures, (GLuint first, GLsizei count, const GLuint *textures)) \
    F(void, BindSamplers, (GLuint first, GLsizei count, const GLuint *samplers)) \
    F(void, BindTextures, (GLuint first, GLsizei count, const GLuint *textures)) \
    F(void, BindBuffersRange, (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes)) \
    F(void, BindBuffersBase, (GLenum target, GLuint first, GLsizei count, const GLuint *buffers)) \
    F(void, ClearTexSubImage, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data)) \
    F(void, ClearTexImage, (GLuint texture, GLint level, GLenum format, GLenum type, const void *data)) \
    F(void, BufferStorage, (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags)) \

    QT_OPENGL_DECLARE(QT_OPENGL_4_4_FUNCTIONS);
};

class QOpenGLFunctions_4_5_CoreBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_4_5_CoreBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_4_5_Core; }

    // OpenGL 4.5 core functions
#define QT_OPENGL_4_5_FUNCTIONS(F) \
    F(void, TextureBarrier, ()) \
    F(void, ReadnPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data)) \
    F(void, GetnUniformuiv, (GLuint program, GLint location, GLsizei bufSize, GLuint *params)) \
    F(void, GetnUniformiv, (GLuint program, GLint location, GLsizei bufSize, GLint *params)) \
    F(void, GetnUniformfv, (GLuint program, GLint location, GLsizei bufSize, GLfloat *params)) \
    F(void, GetnUniformdv, (GLuint program, GLint location, GLsizei bufSize, GLdouble *params)) \
    F(void, GetnTexImage, (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels)) \
    F(void, GetnCompressedTexImage, (GLenum target, GLint lod, GLsizei bufSize, void *pixels)) \
    F(GLenum, GetGraphicsResetStatus, ()) \
    F(void, GetCompressedTextureSubImage, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels)) \
    F(void, GetTextureSubImage, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels)) \
    F(void, MemoryBarrierByRegion, (GLbitfield barriers)) \
    F(void, CreateQueries, (GLenum target, GLsizei n, GLuint *ids)) \
    F(void, CreateProgramPipelines, (GLsizei n, GLuint *pipelines)) \
    F(void, CreateSamplers, (GLsizei n, GLuint *samplers)) \
    F(void, GetVertexArrayIndexed64iv, (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param)) \
    F(void, GetVertexArrayIndexediv, (GLuint vaobj, GLuint index, GLenum pname, GLint *param)) \
    F(void, GetVertexArrayiv, (GLuint vaobj, GLenum pname, GLint *param)) \
    F(void, VertexArrayBindingDivisor, (GLuint vaobj, GLuint bindingindex, GLuint divisor)) \
    F(void, VertexArrayAttribLFormat, (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)) \
    F(void, VertexArrayAttribIFormat, (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)) \
    F(void, VertexArrayAttribFormat, (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)) \
    F(void, VertexArrayAttribBinding, (GLuint vaobj, GLuint attribindex, GLuint bindingindex)) \
    F(void, VertexArrayVertexBuffers, (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides)) \
    F(void, VertexArrayVertexBuffer, (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)) \
    F(void, VertexArrayElementBuffer, (GLuint vaobj, GLuint buffer)) \
    F(void, EnableVertexArrayAttrib, (GLuint vaobj, GLuint index)) \
    F(void, DisableVertexArrayAttrib, (GLuint vaobj, GLuint index)) \
    F(void, CreateVertexArrays, (GLsizei n, GLuint *arrays)) \
    F(void, GetTextureParameteriv, (GLuint texture, GLenum pname, GLint *params)) \
    F(void, GetTextureParameterIuiv, (GLuint texture, GLenum pname, GLuint *params)) \
    F(void, GetTextureParameterIiv, (GLuint texture, GLenum pname, GLint *params)) \
    F(void, GetTextureParameterfv, (GLuint texture, GLenum pname, GLfloat *params)) \
    F(void, GetTextureLevelParameteriv, (GLuint texture, GLint level, GLenum pname, GLint *params)) \
    F(void, GetTextureLevelParameterfv, (GLuint texture, GLint level, GLenum pname, GLfloat *params)) \
    F(void, GetCompressedTextureImage, (GLuint texture, GLint level, GLsizei bufSize, void *pixels)) \
    F(void, GetTextureImage, (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels)) \
    F(void, BindTextureUnit, (GLuint unit, GLuint texture)) \
    F(void, GenerateTextureMipmap, (GLuint texture)) \
    F(void, TextureParameteriv, (GLuint texture, GLenum pname, const GLint *param)) \
    F(void, TextureParameterIuiv, (GLuint texture, GLenum pname, const GLuint *params)) \
    F(void, TextureParameterIiv, (GLuint texture, GLenum pname, const GLint *params)) \
    F(void, TextureParameteri, (GLuint texture, GLenum pname, GLint param)) \
    F(void, TextureParameterfv, (GLuint texture, GLenum pname, const GLfloat *param)) \
    F(void, TextureParameterf, (GLuint texture, GLenum pname, GLfloat param)) \
    F(void, CopyTextureSubImage3D, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)) \
    F(void, CopyTextureSubImage2D, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)) \
    F(void, CopyTextureSubImage1D, (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)) \
    F(void, CompressedTextureSubImage3D, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)) \
    F(void, CompressedTextureSubImage2D, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data)) \
    F(void, CompressedTextureSubImage1D, (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data)) \
    F(void, TextureSubImage3D, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)) \
    F(void, TextureSubImage2D, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)) \
    F(void, TextureSubImage1D, (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels)) \
    F(void, TextureStorage3DMultisample, (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)) \
    F(void, TextureStorage2DMultisample, (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)) \
    F(void, TextureStorage3D, (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)) \
    F(void, TextureStorage2D, (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)) \
    F(void, TextureStorage1D, (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width)) \
    F(void, TextureBufferRange, (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizei size)) \
    F(void, TextureBuffer, (GLuint texture, GLenum internalformat, GLuint buffer)) \
    F(void, CreateTextures, (GLenum target, GLsizei n, GLuint *textures)) \
    F(void, GetNamedRenderbufferParameteriv, (GLuint renderbuffer, GLenum pname, GLint *params)) \
    F(void, NamedRenderbufferStorageMultisample, (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)) \
    F(void, NamedRenderbufferStorage, (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height)) \
    F(void, CreateRenderbuffers, (GLsizei n, GLuint *renderbuffers)) \
    F(void, GetNamedFramebufferAttachmentParameteriv, (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params)) \
    F(void, GetNamedFramebufferParameteriv, (GLuint framebuffer, GLenum pname, GLint *param)) \
    F(GLenum, CheckNamedFramebufferStatus, (GLuint framebuffer, GLenum target)) \
    F(void, BlitNamedFramebuffer, (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)) \
    F(void, ClearNamedFramebufferfi, (GLuint framebuffer, GLenum buffer, GLfloat depth, GLint stencil)) \
    F(void, ClearNamedFramebufferfv, (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value)) \
    F(void, ClearNamedFramebufferuiv, (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value)) \
    F(void, ClearNamedFramebufferiv, (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value)) \
    F(void, InvalidateNamedFramebufferSubData, (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)) \
    F(void, InvalidateNamedFramebufferData, (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments)) \
    F(void, NamedFramebufferReadBuffer, (GLuint framebuffer, GLenum src)) \
    F(void, NamedFramebufferDrawBuffers, (GLuint framebuffer, GLsizei n, const GLenum *bufs)) \
    F(void, NamedFramebufferDrawBuffer, (GLuint framebuffer, GLenum buf)) \
    F(void, NamedFramebufferTextureLayer, (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer)) \
    F(void, NamedFramebufferTexture, (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level)) \
    F(void, NamedFramebufferParameteri, (GLuint framebuffer, GLenum pname, GLint param)) \
    F(void, NamedFramebufferRenderbuffer, (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)) \
    F(void, CreateFramebuffers, (GLsizei n, GLuint *framebuffers)) \
    F(void, GetNamedBufferSubData, (GLuint buffer, GLintptr offset, GLsizei size, void *data)) \
    F(void, GetNamedBufferPointerv, (GLuint buffer, GLenum pname, GLvoid* *params)) \
    F(void, GetNamedBufferParameteri64v, (GLuint buffer, GLenum pname, GLint64 *params)) \
    F(void, GetNamedBufferParameteriv, (GLuint buffer, GLenum pname, GLint *params)) \
    F(void, FlushMappedNamedBufferRange, (GLuint buffer, GLintptr offset, GLsizei length)) \
    F(GLboolean, UnmapNamedBuffer, (GLuint buffer)) \
    F(GLvoid *, MapNamedBufferRange, (GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access)) \
    F(GLvoid *, MapNamedBuffer, (GLuint buffer, GLenum access)) \
    F(void, ClearNamedBufferSubData, (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data)) \
    F(void, ClearNamedBufferData, (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data)) \
    F(void, CopyNamedBufferSubData, (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size)) \
    F(void, NamedBufferSubData, (GLuint buffer, GLintptr offset, GLsizei size, const void *data)) \
    F(void, NamedBufferData, (GLuint buffer, GLsizei size, const void *data, GLenum usage)) \
    F(void, NamedBufferStorage, (GLuint buffer, GLsizei size, const void *data, GLbitfield flags)) \
    F(void, CreateBuffers, (GLsizei n, GLuint *buffers)) \
    F(void, GetTransformFeedbacki64_v,(GLuint xfb, GLenum pname, GLuint index, GLint64 *param)) \
    F(void, GetTransformFeedbacki_v,(GLuint xfb, GLenum pname, GLuint index, GLint *param)) \
    F(void, GetTransformFeedbackiv, (GLuint xfb, GLenum pname, GLint *param)) \
    F(void, TransformFeedbackBufferRange, (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size)) \
    F(void, TransformFeedbackBufferBase, (GLuint xfb, GLuint index, GLuint buffer)) \
    F(void, CreateTransformFeedbacks, (GLsizei n, GLuint *ids)) \
    F(void, ClipControl, (GLenum origin, GLenum depth)) \

    QT_OPENGL_DECLARE(QT_OPENGL_4_5_FUNCTIONS);
};

class QOpenGLFunctions_1_0_DeprecatedBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_0_DeprecatedBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_0_Deprecated; }

    // OpenGL 1.0 deprecated functions
#define QT_OPENGL_1_0_DEPRECATED_FUNCTIONS(F) \
    F(void, Translatef, (GLfloat x, GLfloat y, GLfloat z)) \
    F(void, Translated, (GLdouble x, GLdouble y, GLdouble z)) \
    F(void, Scalef, (GLfloat x, GLfloat y, GLfloat z)) \
    F(void, Scaled, (GLdouble x, GLdouble y, GLdouble z)) \
    F(void, Rotatef, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) \
    F(void, Rotated, (GLdouble angle, GLdouble x, GLdouble y, GLdouble z)) \
    F(void, PushMatrix, ()) \
    F(void, PopMatrix, ()) \
    F(void, Ortho, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) \
    F(void, MultMatrixd, (const GLdouble *m)) \
    F(void, MultMatrixf, (const GLfloat *m)) \
    F(void, MatrixMode, (GLenum mode)) \
    F(void, LoadMatrixd, (const GLdouble *m)) \
    F(void, LoadMatrixf, (const GLfloat *m)) \
    F(void, LoadIdentity, ()) \
    F(void, Frustum, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) \
    F(GLboolean, IsList, (GLuint list)) \
    F(void, GetTexGeniv, (GLenum coord, GLenum pname, GLint *params)) \
    F(void, GetTexGenfv, (GLenum coord, GLenum pname, GLfloat *params)) \
    F(void, GetTexGendv, (GLenum coord, GLenum pname, GLdouble *params)) \
    F(void, GetTexEnviv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, GetTexEnvfv, (GLenum target, GLenum pname, GLfloat *params)) \
    F(void, GetPolygonStipple, (GLubyte *mask)) \
    F(void, GetPixelMapusv, (GLenum map, GLushort *values)) \
    F(void, GetPixelMapuiv, (GLenum map, GLuint *values)) \
    F(void, GetPixelMapfv, (GLenum map, GLfloat *values)) \
    F(void, GetMaterialiv, (GLenum face, GLenum pname, GLint *params)) \
    F(void, GetMaterialfv, (GLenum face, GLenum pname, GLfloat *params)) \
    F(void, GetMapiv, (GLenum target, GLenum query, GLint *v)) \
    F(void, GetMapfv, (GLenum target, GLenum query, GLfloat *v)) \
    F(void, GetMapdv, (GLenum target, GLenum query, GLdouble *v)) \
    F(void, GetLightiv, (GLenum light, GLenum pname, GLint *params)) \
    F(void, GetLightfv, (GLenum light, GLenum pname, GLfloat *params)) \
    F(void, GetClipPlane, (GLenum plane, GLdouble *equation)) \
    F(void, DrawPixels, (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) \
    F(void, CopyPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)) \
    F(void, PixelMapusv, (GLenum map, GLsizei mapsize, const GLushort *values)) \
    F(void, PixelMapuiv, (GLenum map, GLsizei mapsize, const GLuint *values)) \
    F(void, PixelMapfv, (GLenum map, GLsizei mapsize, const GLfloat *values)) \
    F(void, PixelTransferi, (GLenum pname, GLint param)) \
    F(void, PixelTransferf, (GLenum pname, GLfloat param)) \
    F(void, PixelZoom, (GLfloat xfactor, GLfloat yfactor)) \
    F(void, AlphaFunc, (GLenum func, GLfloat ref)) \
    F(void, EvalPoint2, (GLint i, GLint j)) \
    F(void, EvalMesh2, (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)) \
    F(void, EvalPoint1, (GLint i)) \
    F(void, EvalMesh1, (GLenum mode, GLint i1, GLint i2)) \
    F(void, EvalCoord2fv, (const GLfloat *u)) \
    F(void, EvalCoord2f, (GLfloat u, GLfloat v)) \
    F(void, EvalCoord2dv, (const GLdouble *u)) \
    F(void, EvalCoord2d, (GLdouble u, GLdouble v)) \
    F(void, EvalCoord1fv, (const GLfloat *u)) \
    F(void, EvalCoord1f, (GLfloat u)) \
    F(void, EvalCoord1dv, (const GLdouble *u)) \
    F(void, EvalCoord1d, (GLdouble u)) \
    F(void, MapGrid2f, (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)) \
    F(void, MapGrid2d, (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)) \
    F(void, MapGrid1f, (GLint un, GLfloat u1, GLfloat u2)) \
    F(void, MapGrid1d, (GLint un, GLdouble u1, GLdouble u2)) \
    F(void, Map2f, (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)) \
    F(void, Map2d, (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)) \
    F(void, Map1f, (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)) \
    F(void, Map1d, (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)) \
    F(void, PushAttrib, (GLbitfield mask)) \
    F(void, PopAttrib, ()) \
    F(void, Accum, (GLenum op, GLfloat value)) \
    F(void, IndexMask, (GLuint mask)) \
    F(void, ClearIndex, (GLfloat c)) \
    F(void, ClearAccum, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) \
    F(void, PushName, (GLuint name)) \
    F(void, PopName, ()) \
    F(void, PassThrough, (GLfloat token)) \
    F(void, LoadName, (GLuint name)) \
    F(void, InitNames, ()) \
    F(GLint, RenderMode, (GLenum mode)) \
    F(void, SelectBuffer, (GLsizei size, GLuint *buffer)) \
    F(void, FeedbackBuffer, (GLsizei size, GLenum type, GLfloat *buffer)) \
    F(void, TexGeniv, (GLenum coord, GLenum pname, const GLint *params)) \
    F(void, TexGeni, (GLenum coord, GLenum pname, GLint param)) \
    F(void, TexGenfv, (GLenum coord, GLenum pname, const GLfloat *params)) \
    F(void, TexGenf, (GLenum coord, GLenum pname, GLfloat param)) \
    F(void, TexGendv, (GLenum coord, GLenum pname, const GLdouble *params)) \
    F(void, TexGend, (GLenum coord, GLenum pname, GLdouble param)) \
    F(void, TexEnviv, (GLenum target, GLenum pname, const GLint *params)) \
    F(void, TexEnvi, (GLenum target, GLenum pname, GLint param)) \
    F(void, TexEnvfv, (GLenum target, GLenum pname, const GLfloat *params)) \
    F(void, TexEnvf, (GLenum target, GLenum pname, GLfloat param)) \
    F(void, ShadeModel, (GLenum mode)) \
    F(void, PolygonStipple, (const GLubyte *mask)) \
    F(void, Materialiv, (GLenum face, GLenum pname, const GLint *params)) \
    F(void, Materiali, (GLenum face, GLenum pname, GLint param)) \
    F(void, Materialfv, (GLenum face, GLenum pname, const GLfloat *params)) \
    F(void, Materialf, (GLenum face, GLenum pname, GLfloat param)) \
    F(void, LineStipple, (GLint factor, GLushort pattern)) \
    F(void, LightModeliv, (GLenum pname, const GLint *params)) \
    F(void, LightModeli, (GLenum pname, GLint param)) \
    F(void, LightModelfv, (GLenum pname, const GLfloat *params)) \
    F(void, LightModelf, (GLenum pname, GLfloat param)) \
    F(void, Lightiv, (GLenum light, GLenum pname, const GLint *params)) \
    F(void, Lighti, (GLenum light, GLenum pname, GLint param)) \
    F(void, Lightfv, (GLenum light, GLenum pname, const GLfloat *params)) \
    F(void, Lightf, (GLenum light, GLenum pname, GLfloat param)) \
    F(void, Fogiv, (GLenum pname, const GLint *params)) \
    F(void, Fogi, (GLenum pname, GLint param)) \
    F(void, Fogfv, (GLenum pname, const GLfloat *params)) \
    F(void, Fogf, (GLenum pname, GLfloat param)) \
    F(void, ColorMaterial, (GLenum face, GLenum mode)) \
    F(void, ClipPlane, (GLenum plane, const GLdouble *equation)) \
    F(void, Vertex4sv, (const GLshort *v)) \
    F(void, Vertex4s, (GLshort x, GLshort y, GLshort z, GLshort w)) \
    F(void, Vertex4iv, (const GLint *v)) \
    F(void, Vertex4i, (GLint x, GLint y, GLint z, GLint w)) \
    F(void, Vertex4fv, (const GLfloat *v)) \
    F(void, Vertex4f, (GLfloat x, GLfloat y, GLfloat z, GLfloat w)) \
    F(void, Vertex4dv, (const GLdouble *v)) \
    F(void, Vertex4d, (GLdouble x, GLdouble y, GLdouble z, GLdouble w)) \
    F(void, Vertex3sv, (const GLshort *v)) \
    F(void, Vertex3s, (GLshort x, GLshort y, GLshort z)) \
    F(void, Vertex3iv, (const GLint *v)) \
    F(void, Vertex3i, (GLint x, GLint y, GLint z)) \
    F(void, Vertex3fv, (const GLfloat *v)) \
    F(void, Vertex3f, (GLfloat x, GLfloat y, GLfloat z)) \
    F(void, Vertex3dv, (const GLdouble *v)) \
    F(void, Vertex3d, (GLdouble x, GLdouble y, GLdouble z)) \
    F(void, Vertex2sv, (const GLshort *v)) \
    F(void, Vertex2s, (GLshort x, GLshort y)) \
    F(void, Vertex2iv, (const GLint *v)) \
    F(void, Vertex2i, (GLint x, GLint y)) \
    F(void, Vertex2fv, (const GLfloat *v)) \
    F(void, Vertex2f, (GLfloat x, GLfloat y)) \
    F(void, Vertex2dv, (const GLdouble *v)) \
    F(void, Vertex2d, (GLdouble x, GLdouble y)) \
    F(void, TexCoord4sv, (const GLshort *v)) \
    F(void, TexCoord4s, (GLshort s, GLshort t, GLshort r, GLshort q)) \
    F(void, TexCoord4iv, (const GLint *v)) \
    F(void, TexCoord4i, (GLint s, GLint t, GLint r, GLint q)) \
    F(void, TexCoord4fv, (const GLfloat *v)) \
    F(void, TexCoord4f, (GLfloat s, GLfloat t, GLfloat r, GLfloat q)) \
    F(void, TexCoord4dv, (const GLdouble *v)) \
    F(void, TexCoord4d, (GLdouble s, GLdouble t, GLdouble r, GLdouble q)) \
    F(void, TexCoord3sv, (const GLshort *v)) \
    F(void, TexCoord3s, (GLshort s, GLshort t, GLshort r)) \
    F(void, TexCoord3iv, (const GLint *v)) \
    F(void, TexCoord3i, (GLint s, GLint t, GLint r)) \
    F(void, TexCoord3fv, (const GLfloat *v)) \
    F(void, TexCoord3f, (GLfloat s, GLfloat t, GLfloat r)) \
    F(void, TexCoord3dv, (const GLdouble *v)) \
    F(void, TexCoord3d, (GLdouble s, GLdouble t, GLdouble r)) \
    F(void, TexCoord2sv, (const GLshort *v)) \
    F(void, TexCoord2s, (GLshort s, GLshort t)) \
    F(void, TexCoord2iv, (const GLint *v)) \
    F(void, TexCoord2i, (GLint s, GLint t)) \
    F(void, TexCoord2fv, (const GLfloat *v)) \
    F(void, TexCoord2f, (GLfloat s, GLfloat t)) \
    F(void, TexCoord2dv, (const GLdouble *v)) \
    F(void, TexCoord2d, (GLdouble s, GLdouble t)) \
    F(void, TexCoord1sv, (const GLshort *v)) \
    F(void, TexCoord1s, (GLshort s)) \
    F(void, TexCoord1iv, (const GLint *v)) \
    F(void, TexCoord1i, (GLint s)) \
    F(void, TexCoord1fv, (const GLfloat *v)) \
    F(void, TexCoord1f, (GLfloat s)) \
    F(void, TexCoord1dv, (const GLdouble *v)) \
    F(void, TexCoord1d, (GLdouble s)) \
    F(void, Rectsv, (const GLshort *v1, const GLshort *v2)) \
    F(void, Rects, (GLshort x1, GLshort y1, GLshort x2, GLshort y2)) \
    F(void, Rectiv, (const GLint *v1, const GLint *v2)) \
    F(void, Recti, (GLint x1, GLint y1, GLint x2, GLint y2)) \
    F(void, Rectfv, (const GLfloat *v1, const GLfloat *v2)) \
    F(void, Rectf, (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) \
    F(void, Rectdv, (const GLdouble *v1, const GLdouble *v2)) \
    F(void, Rectd, (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)) \
    F(void, RasterPos4sv, (const GLshort *v)) \
    F(void, RasterPos4s, (GLshort x, GLshort y, GLshort z, GLshort w)) \
    F(void, RasterPos4iv, (const GLint *v)) \
    F(void, RasterPos4i, (GLint x, GLint y, GLint z, GLint w)) \
    F(void, RasterPos4fv, (const GLfloat *v)) \
    F(void, RasterPos4f, (GLfloat x, GLfloat y, GLfloat z, GLfloat w)) \
    F(void, RasterPos4dv, (const GLdouble *v)) \
    F(void, RasterPos4d, (GLdouble x, GLdouble y, GLdouble z, GLdouble w)) \
    F(void, RasterPos3sv, (const GLshort *v)) \
    F(void, RasterPos3s, (GLshort x, GLshort y, GLshort z)) \
    F(void, RasterPos3iv, (const GLint *v)) \
    F(void, RasterPos3i, (GLint x, GLint y, GLint z)) \
    F(void, RasterPos3fv, (const GLfloat *v)) \
    F(void, RasterPos3f, (GLfloat x, GLfloat y, GLfloat z)) \
    F(void, RasterPos3dv, (const GLdouble *v)) \
    F(void, RasterPos3d, (GLdouble x, GLdouble y, GLdouble z)) \
    F(void, RasterPos2sv, (const GLshort *v)) \
    F(void, RasterPos2s, (GLshort x, GLshort y)) \
    F(void, RasterPos2iv, (const GLint *v)) \
    F(void, RasterPos2i, (GLint x, GLint y)) \
    F(void, RasterPos2fv, (const GLfloat *v)) \
    F(void, RasterPos2f, (GLfloat x, GLfloat y)) \
    F(void, RasterPos2dv, (const GLdouble *v)) \
    F(void, RasterPos2d, (GLdouble x, GLdouble y)) \
    F(void, Normal3sv, (const GLshort *v)) \
    F(void, Normal3s, (GLshort nx, GLshort ny, GLshort nz)) \
    F(void, Normal3iv, (const GLint *v)) \
    F(void, Normal3i, (GLint nx, GLint ny, GLint nz)) \
    F(void, Normal3fv, (const GLfloat *v)) \
    F(void, Normal3f, (GLfloat nx, GLfloat ny, GLfloat nz)) \
    F(void, Normal3dv, (const GLdouble *v)) \
    F(void, Normal3d, (GLdouble nx, GLdouble ny, GLdouble nz)) \
    F(void, Normal3bv, (const GLbyte *v)) \
    F(void, Normal3b, (GLbyte nx, GLbyte ny, GLbyte nz)) \
    F(void, Indexsv, (const GLshort *c)) \
    F(void, Indexs, (GLshort c)) \
    F(void, Indexiv, (const GLint *c)) \
    F(void, Indexi, (GLint c)) \
    F(void, Indexfv, (const GLfloat *c)) \
    F(void, Indexf, (GLfloat c)) \
    F(void, Indexdv, (const GLdouble *c)) \
    F(void, Indexd, (GLdouble c)) \
    F(void, End, ()) \
    F(void, EdgeFlagv, (const GLboolean *flag)) \
    F(void, EdgeFlag, (GLboolean flag)) \
    F(void, Color4usv, (const GLushort *v)) \
    F(void, Color4us, (GLushort red, GLushort green, GLushort blue, GLushort alpha)) \
    F(void, Color4uiv, (const GLuint *v)) \
    F(void, Color4ui, (GLuint red, GLuint green, GLuint blue, GLuint alpha)) \
    F(void, Color4ubv, (const GLubyte *v)) \
    F(void, Color4ub, (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)) \
    F(void, Color4sv, (const GLshort *v)) \
    F(void, Color4s, (GLshort red, GLshort green, GLshort blue, GLshort alpha)) \
    F(void, Color4iv, (const GLint *v)) \
    F(void, Color4i, (GLint red, GLint green, GLint blue, GLint alpha)) \
    F(void, Color4fv, (const GLfloat *v)) \
    F(void, Color4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) \
    F(void, Color4dv, (const GLdouble *v)) \
    F(void, Color4d, (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)) \
    F(void, Color4bv, (const GLbyte *v)) \
    F(void, Color4b, (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)) \
    F(void, Color3usv, (const GLushort *v)) \
    F(void, Color3us, (GLushort red, GLushort green, GLushort blue)) \
    F(void, Color3uiv, (const GLuint *v)) \
    F(void, Color3ui, (GLuint red, GLuint green, GLuint blue)) \
    F(void, Color3ubv, (const GLubyte *v)) \
    F(void, Color3ub, (GLubyte red, GLubyte green, GLubyte blue)) \
    F(void, Color3sv, (const GLshort *v)) \
    F(void, Color3s, (GLshort red, GLshort green, GLshort blue)) \
    F(void, Color3iv, (const GLint *v)) \
    F(void, Color3i, (GLint red, GLint green, GLint blue)) \
    F(void, Color3fv, (const GLfloat *v)) \
    F(void, Color3f, (GLfloat red, GLfloat green, GLfloat blue)) \
    F(void, Color3dv, (const GLdouble *v)) \
    F(void, Color3d, (GLdouble red, GLdouble green, GLdouble blue)) \
    F(void, Color3bv, (const GLbyte *v)) \
    F(void, Color3b, (GLbyte red, GLbyte green, GLbyte blue)) \
    F(void, Bitmap, (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)) \
    F(void, Begin, (GLenum mode)) \
    F(void, ListBase, (GLuint base)) \
    F(GLuint, GenLists, (GLsizei range)) \
    F(void, DeleteLists, (GLuint list, GLsizei range)) \
    F(void, CallLists, (GLsizei n, GLenum type, const GLvoid *lists)) \
    F(void, CallList, (GLuint list)) \
    F(void, EndList, ()) \
    F(void, NewList, (GLuint list, GLenum mode)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_0_DEPRECATED_FUNCTIONS);
};

class QOpenGLFunctions_1_1_DeprecatedBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_1_DeprecatedBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_1_Deprecated; }

    // OpenGL 1.1 deprecated functions
#define QT_OPENGL_1_1_DEPRECATED_FUNCTIONS(F) \
    F(void, PushClientAttrib, (GLbitfield mask)) \
    F(void, PopClientAttrib, ()) \
    F(void, PrioritizeTextures, (GLsizei n, const GLuint *textures, const GLfloat *priorities)) \
    F(GLboolean, AreTexturesResident, (GLsizei n, const GLuint *textures, GLboolean *residences)) \
    F(void, VertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) \
    F(void, TexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) \
    F(void, NormalPointer, (GLenum type, GLsizei stride, const GLvoid *pointer)) \
    F(void, InterleavedArrays, (GLenum format, GLsizei stride, const GLvoid *pointer)) \
    F(void, IndexPointer, (GLenum type, GLsizei stride, const GLvoid *pointer)) \
    F(void, EnableClientState, (GLenum array)) \
    F(void, EdgeFlagPointer, (GLsizei stride, const GLvoid *pointer)) \
    F(void, DisableClientState, (GLenum array)) \
    F(void, ColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) \
    F(void, ArrayElement, (GLint i)) \
    F(void, Indexubv, (const GLubyte *c)) \
    F(void, Indexub, (GLubyte c)) \
    F(void, GetPointerv, (GLenum pname, GLvoid* *params)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_1_DEPRECATED_FUNCTIONS);
};

class QOpenGLFunctions_1_2_DeprecatedBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_2_DeprecatedBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_2_Deprecated; }

    // OpenGL 1.2 deprecated functions
#define QT_OPENGL_1_2_DEPRECATED_FUNCTIONS(F) \
    F(void, ColorTableParameterfv, (GLenum target, GLenum pname, const GLfloat *params)) \
    F(void, ColorTableParameteriv, (GLenum target, GLenum pname, const GLint *params)) \
    F(void, CopyColorTable, (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)) \
    F(void, GetColorTable, (GLenum target, GLenum format, GLenum type, GLvoid *table)) \
    F(void, GetColorTableParameterfv, (GLenum target, GLenum pname, GLfloat *params)) \
    F(void, GetColorTableParameteriv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, ColorSubTable, (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data)) \
    F(void, CopyColorSubTable, (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width)) \
    F(void, ConvolutionFilter1D, (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image)) \
    F(void, ConvolutionFilter2D, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image)) \
    F(void, ConvolutionParameterf, (GLenum target, GLenum pname, GLfloat params)) \
    F(void, ConvolutionParameterfv, (GLenum target, GLenum pname, const GLfloat *params)) \
    F(void, ConvolutionParameteri, (GLenum target, GLenum pname, GLint params)) \
    F(void, ConvolutionParameteriv, (GLenum target, GLenum pname, const GLint *params)) \
    F(void, CopyConvolutionFilter1D, (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)) \
    F(void, CopyConvolutionFilter2D, (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height)) \
    F(void, GetConvolutionFilter, (GLenum target, GLenum format, GLenum type, GLvoid *image)) \
    F(void, GetConvolutionParameterfv, (GLenum target, GLenum pname, GLfloat *params)) \
    F(void, GetConvolutionParameteriv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, GetSeparableFilter, (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span)) \
    F(void, SeparableFilter2D, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column)) \
    F(void, GetHistogram, (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)) \
    F(void, GetHistogramParameterfv, (GLenum target, GLenum pname, GLfloat *params)) \
    F(void, GetHistogramParameteriv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, GetMinmax, (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)) \
    F(void, GetMinmaxParameterfv, (GLenum target, GLenum pname, GLfloat *params)) \
    F(void, GetMinmaxParameteriv, (GLenum target, GLenum pname, GLint *params)) \
    F(void, Histogram, (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink)) \
    F(void, Minmax, (GLenum target, GLenum internalformat, GLboolean sink)) \
    F(void, ResetHistogram, (GLenum target)) \
    F(void, ResetMinmax, (GLenum target)) \
    F(void, ColorTable, (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_2_DEPRECATED_FUNCTIONS);
};

class QOpenGLFunctions_1_3_DeprecatedBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_3_DeprecatedBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_3_Deprecated; }

    // OpenGL 1.3 deprecated functions
#define QT_OPENGL_1_3_DEPRECATED_FUNCTIONS(F) \
    F(void, MultTransposeMatrixd, (const GLdouble *m)) \
    F(void, MultTransposeMatrixf, (const GLfloat *m)) \
    F(void, LoadTransposeMatrixd, (const GLdouble *m)) \
    F(void, LoadTransposeMatrixf, (const GLfloat *m)) \
    F(void, MultiTexCoord4sv, (GLenum target, const GLshort *v)) \
    F(void, MultiTexCoord4s, (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q)) \
    F(void, MultiTexCoord4iv, (GLenum target, const GLint *v)) \
    F(void, MultiTexCoord4i, (GLenum target, GLint s, GLint t, GLint r, GLint q)) \
    F(void, MultiTexCoord4fv, (GLenum target, const GLfloat *v)) \
    F(void, MultiTexCoord4f, (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)) \
    F(void, MultiTexCoord4dv, (GLenum target, const GLdouble *v)) \
    F(void, MultiTexCoord4d, (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q)) \
    F(void, MultiTexCoord3sv, (GLenum target, const GLshort *v)) \
    F(void, MultiTexCoord3s, (GLenum target, GLshort s, GLshort t, GLshort r)) \
    F(void, MultiTexCoord3iv, (GLenum target, const GLint *v)) \
    F(void, MultiTexCoord3i, (GLenum target, GLint s, GLint t, GLint r)) \
    F(void, MultiTexCoord3fv, (GLenum target, const GLfloat *v)) \
    F(void, MultiTexCoord3f, (GLenum target, GLfloat s, GLfloat t, GLfloat r)) \
    F(void, MultiTexCoord3dv, (GLenum target, const GLdouble *v)) \
    F(void, MultiTexCoord3d, (GLenum target, GLdouble s, GLdouble t, GLdouble r)) \
    F(void, MultiTexCoord2sv, (GLenum target, const GLshort *v)) \
    F(void, MultiTexCoord2s, (GLenum target, GLshort s, GLshort t)) \
    F(void, MultiTexCoord2iv, (GLenum target, const GLint *v)) \
    F(void, MultiTexCoord2i, (GLenum target, GLint s, GLint t)) \
    F(void, MultiTexCoord2fv, (GLenum target, const GLfloat *v)) \
    F(void, MultiTexCoord2f, (GLenum target, GLfloat s, GLfloat t)) \
    F(void, MultiTexCoord2dv, (GLenum target, const GLdouble *v)) \
    F(void, MultiTexCoord2d, (GLenum target, GLdouble s, GLdouble t)) \
    F(void, MultiTexCoord1sv, (GLenum target, const GLshort *v)) \
    F(void, MultiTexCoord1s, (GLenum target, GLshort s)) \
    F(void, MultiTexCoord1iv, (GLenum target, const GLint *v)) \
    F(void, MultiTexCoord1i, (GLenum target, GLint s)) \
    F(void, MultiTexCoord1fv, (GLenum target, const GLfloat *v)) \
    F(void, MultiTexCoord1f, (GLenum target, GLfloat s)) \
    F(void, MultiTexCoord1dv, (GLenum target, const GLdouble *v)) \
    F(void, MultiTexCoord1d, (GLenum target, GLdouble s)) \
    F(void, ClientActiveTexture, (GLenum texture)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_3_DEPRECATED_FUNCTIONS);
};

class QOpenGLFunctions_1_4_DeprecatedBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_1_4_DeprecatedBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_1_4_Deprecated; }

    // OpenGL 1.4 deprecated functions
#define QT_OPENGL_1_4_DEPRECATED_FUNCTIONS(F) \
    F(void, WindowPos3sv, (const GLshort *v)) \
    F(void, WindowPos3s, (GLshort x, GLshort y, GLshort z)) \
    F(void, WindowPos3iv, (const GLint *v)) \
    F(void, WindowPos3i, (GLint x, GLint y, GLint z)) \
    F(void, WindowPos3fv, (const GLfloat *v)) \
    F(void, WindowPos3f, (GLfloat x, GLfloat y, GLfloat z)) \
    F(void, WindowPos3dv, (const GLdouble *v)) \
    F(void, WindowPos3d, (GLdouble x, GLdouble y, GLdouble z)) \
    F(void, WindowPos2sv, (const GLshort *v)) \
    F(void, WindowPos2s, (GLshort x, GLshort y)) \
    F(void, WindowPos2iv, (const GLint *v)) \
    F(void, WindowPos2i, (GLint x, GLint y)) \
    F(void, WindowPos2fv, (const GLfloat *v)) \
    F(void, WindowPos2f, (GLfloat x, GLfloat y)) \
    F(void, WindowPos2dv, (const GLdouble *v)) \
    F(void, WindowPos2d, (GLdouble x, GLdouble y)) \
    F(void, SecondaryColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) \
    F(void, SecondaryColor3usv, (const GLushort *v)) \
    F(void, SecondaryColor3us, (GLushort red, GLushort green, GLushort blue)) \
    F(void, SecondaryColor3uiv, (const GLuint *v)) \
    F(void, SecondaryColor3ui, (GLuint red, GLuint green, GLuint blue)) \
    F(void, SecondaryColor3ubv, (const GLubyte *v)) \
    F(void, SecondaryColor3ub, (GLubyte red, GLubyte green, GLubyte blue)) \
    F(void, SecondaryColor3sv, (const GLshort *v)) \
    F(void, SecondaryColor3s, (GLshort red, GLshort green, GLshort blue)) \
    F(void, SecondaryColor3iv, (const GLint *v)) \
    F(void, SecondaryColor3i, (GLint red, GLint green, GLint blue)) \
    F(void, SecondaryColor3fv, (const GLfloat *v)) \
    F(void, SecondaryColor3f, (GLfloat red, GLfloat green, GLfloat blue)) \
    F(void, SecondaryColor3dv, (const GLdouble *v)) \
    F(void, SecondaryColor3d, (GLdouble red, GLdouble green, GLdouble blue)) \
    F(void, SecondaryColor3bv, (const GLbyte *v)) \
    F(void, SecondaryColor3b, (GLbyte red, GLbyte green, GLbyte blue)) \
    F(void, FogCoordPointer, (GLenum type, GLsizei stride, const GLvoid *pointer)) \
    F(void, FogCoorddv, (const GLdouble *coord)) \
    F(void, FogCoordd, (GLdouble coord)) \
    F(void, FogCoordfv, (const GLfloat *coord)) \
    F(void, FogCoordf, (GLfloat coord)) \

    QT_OPENGL_DECLARE(QT_OPENGL_1_4_DEPRECATED_FUNCTIONS);
};

class QOpenGLFunctions_2_0_DeprecatedBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_2_0_DeprecatedBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_2_0_Deprecated; }

    // OpenGL 2.0 deprecated functions
#define QT_OPENGL_2_0_DEPRECATED_FUNCTIONS(F) \
    F(void, VertexAttrib4usv, (GLuint index, const GLushort *v)) \
    F(void, VertexAttrib4uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttrib4ubv, (GLuint index, const GLubyte *v)) \
    F(void, VertexAttrib4sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib4s, (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)) \
    F(void, VertexAttrib4iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttrib4fv, (GLuint index, const GLfloat *v)) \
    F(void, VertexAttrib4f, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)) \
    F(void, VertexAttrib4dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttrib4d, (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) \
    F(void, VertexAttrib4bv, (GLuint index, const GLbyte *v)) \
    F(void, VertexAttrib4Nusv, (GLuint index, const GLushort *v)) \
    F(void, VertexAttrib4Nuiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttrib4Nubv, (GLuint index, const GLubyte *v)) \
    F(void, VertexAttrib4Nub, (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)) \
    F(void, VertexAttrib4Nsv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib4Niv, (GLuint index, const GLint *v)) \
    F(void, VertexAttrib4Nbv, (GLuint index, const GLbyte *v)) \
    F(void, VertexAttrib3sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib3s, (GLuint index, GLshort x, GLshort y, GLshort z)) \
    F(void, VertexAttrib3fv, (GLuint index, const GLfloat *v)) \
    F(void, VertexAttrib3f, (GLuint index, GLfloat x, GLfloat y, GLfloat z)) \
    F(void, VertexAttrib3dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttrib3d, (GLuint index, GLdouble x, GLdouble y, GLdouble z)) \
    F(void, VertexAttrib2sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib2s, (GLuint index, GLshort x, GLshort y)) \
    F(void, VertexAttrib2fv, (GLuint index, const GLfloat *v)) \
    F(void, VertexAttrib2f, (GLuint index, GLfloat x, GLfloat y)) \
    F(void, VertexAttrib2dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttrib2d, (GLuint index, GLdouble x, GLdouble y)) \
    F(void, VertexAttrib1sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttrib1s, (GLuint index, GLshort x)) \
    F(void, VertexAttrib1fv, (GLuint index, const GLfloat *v)) \
    F(void, VertexAttrib1f, (GLuint index, GLfloat x)) \
    F(void, VertexAttrib1dv, (GLuint index, const GLdouble *v)) \
    F(void, VertexAttrib1d, (GLuint index, GLdouble x)) \

    QT_OPENGL_DECLARE(QT_OPENGL_2_0_DEPRECATED_FUNCTIONS);
};

class QOpenGLFunctions_3_0_DeprecatedBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_3_0_DeprecatedBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_3_0_Deprecated; }

    // OpenGL 3.0 deprecated functions
#define QT_OPENGL_3_0_DEPRECATED_FUNCTIONS(F) \
    F(void, VertexAttribI4usv, (GLuint index, const GLushort *v)) \
    F(void, VertexAttribI4ubv, (GLuint index, const GLubyte *v)) \
    F(void, VertexAttribI4sv, (GLuint index, const GLshort *v)) \
    F(void, VertexAttribI4bv, (GLuint index, const GLbyte *v)) \
    F(void, VertexAttribI4uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttribI3uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttribI2uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttribI1uiv, (GLuint index, const GLuint *v)) \
    F(void, VertexAttribI4iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttribI3iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttribI2iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttribI1iv, (GLuint index, const GLint *v)) \
    F(void, VertexAttribI4ui, (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)) \
    F(void, VertexAttribI3ui, (GLuint index, GLuint x, GLuint y, GLuint z)) \
    F(void, VertexAttribI2ui, (GLuint index, GLuint x, GLuint y)) \
    F(void, VertexAttribI1ui, (GLuint index, GLuint x)) \
    F(void, VertexAttribI4i, (GLuint index, GLint x, GLint y, GLint z, GLint w)) \
    F(void, VertexAttribI3i, (GLuint index, GLint x, GLint y, GLint z)) \
    F(void, VertexAttribI2i, (GLuint index, GLint x, GLint y)) \
    F(void, VertexAttribI1i, (GLuint index, GLint x)) \

    QT_OPENGL_DECLARE(QT_OPENGL_3_0_DEPRECATED_FUNCTIONS);
};

class QOpenGLFunctions_3_3_DeprecatedBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_3_3_DeprecatedBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_3_3_Deprecated; }

    // OpenGL 3.3 deprecated functions
#define QT_OPENGL_3_3_DEPRECATED_FUNCTIONS(F) \
    F(void, SecondaryColorP3uiv, (GLenum type, const GLuint *color)) \
    F(void, SecondaryColorP3ui, (GLenum type, GLuint color)) \
    F(void, ColorP4uiv, (GLenum type, const GLuint *color)) \
    F(void, ColorP4ui, (GLenum type, GLuint color)) \
    F(void, ColorP3uiv, (GLenum type, const GLuint *color)) \
    F(void, ColorP3ui, (GLenum type, GLuint color)) \
    F(void, NormalP3uiv, (GLenum type, const GLuint *coords)) \
    F(void, NormalP3ui, (GLenum type, GLuint coords)) \
    F(void, MultiTexCoordP4uiv, (GLenum texture, GLenum type, const GLuint *coords)) \
    F(void, MultiTexCoordP4ui, (GLenum texture, GLenum type, GLuint coords)) \
    F(void, MultiTexCoordP3uiv, (GLenum texture, GLenum type, const GLuint *coords)) \
    F(void, MultiTexCoordP3ui, (GLenum texture, GLenum type, GLuint coords)) \
    F(void, MultiTexCoordP2uiv, (GLenum texture, GLenum type, const GLuint *coords)) \
    F(void, MultiTexCoordP2ui, (GLenum texture, GLenum type, GLuint coords)) \
    F(void, MultiTexCoordP1uiv, (GLenum texture, GLenum type, const GLuint *coords)) \
    F(void, MultiTexCoordP1ui, (GLenum texture, GLenum type, GLuint coords)) \
    F(void, TexCoordP4uiv, (GLenum type, const GLuint *coords)) \
    F(void, TexCoordP4ui, (GLenum type, GLuint coords)) \
    F(void, TexCoordP3uiv, (GLenum type, const GLuint *coords)) \
    F(void, TexCoordP3ui, (GLenum type, GLuint coords)) \
    F(void, TexCoordP2uiv, (GLenum type, const GLuint *coords)) \
    F(void, TexCoordP2ui, (GLenum type, GLuint coords)) \
    F(void, TexCoordP1uiv, (GLenum type, const GLuint *coords)) \
    F(void, TexCoordP1ui, (GLenum type, GLuint coords)) \
    F(void, VertexP4uiv, (GLenum type, const GLuint *value)) \
    F(void, VertexP4ui, (GLenum type, GLuint value)) \
    F(void, VertexP3uiv, (GLenum type, const GLuint *value)) \
    F(void, VertexP3ui, (GLenum type, GLuint value)) \
    F(void, VertexP2uiv, (GLenum type, const GLuint *value)) \
    F(void, VertexP2ui, (GLenum type, GLuint value)) \

    QT_OPENGL_DECLARE(QT_OPENGL_3_3_DEPRECATED_FUNCTIONS);
};

class QOpenGLFunctions_4_5_DeprecatedBackend : public QOpenGLVersionFunctionsBackend
{
public:
    QOpenGLFunctions_4_5_DeprecatedBackend(QOpenGLContext *c)
        : QOpenGLVersionFunctionsBackend(c)
    {
        init();
    }

    constexpr static Version versionStatus()
    { return OpenGL_4_5_Deprecated; }

    // OpenGL 4.5 deprecated functions
#define QT_OPENGL_4_5_DEPRECATED_FUNCTIONS(F) \
    F(void, GetnMinmax, (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values)) \
    F(void, GetnHistogram, (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values)) \
    F(void, GetnSeparableFilter, (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span)) \
    F(void, GetnConvolutionFilter, (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image)) \
    F(void, GetnColorTable, (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table)) \
    F(void, GetnPolygonStipple, (GLsizei bufSize, GLubyte *pattern)) \
    F(void, GetnPixelMapusv, (GLenum map, GLsizei bufSize, GLushort *values)) \
    F(void, GetnPixelMapuiv, (GLenum map, GLsizei bufSize, GLuint *values)) \
    F(void, GetnPixelMapfv, (GLenum map, GLsizei bufSize, GLfloat *values)) \
    F(void, GetnMapiv, (GLenum target, GLenum query, GLsizei bufSize, GLint *v)) \
    F(void, GetnMapfv, (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v)) \
    F(void, GetnMapdv, (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v)) \

    QT_OPENGL_DECLARE(QT_OPENGL_4_5_DEPRECATED_FUNCTIONS);
};

#else

// No need for backend classes with function pointers with ES2.
// All function addresses are independent of context and display.

#endif // !QT_CONFIG(opengles2)

#undef QT_OPENGL_DECLARE_FUNCTIONS
#undef QT_OPENGL_COUNT_FUNCTIONS
#undef QT_OPENGL_DECLARE


QT_END_NAMESPACE

#ifdef Q_OS_WIN
#pragma pop_macro("MemoryBarrier")
#endif

#endif // QT_NO_OPENGL

#endif
