Qt 6.6.1 Android Build Error: use of undeclared identifier 'GL_DRAW_FRAMEBUFFER'

Hi,

My example works on Desktop. It prints a color of a pixel with (0, 0) coordinates and OpenGL version:

image

But when I switch to Android I have these errors when I build:

main.cpp:45:27: error: use of undeclared identifier 'GL_DRAW_FRAMEBUFFER'
main.cpp:50:27: error: use of undeclared identifier 'GL_DRAW_FRAMEBUFFER'
main.cpp:52:27: error: use of undeclared identifier 'GL_READ_FRAMEBUFFER'
main.cpp:57:22: error: use of undeclared identifier 'GL_READ_FRAMEBUFFER'

I connected the Redmi 4X phone using USB cable. This is a screenshot that I made on laptop using the scrcpy program. This screenshot shows that my device supports OpenGL ES 3.2:

image

main.cpp

#include <QtGui/QOpenGLExtraFunctions>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QVector3D>
#include <QtOpenGL/QOpenGLFramebufferObject>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QWidget>
#include <QtWidgets/QVBoxLayout>
#include <QtOpenGLWidgets/QOpenGLWidget>

class OpenGLWidget : public QOpenGLWidget, private QOpenGLExtraFunctions
{
    Q_OBJECT

public:
    OpenGLWidget()
    {
        QSurfaceFormat surfaceFormat;
        surfaceFormat.setSamples(4);
        setFormat(surfaceFormat);
    }

signals:
    void showInfoSignal(const QString &openGLVersion, const QString &shadingVersion,
                        const QString &vendor);
    void showPixelColorSignal(const QVector3D &color);

private:
    void initializeGL() override
    {
        initializeOpenGLFunctions();
        glClearColor(0.f, 1.f, 0.f, 1.f);
        m_fbo.reset(new QOpenGLFramebufferObject(1, 1));
        QString version(QString("OpenGL version: %1").arg((const char*) glGetString(GL_VERSION)));
        QString shadingLanguageVersion(QString("GLSL version: %1")
                                           .arg((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)));
        QString vendor(QString("Vendor: %1").arg((const char*) glGetString(GL_VENDOR)));
        emit showInfoSignal(version, shadingLanguageVersion, vendor);
    }

    void paintGL() override
    {
        glClear(GL_COLOR_BUFFER_BIT);
        // Set draw buffer to be fbo. Read buffer is already the default one
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo->handle());
        // Blit from the default MSAA buffer to non-MSAA fbo
        glBlitFramebuffer(0, 0, m_fbo->width(), m_fbo->height(),
                          0, 0, m_fbo->width(), m_fbo->height(),
                          GL_COLOR_BUFFER_BIT, GL_NEAREST);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context()->defaultFramebufferObject());
        // Set read buffer
        glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo->handle());
        // Read the pixel
        GLubyte pixel[4];
        glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
        // Set read buffer back to default
        glBindBuffer(GL_READ_FRAMEBUFFER, context()->defaultFramebufferObject());
        emit showPixelColorSignal(QVector3D(pixel[0] / 255.f, pixel[1] / 255.f, pixel[2] / 255.f));
    }

private:
    std::unique_ptr<QOpenGLFramebufferObject> m_fbo;
};

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    MainWindow()
    {
        resize(300, 300);
        setWindowTitle("Read Pixel Color");

        m_openGLVersionLabel = new QLabel();
        m_shadingLanguageVersionLabel = new QLabel();
        m_vendorLabel = new QLabel();
        m_pixelColorLabel = new QLabel();
        OpenGLWidget *openGLWidget = new OpenGLWidget();

        m_openGLVersionLabel->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
        m_shadingLanguageVersionLabel->setSizePolicy(QSizePolicy::Policy::Fixed,
                                                     QSizePolicy::Policy::Fixed);
        m_vendorLabel->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
        m_pixelColorLabel->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);

        QVBoxLayout *layout = new QVBoxLayout();
        layout->addWidget(m_openGLVersionLabel);
        layout->addWidget(m_shadingLanguageVersionLabel);
        layout->addWidget(m_vendorLabel);
        layout->addWidget(m_pixelColorLabel);
        layout->addWidget(openGLWidget);
        setLayout(layout);

        connect(openGLWidget, &OpenGLWidget::showPixelColorSignal,
                this, &MainWindow::showPixelColorSlot);
        connect(openGLWidget, &OpenGLWidget::showInfoSignal, this, &MainWindow::showInfoSlot);
    }

private slots:
    void showInfoSlot(const QString &openGLVersion, const QString &shadingVersion,
                      const QString &vendor)
    {
        m_openGLVersionLabel->setText(openGLVersion);
        m_shadingLanguageVersionLabel->setText(shadingVersion);
        m_vendorLabel->setText(vendor);
    }

    void showPixelColorSlot(const QVector3D &color)
    {
        m_pixelColorLabel->setText(QString("Pixel Color: (r: %1, g: %2, b: %3)")
                                       .arg(color.x()).arg(color.y()).arg(color.x()));
    }

private:
    QLabel *m_openGLVersionLabel;
    QLabel *m_shadingLanguageVersionLabel;
    QLabel *m_vendorLabel;
    QLabel *m_pixelColorLabel;
};

#include "main.moc"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow w;
    w.show();
    return app.exec();
}

pro

QT += core gui openglwidgets widgets

win32: LIBS += -lopengl32

CONFIG += c++17

SOURCES += \
    main.cpp

TARGET = app

Cross-ref:

Cross-ref:

I commented all lines of code except glClear() in the paintGL() method to show OpenGL version, GLSL version, and vendor. I ran the example on physical device connected with USB cable. OpenGL ES 3.2 supports GL_DRAW_FRAMEBUFFER and GL_READ_FRAMEBUFFER. But it looks like it doesn’t.

image

I found a temporary solution that is good for me for now. I just deleted the sampling:

    OpenGLWidget()
    {
        // QSurfaceFormat surfaceFormat;
        // surfaceFormat.setMajorVersion(3);
        // surfaceFormat.setMinorVersion(0);
        // surfaceFormat.setSamples(4);
        // setFormat(surfaceFormat);
    }

In this case I don’t need to use GL_DRAW_FRAMEBUFFER and GL_READ_FRAMEBUFFER to read a pixel color using glReadPixels():

    void paintGL() override
    {
        glClear(GL_COLOR_BUFFER_BIT);
        // // Set draw buffer to be fbo. Read buffer is already the default one
        // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo->handle());
        // // Blit from the default MSAA buffer to non-MSAA fbo
        // glBlitFramebuffer(0, 0, m_fbo->width(), m_fbo->height(),
        //                   0, 0, m_fbo->width(), m_fbo->height(),
        //                   GL_COLOR_BUFFER_BIT, GL_NEAREST);
        // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context()->defaultFramebufferObject());
        // // Set read buffer
        // glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo->handle());

        // Read the pixel
        GLubyte pixel[4];
        glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
        // Set read buffer back to default
        // glBindBuffer(GL_READ_FRAMEBUFFER, context()->defaultFramebufferObject());
        qDebug() << pixel[0] / 255.f << pixel[1] / 255.f << pixel[2] / 255.f;
        emit showPixelColorSignal(QVector3D(pixel[0] / 255.f, pixel[1] / 255.f, pixel[2] / 255.f));
    }

My applications works correctly on Android and WebAssembly. It read a pixel with green color (0, 1, 0):

Android:

image

WebAssembly:

image