Qt 6.6.1 WebAssembly: Triangle disappears when it was clicked
-
I removed
Qt 6.5.3
and installedQt 6.7.0 beta1
. I run an example with triangle above. I see a warning in the Qt Creator console::-1: warning: This Qt was built with Emscripten version 3.1.37. You have 3.1.25. The difference may cause issues.
I don't see a triangle in the browser (I see just a black color) but I see a message in the browser console:
WebGL: INVALID_OPERATION: drawArrays: no valid shader program in use
-
I remove the
emsdk
folder to installemsdk 3.1.37
. As withemsdk 3.1.25
I have an error in the process of installation:C:\>git clone https://github.com/emscripten-core/emsdk.git Cloning into 'emsdk'... remote: Enumerating objects: 3884, done. remote: Counting objects: 100% (47/47), done. remote: Compressing objects: 100% (31/31), done. remote: Total 3884 (delta 22), reused 39 (delta 15), pack-reused 3837Receiving objects: 100% (3884/3884), 1.68 MiB | 331Receiving objects: 100% (3884/3884), 2.16 MiB | 295.00 KiB/s, done. Resolving deltas: 100% (2552/2552), done. C:\>cd emsdk C:\emsdk>emsdk.bat install 3.1.37 Resolving SDK version '3.1.37' to 'sdk-releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit' Installing SDK 'sdk-releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit'.. Installing tool 'node-16.20.0-64bit'.. Downloading: C:/emsdk/downloads/node-v16.20.0-win-x64.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v16.20.0-win-x64.zip, 28623474 Bytes Unpacking 'C:/emsdk/downloads/node-v16.20.0-win-x64.zip' to 'C:/emsdk/node/16.20.0_64bit' Done installing tool 'node-16.20.0-64bit'. Installing tool 'python-3.9.2-nuget-64bit'.. Downloading: C:/emsdk/downloads/python-3.9.2-4-amd64+pywin32.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/python-3.9.2-4-amd64+pywin32.zip, 14413267 Bytes Unpacking 'C:/emsdk/downloads/python-3.9.2-4-amd64+pywin32.zip' to 'C:/emsdk/python/3.9.2-nuget_64bit' Done installing tool 'python-3.9.2-nuget-64bit'. Installing tool 'java-8.152-64bit'.. Error: Downloading URL 'https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/portable_jre_8_update_152_64bit.zip': <urlopen error [Errno 2] No such file or directory> error: installation failed!
But when I start in the second time it was installed:
C:\emsdk>emsdk.bat install 3.1.37 Resolving SDK version '3.1.37' to 'sdk-releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit' Installing SDK 'sdk-releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit'.. Skipped installing node-16.20.0-64bit, already installed. Skipped installing python-3.9.2-nuget-64bit, already installed. Installing tool 'java-8.152-64bit'.. Downloading: C:/emsdk/downloads/portable_jre_8_update_152_64bit.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/portable_jre_8_update_152_64bit.zip, 69241499 Bytes Unpacking 'C:/emsdk/downloads/portable_jre_8_update_152_64bit.zip' to 'C:/emsdk/java/8.152_64bit' Done installing tool 'java-8.152-64bit'. Installing tool 'releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit'.. Downloading: C:/emsdk/downloads/7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-wasm-binaries.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2/wasm-binaries.zip, 419522512 Bytes Unpacking 'C:/emsdk/downloads/7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-wasm-binaries.zip' to 'C:/emsdk/upstream' Done installing tool 'releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit'. Done installing SDK 'sdk-releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit'.
If I don't active the
emsdk
I get this error::-1: warning: This Qt was built with Emscripten version 3.1.37. You have can `clang`. The difference may cause issues. :-1: error: [Makefile:69: .\triangle-in-main-opengl3-qt6-cpp.js] Error 1
But after the activation of
emsdk 3.1.37
I don't have the error above and I don't have the warningThis Qt was built with Emscripten version 3.1.37. You have 3.1.25.
withQt 6.7.0 beta1
. I have the black window again. But I have this error in the browser console like withemsdk 3.1.25
above:WebGL: INVALID_OPERATION: drawArrays: no valid shader program in use
But this example doesn't show a triangle on Desktop:
main.cpp
#include <QtGui/QOpenGLFunctions> #include <QtGui/QSurfaceFormat> #include <QtOpenGLWidgets/QOpenGLWidget> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtWidgets/QApplication> class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { public: OpenGLWidget() { resize(350, 350); } private: void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.4f, 0.8f, 0.9f, 1.f); qDebug() << "OpenGL Version:" << (const char*) glGetString(GL_VERSION); qDebug() << "GLSL Version:" << (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION); qDebug() << "OpenGL Vendor:" << (const char*) glGetString(GL_VENDOR); QString vertexShaderSource = "attribute vec2 aPosition;\n" "void main()\n" "{\n" " gl_Position = vec4(aPosition, 0.0, 1.0);\n" "}\n"; QString fragmentShaderSource = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "//out vec4 fragColor;\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"; m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertexShaderSource); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragmentShaderSource); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.f, 0.5f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2); m_program.enableAttributeArray("aPosition"); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 4); } private: QOpenGLShaderProgram m_program; QOpenGLBuffer m_vertPosBuffer; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); OpenGLWidget w; w.show(); return app.exec(); }
pro
QT += core gui openglwidgets widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp
-
The example above prints this versions of OpenGL/GLSL and the vendor to the Qt Creator console on Desktop, it is Mesa:
OpenGL Version: 3.0 Mesa 11.2.2 GLSL Version: 1.30 OpenGL Vendor: VMware, Inc.
I added the
AA_UseDesktopOpenGL
attribute for Desktop:int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL); QApplication app(argc, argv); OpenGLWidget w; w.show(); return app.exec(); }
Now it prints the integrated video card info:
OpenGL Version: 3.1.0 - Build 9.17.10.4459 GLSL Version: 1.40 - Intel Build 9.17.10.4459 OpenGL Vendor: Intel
But it shows a white triangle instead of a red triangle on Desktop:
When I build this example for WebAssembly it shows a black window and the message:
WebGL: INVALID_OPERATION: drawArrays: no valid shader program in use
main.cpp
#include <QtGui/QOpenGLFunctions> #include <QtGui/QSurfaceFormat> #include <QtOpenGLWidgets/QOpenGLWidget> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtWidgets/QApplication> class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { public: OpenGLWidget() { resize(350, 350); setWindowTitle("Example"); } private: void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.4f, 0.8f, 0.9f, 1.f); qDebug() << "OpenGL Version:" << (const char*) glGetString(GL_VERSION); qDebug() << "GLSL Version:" << (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION); qDebug() << "OpenGL Vendor:" << (const char*) glGetString(GL_VENDOR); QString vertexShaderSource = "attribute vec2 aPosition;\n" "void main()\n" "{\n" " gl_Position = vec4(aPosition, 0.0, 1.0);\n" "}\n"; QString fragmentShaderSource = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "//out vec4 fragColor;\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"; m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertexShaderSource); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragmentShaderSource); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.f, 0.5f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2); m_program.enableAttributeArray("aPosition"); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 4); } private: QOpenGLShaderProgram m_program; QOpenGLBuffer m_vertPosBuffer; }; int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL); QApplication app(argc, argv); OpenGLWidget w; w.show(); return app.exec(); }
pro
QT += core gui openglwidgets widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp
-
I tried to activate the discrete video card to see the red triangle on Desktop by adding this code at the beginning of main.cpp:
#ifdef _WIN32 #include <windows.h> extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; #endif
The program print this info to the Qt Creater console that means that the discrete card was activated:
OpenGL Version: 4.6.0 NVIDIA 391.35 GLSL Version: 4.60 NVIDIA OpenGL Vendor: NVIDIA Corporation
But it draws a white triangle with
Qt 6.7.0 beta1
. -
I created a bug report about the problem above on Desktop:
Drawing a triangle doesn't work on laptop Asus K53SV with Mesa using Qt 6.7.0 beta1
: https://bugreports.qt.io/browse/QTBUG-120949 -
I created a separated topic for the problem above on Desktop: Drawing a triangle doesn't work on laptop Asus K53SV with Mesa using Qt 6.7.0 beta1
-
@Christian-Ehrlicher solved the problem above for Desktop. I forgot to activate (bind) the program in paintGL():
void paintGL() override { m_program.bind(); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 4); }
This program works on Desktop but it still doesn't work on WebAssembly. I use
Qt 6.7.0 beta1
. But now it doesn't print this messageWebGL: INVALID_OPERATION: drawArrays: no valid shader program in use
to the browser console. The window is black on browser.pro
QT += core gui openglwidgets widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp
main.cpp
#include <QtGui/QOpenGLFunctions> #include <QtGui/QSurfaceFormat> #include <QtOpenGLWidgets/QOpenGLWidget> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtWidgets/QApplication> class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { public: OpenGLWidget() { resize(350, 350); setWindowTitle("OpenGL Triangle"); } private: void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.4f, 0.8f, 0.9f, 1.f); qDebug() << "OpenGL Version:" << (const char*) glGetString(GL_VERSION); qDebug() << "GLSL Version:" << (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION); qDebug() << "OpenGL Vendor:" << (const char*) glGetString(GL_VENDOR); QString vertexShaderSource = "attribute vec2 aPosition;\n" "void main()\n" "{\n" " gl_Position = vec4(aPosition, 0.0, 1.0);\n" "}\n"; QString fragmentShaderSource = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "//out vec4 fragColor;\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"; m_program.create(); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertexShaderSource); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragmentShaderSource); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.f, 0.5f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2); m_program.enableAttributeArray("aPosition"); } void paintGL() override { m_program.bind(); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 4); } private: QOpenGLShaderProgram m_program; QOpenGLBuffer m_vertPosBuffer; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); OpenGLWidget w; w.show(); return app.exec(); }
-
I made a bug report for drawing a triangle without clicking. It draws a black screen. I attacked a zip here: https://bugreports.qt.io/browse/QTBUG-120954
-
The solution for drawing a triangle with
Qt 6.7.0 beta1
is to add bind() for the vertex buffer:  void paintGL() override   {     m_program.bind();     m_vertPosBuffer.bind();     m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2);     m_program.enableAttributeArray("aPosition");     glClear(GL_COLOR_BUFFER_BIT);     glDrawArrays(GL_TRIANGLES, 0, 3);   }
But why a background is black?
I set it to blue. If I switch to Desktop I see the blue background:
pro
QT += core gui openglwidgets widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp
main.cpp
#include <QtGui/QOpenGLFunctions> #include <QtGui/QSurfaceFormat> #include <QtOpenGLWidgets/QOpenGLWidget> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtWidgets/QApplication> class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { public: OpenGLWidget() { resize(350, 350); setWindowTitle("OpenGL Triangle"); } private: void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.4f, 0.8f, 0.9f, 1.f); qDebug() << "OpenGL Version:" << (const char*) glGetString(GL_VERSION); qDebug() << "GLSL Version:" << (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION); qDebug() << "OpenGL Vendor:" << (const char*) glGetString(GL_VENDOR); QString vertexShaderSource = "attribute vec2 aPosition;\n" "void main()\n" "{\n" " gl_Position = vec4(aPosition, 0.0, 1.0);\n" "}\n"; QString fragmentShaderSource = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"; m_program.create(); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertexShaderSource); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragmentShaderSource); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.f, 0.5f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); } void paintGL() override { m_program.bind(); m_vertPosBuffer.bind(); m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2); m_program.enableAttributeArray("aPosition"); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); } private: QOpenGLShaderProgram m_program; QOpenGLBuffer m_vertPosBuffer; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); OpenGLWidget w; w.show(); return app.exec(); }
-
So when I run an example above on WebAssembly it draws a background in black color. I created a bug report: https://bugreports.qt.io/browse/QTBUG-120956
-
I found a way how to draw a custom background color. In the example above I set a background color in the
initializeGL()
method:void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.4f, 0.8f, 0.9f, 1.f);
But now I moved the setting of background color to the
paintGL()
method:void paintGL() override { // ... glClearColor(0.4f, 0.8f, 0.9f, 1.f); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); }
pro
QT += core gui openglwidgets widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp
main.cpp
#include <QtGui/QOpenGLFunctions> #include <QtGui/QSurfaceFormat> #include <QtOpenGLWidgets/QOpenGLWidget> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtWidgets/QApplication> class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { public: OpenGLWidget() { resize(350, 350); setWindowTitle("OpenGL Triangle"); } private: void initializeGL() override { initializeOpenGLFunctions(); qDebug() << "OpenGL Version:" << (const char*) glGetString(GL_VERSION); qDebug() << "GLSL Version:" << (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION); qDebug() << "OpenGL Vendor:" << (const char*) glGetString(GL_VENDOR); QString vertexShaderSource = "attribute vec2 aPosition;\n" "void main()\n" "{\n" " gl_Position = vec4(aPosition, 0.0, 1.0);\n" "}\n"; QString fragmentShaderSource = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"; m_program.create(); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertexShaderSource); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragmentShaderSource); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.f, 0.5f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); } void paintGL() override { m_program.bind(); m_vertPosBuffer.bind(); m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2); m_program.enableAttributeArray("aPosition"); glClearColor(0.4f, 0.8f, 0.9f, 1.f); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); } private: QOpenGLShaderProgram m_program; QOpenGLBuffer m_vertPosBuffer; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); OpenGLWidget w; w.show(); return app.exec(); }
-
This is a solution of the topic with picking color of a triangle. I didn't test it in
Qt 6.6.1
. It works inQt 6.7.0 beta1
.- The shader program must be bind before drawing
- The vertex buffer must be bind before drawing
glClearColor
must be called beforeglClear
inpaintGL
for WebAssembly
This example prints a color in the point of mouse click using the
glReadPixles
method:void paintGL() override { glClearColor(0.2f, 0.2f, 0.2f, 1.f); glClear(GL_COLOR_BUFFER_BIT); m_program.bind(); m_vertPosBuffer.bind(); m_program.setAttributeBuffer(m_aPositionLocation, GL_FLOAT, 0, 2); m_program.enableAttributeArray(m_aPositionLocation); glDrawArrays(GL_TRIANGLES, 0, 3); // qDebug() << glGetError() << "\n"; if (m_mouseClicked) { // Read the pixel GLubyte pixel[4]; glReadPixels(m_mouseX, m_mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); // qDebug() << glGetError() << "\n"; qDebug() << pixel[0] / 255.f << pixel[1] / 255.f << pixel[2] / 255.f; m_mouseClicked = false; } }
pro
QT += core gui openglwidgets widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp TARGET = app
main.cpp
#include <QtGui/QOpenGLFunctions> #include <QtGui/QMouseEvent> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtOpenGLWidgets/QOpenGLWidget> #include <QtWidgets/QApplication> #include <QtWidgets/QLabel> #include <QtWidgets/QVBoxLayout> #include <QtWidgets/QWidget> class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { Q_OBJECT private: void initializeGL() override { initializeOpenGLFunctions(); QString vertexShaderSource = "attribute vec2 aPosition;\n" "void main()\n" "{\n" " gl_Position = vec4(aPosition, 0.0, 1.0);\n" "}\n"; QString fragmentShaderSource = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"; m_program.create(); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertexShaderSource); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragmentShaderSource); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.f, 0.5f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); m_aPositionLocation = m_program.attributeLocation("aPosition"); } void paintGL() override { glClearColor(0.2f, 0.2f, 0.2f, 1.f); glClear(GL_COLOR_BUFFER_BIT); m_program.bind(); m_vertPosBuffer.bind(); m_program.setAttributeBuffer(m_aPositionLocation, GL_FLOAT, 0, 2); m_program.enableAttributeArray(m_aPositionLocation); glDrawArrays(GL_TRIANGLES, 0, 3); // qDebug() << glGetError() << "\n"; if (m_mouseClicked) { // Read the pixel GLubyte pixel[4]; glReadPixels(m_mouseX, m_mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); // qDebug() << glGetError() << "\n"; qDebug() << pixel[0] / 255.f << pixel[1] / 255.f << pixel[2] / 255.f; m_mouseClicked = false; } } void mousePressEvent(QMouseEvent *event) override { m_mouseX = event->pos().x(); m_mouseY = height() - event->pos().y() - 1; m_mouseClicked = true; update(); } private: int m_mouseX; int m_mouseY; bool m_mouseClicked = false; QOpenGLBuffer m_vertPosBuffer; QOpenGLShaderProgram m_program; int m_aPositionLocation; }; class MainWindow : public QWidget { Q_OBJECT public: MainWindow() { setWindowTitle("Pick a red or green triangle"); resize(350, 350); m_nameLabel = new QLabel("Click on a triangle or background"); m_nameLabel->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed); OpenGLWidget *openGLWidget = new OpenGLWidget(); QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(m_nameLabel); layout->addWidget(openGLWidget); setLayout(layout); } private: QLabel *m_nameLabel; }; #include "main.moc" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow w; w.show(); return app.exec(); }
-
8 8Observer8 has marked this topic as solved on
-
Piotr WierciĆski wrote here: https://bugreports.qt.io/browse/QTBUG-120956 that it is better to use QOpenGLWindow instead of QOpenGLWidget with WebAssembly:
If separate context is needed, consider using QOpenGLWindow , which will have it's own canvas in DOM and it's own WebGL context, instead of QOpenGLWidget
I tried it and he is right. With QOpenGLWindow I can call
glClearColor
ininitializeGL
:#include <QtGui/QOpenGLFunctions> #include <QtOpenGL/QOpenGLWindow> #include <QtWidgets/QApplication> class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions { void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.2f, 0.5f, 0.3f, 1.f); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); OpenGLWindow w; w.show(); return app.exec(); }
background-color-qopenglwindow-webassembly-qt6-cpp.pro
QT += core gui opengl widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp TARGET = app
-
I even must not bind a shader program (
m_program.bind()
) and a vertex buffer (m_vertPosBuffer.bind()
) inside ofpaintGL
with QOpenGLWindow:main.cpp
#include <QtGui/QOpenGLFunctions> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtOpenGL/QOpenGLWindow> #include <QtWidgets/QApplication> class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions { QOpenGLBuffer m_vertPosBuffer; QOpenGLShaderProgram m_program; void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.2f, 0.5f, 0.3f, 1.f); QString vertexShaderSource = "attribute vec2 aPosition;\n" "void main()\n" "{\n" " gl_Position = vec4(aPosition, 0.0, 1.0);\n" "}\n"; QString fragmentShaderSource = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"; m_program.create(); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertexShaderSource); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragmentShaderSource); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.f, 0.5f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2); m_program.enableAttributeArray("aPosition"); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); OpenGLWindow w; w.show(); return app.exec(); }
simple-triangle-qopenglwindow-qt6-cpp.pro
QT += core gui opengl widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp TARGET = app
-
Color picking with
glReadPixels
works without problems on WebAssembly withQOpenGLWindow
andQOpenGLWidget
:main.cpp
#include <QtGui/QMouseEvent> #include <QtGui/QOpenGLFunctions> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtOpenGL/QOpenGLWindow> #include <QtWidgets/QApplication> class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions { int m_mouseX; int m_mouseY; bool m_mouseClicked = false; QOpenGLBuffer m_vertPosBuffer; QOpenGLShaderProgram m_program; void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.2f, 0.2f, 0.2f, 1.f); QString vertexShaderSource = "attribute vec2 aPosition;\n" "void main()\n" "{\n" " gl_Position = vec4(aPosition, 0.0, 1.0);\n" "}\n"; QString fragmentShaderSource = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"; m_program.create(); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertexShaderSource); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragmentShaderSource); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.f, 0.5f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2); m_program.enableAttributeArray("aPosition"); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); if (m_mouseClicked) { // Read the pixel GLubyte pixel[4]; glReadPixels(m_mouseX, m_mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); // qDebug() << glGetError() << "\n"; qDebug() << pixel[0] / 255.f << pixel[1] / 255.f << pixel[2] / 255.f; m_mouseClicked = false; } } void mousePressEvent(QMouseEvent *event) override { m_mouseX = event->pos().x(); m_mouseY = height() - event->pos().y() - 1; m_mouseClicked = true; update(); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); OpenGLWindow w; w.show(); return app.exec(); }
pick-color-of-simple-triangle-qopenglwindow-qt6-cpp.pro
QT += core gui opengl widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp TARGET = app
-
Color picking with
glReadPixels
works without problems on WebAssembly withQOpenGLWindow
andQOpenGLWidget
:main.cpp
#include <QtGui/QMouseEvent> #include <QtGui/QOpenGLFunctions> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtOpenGL/QOpenGLWindow> #include <QtWidgets/QApplication> class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions { int m_mouseX; int m_mouseY; bool m_mouseClicked = false; QOpenGLBuffer m_vertPosBuffer; QOpenGLShaderProgram m_program; void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.2f, 0.2f, 0.2f, 1.f); QString vertexShaderSource = "attribute vec2 aPosition;\n" "void main()\n" "{\n" " gl_Position = vec4(aPosition, 0.0, 1.0);\n" "}\n"; QString fragmentShaderSource = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"; m_program.create(); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertexShaderSource); m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragmentShaderSource); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.f, 0.5f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2); m_program.enableAttributeArray("aPosition"); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); if (m_mouseClicked) { // Read the pixel GLubyte pixel[4]; glReadPixels(m_mouseX, m_mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); // qDebug() << glGetError() << "\n"; qDebug() << pixel[0] / 255.f << pixel[1] / 255.f << pixel[2] / 255.f; m_mouseClicked = false; } } void mousePressEvent(QMouseEvent *event) override { m_mouseX = event->pos().x(); m_mouseY = height() - event->pos().y() - 1; m_mouseClicked = true; update(); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); OpenGLWindow w; w.show(); return app.exec(); }
pick-color-of-simple-triangle-qopenglwindow-qt6-cpp.pro
QT += core gui opengl widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp TARGET = app
@8Observer8 said in Qt 6.6.1 WebAssebly: Triangle disappears when it was clicked:
Color picking with glReadPixels works without problems on WebAssembly with QOpenGLWindow and QOpenGLWidget
I had a problem with color picking on Android but it was solved here: https://forum.qt.io/post/787931