Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for WebAssembly
  4. Qt 6.6.1 WebAssembly Error. WebGL: INVALID_ENUM: bindFramebuffer: invalid target

Qt 6.6.1 WebAssembly Error. WebGL: INVALID_ENUM: bindFramebuffer: invalid target

Scheduled Pinned Locked Moved Unsolved Qt for WebAssembly
7 Posts 2 Posters 683 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 8 Offline
    8 Offline
    8Observer8
    wrote on 29 Dec 2023, 12:44 last edited by 8Observer8
    #1

    Hi,

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

    b00ca404-8a17-46f2-8e1f-932db170e7ae-image.png

    But when I try to build it for WebAssembly the browser prints this message: WebGL: INVALID_ENUM: bindFramebuffer: invalid target

    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
    
    1 Reply Last reply
    0
    • 8 Offline
      8 Offline
      8Observer8
      wrote on 29 Dec 2023, 18:47 last edited by 8Observer8
      #2

      Cross-refs:

      • https://stackoverflow.com/questions/77733503/qt-6-6-1-webassembly-error-webgl-invalid-enum-bindframebuffer-invalid-target
      • https://community.khronos.org/t/qt-6-6-1-webassembly-error-webgl-invalid-enum-bindframebuffer-invalid-target/110398
      1 Reply Last reply
      0
      • 8 Offline
        8 Offline
        8Observer8
        wrote on 30 Dec 2023, 02:28 last edited by 8Observer8
        #3

        Dark_Photon answered here that it seams like WebAssembly uses WebGL 1.0 where there is no GL_DRAW_FRAMEBUFFER and GL_READ_FRAMEBUFFER: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindFramebuffer But WebGL 2.0 has them. This means that WebAssembly uses WebGL 1.0. To solve the problem, I need WebAssembly to use WebGL 2.0. But how to do that?

        1 Reply Last reply
        0
        • 8 Offline
          8 Offline
          8Observer8
          wrote on 30 Dec 2023, 03:06 last edited by 8Observer8
          #4

          I commented all lines of code except glClear() in the paintGL() method to show OpenGL version, GLSL version, and vendor:

          • OpenGL version: OpenGL version: OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))
          • GLSL version: GLSL version: OpenGL ES GLSL ES 1.00 (WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium))
          • Vendor version: Vendor: WebKit

          How to activate WebGL 2.0 from WebAssembly?

          L 1 Reply Last reply 30 Dec 2023, 09:13
          0
          • 8 8Observer8
            30 Dec 2023, 03:06

            I commented all lines of code except glClear() in the paintGL() method to show OpenGL version, GLSL version, and vendor:

            • OpenGL version: OpenGL version: OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))
            • GLSL version: GLSL version: OpenGL ES GLSL ES 1.00 (WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium))
            • Vendor version: Vendor: WebKit

            How to activate WebGL 2.0 from WebAssembly?

            L Offline
            L Offline
            lorn.potter
            wrote on 30 Dec 2023, 09:13 last edited by
            #5

            @8Observer8
            Set the QSurfaceFormat version to 3.0

            https://doc.qt.io/qt-6/qsurfaceformat.html#setMajorVersion

            Freelance Software Engineer, Platform Maintainer QtWebAssembly, Maintainer QtSensors
            Author, Hands-On Mobile and Embedded Development with Qt 5 http://bit.ly/HandsOnMobileEmbedded

            8 1 Reply Last reply 30 Dec 2023, 10:54
            2
            • L lorn.potter
              30 Dec 2023, 09:13

              @8Observer8
              Set the QSurfaceFormat version to 3.0

              https://doc.qt.io/qt-6/qsurfaceformat.html#setMajorVersion

              8 Offline
              8 Offline
              8Observer8
              wrote on 30 Dec 2023, 10:54 last edited by
              #6

              @lorn-potter said in Qt 6.6.1 WebAssembly Error. WebGL: INVALID_ENUM: bindFramebuffer: invalid target:

              Set the QSurfaceFormat version to 3.0

              I tried to set:

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

              But it didn't help:

              7396e620-2def-4def-900f-03c88745136f-image.png

              1 Reply Last reply
              0
              • 8 Offline
                8 Offline
                8Observer8
                wrote on 30 Dec 2023, 11:57 last edited by 8Observer8
                #7

                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:

                a0b95b4f-30f1-4a9f-8c1f-d726fd90577e-image.png

                WebAssembly:

                730c5fca-dd06-454c-9f10-2320426c8a0a-image.png

                1 Reply Last reply
                0

                5/7

                30 Dec 2023, 09:13

                • Login

                • Login or register to search.
                5 out of 7
                • First post
                  5/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved