15.1.209. tablet_qt/lib/openglfunc.cpp

/*
    Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
    Created by Rudolf Cardinal (rnc1001@cam.ac.uk).

    This file is part of CamCOPS.

    CamCOPS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    CamCOPS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
*/

// See:
// - https://raw.githubusercontent.com/mltframework/shotcut/master/src/widgets/gltestwidget.h
// - https://raw.githubusercontent.com/mltframework/shotcut/master/src/widgets/gltestwidget.cpp
// - https://forum.qt.io/topic/68217/qopenglwidget-how-to-get-opengl-version-from-os


#include "openglfunc.h"
#include <QDebug>
#include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QSurface>
#include <QtGui/QSurfaceFormat>
#include <QOpenGLWidget>

static bool s_opengl_presence_checked = false;
static bool s_opengl_present = false;


namespace openglfunc {


bool isOpenGLPresent()
{
    if (!s_opengl_presence_checked) {
        s_opengl_presence_checked = true;
        s_opengl_present = false;

#ifndef QT_NO_OPENGL

        // - Android supports OpenGL ES 2.0 from Android 2.2 (API level 8).
        // - Android supports OpenGL ES 3.0 from Android 4.3 (API level 18),
        //   though not all devices may support this.
        // See https://developer.android.com/guide/topics/graphics/opengl.

        // For Qt support, see
        // - https://blog.qt.io/blog/2015/09/09/cross-platform-opengl-es-3-apps-with-qt-5-6/
        // - https://doc.qt.io/qt-6.5/qopenglfunctions.html
        // - https://doc.qt.io/qt-6.5/qopenglversionprofile.html#details

        QOffscreenSurface surf;
        surf.create();
        const QSurfaceFormat fmt = surf.format();
        qInfo() << "OpenGL surface format:" << fmt;

        QOpenGLContext ctx;
        if (!ctx.create()) {
            qCritical() << "Unable to create OpenGL context";
            return false;
        }
        ctx.makeCurrent(&surf);

        QOpenGLFunctions* glfuncs = ctx.functions();
        glfuncs->initializeOpenGLFunctions();

        // Doesn't work under Android:
        // const QOpenGLFunctions_2_0* v2funcs = ctx.versionFunctions<QOpenGLFunctions_2_0>();
        // const bool opengl_v2 = (v2funcs != nullptr);

        // Deprecated and missing on Android:
        // const bool opengl_v2 = QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0;

        const bool opengl_v2 = fmt.majorVersion() >= 2;

        const bool npot_textures = glfuncs->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
        const bool shaders = glfuncs->hasOpenGLFeature(QOpenGLFunctions::Shaders);
        const bool framebuffers = glfuncs->hasOpenGLFeature(QOpenGLFunctions::Framebuffers);
        qInfo() << "OpenGL v2.0 present:" << opengl_v2;
        qInfo() << "OpenGL has NPOTTextures:" << npot_textures;
        // ... "not powers of two" textures
        qInfo() << "OpenGL has shaders:" << shaders;
        qInfo() << "OpenGL has framebuffers:" << framebuffers;

        s_opengl_present = opengl_v2;  // we don't need the fancy bits

        if (s_opengl_present) {
            qInfo() << "OpenGL v2.0 or higher is present and satisfactory";
        } else {
            qCritical() << "Error: This program requires OpenGL version 2.0+";
        }
#endif

    }
    return s_opengl_present;
}


}  // namespace openglfunc