Qt 6.6.1 WebAssembly: Triangle disappears when it was clicked
-
Hello,
When I click on a triangle it disappears:
Before a click:
After a click:
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(); glClearColor(0.f, 1.f, 0.f, 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" "//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_aPositionLocation = m_program.attributeLocation("aPosition"); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); m_program.setAttributeBuffer(m_aPositionLocation, GL_FLOAT, 0, 2); m_program.enableAttributeArray(m_aPositionLocation); 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() << 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("OpenGL, Qt6, C++"); resize(300, 300); m_nameLabel = new QLabel("Click on object 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(); }
pro
QT += core gui openglwidgets widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp TARGET = app
-
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(); }
-
I created the bug report: https://bugreports.qt.io/browse/QTBUG-120650
-
Have you tried changing the qt version? I use version 6.5.3, and all opengl-related displays are normal.
I am using qml and have not tested QOpenGLWidget
@JasonWong I deleted Qt 6.6.1 completely and installed Qt 6.5.3. When I run the example with a triangle (see a code example below. I see a triangle less than 1 second and it disappears. I see a black screen. The browser console has nothing. I see this warning in Qt Creator:
:-1: warning: This Qt was built with Emscripten version 3.1.25. You have 3.1.37. The difference may cause issues.
I deleted the "emsdk" folder with
emsdk 3.1.37
and installedemsdk 3.1.25
:> git clone https://github.com/emscripten-core/emsdk.git > cd emsdk > emsdk.bat install 3.1.25 > emsdk.bat activate 3.1.25
I don't see the warning message but the problem is the same. In Qt 6.6.1 I see a triangle and it disappears after a click but in Qt 6.5.3 I see a triangle less than 1 second without a click. I will delete
Qt 6.5.3
and I will tryQt 6.7.0 beta
.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
Log:
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 3837 Receiving objects: 100% (3884/3884), 2.16 MiB | 3.21 MiB/s, done. Resolving deltas: 100% (2552/2552), done. C:\>cd emsdk C:\emsdk>emsdk.bat install 3.1.25 Resolving SDK version '3.1.25' to 'sdk-releases-ff6babb041d0f31575cc16d15ef82c6222ca99b8-64bit' Installing SDK 'sdk-releases-ff6babb041d0f31575cc16d15ef82c6222ca99b8-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-ff6babb041d0f31575cc16d15ef82c6222ca99b8-64bit'.. Downloading: C:/emsdk/downloads/ff6babb041d0f31575cc16d15ef82c6222ca99b8-wasm-binaries.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/ff6babb041d0f31575cc16d15ef82c6222ca99b8/wasm-binaries.zip, 455169988 Bytes Unpacking 'C:/emsdk/downloads/ff6babb041d0f31575cc16d15ef82c6222ca99b8-wasm-binaries.zip' to 'C:/emsdk/upstream' Done installing tool 'releases-ff6babb041d0f31575cc16d15ef82c6222ca99b8-64bit'. Done installing SDK 'sdk-releases-ff6babb041d0f31575cc16d15ef82c6222ca99b8-64bit'. C:\emsdk>emsdk.bat activate 3.1.25 Resolving SDK version '3.1.25' to 'sdk-releases-ff6babb041d0f31575cc16d15ef82c6222ca99b8-64bit' Setting the following tools as active: node-16.20.0-64bit python-3.9.2-nuget-64bit java-8.152-64bit releases-ff6babb041d0f31575cc16d15ef82c6222ca99b8-64bit Next steps: - Consider running `emsdk activate` with --permanent or --system to have emsdk settings available on startup. Adding directories to PATH: PATH += C:\emsdk PATH += C:\emsdk\upstream\emscripten Setting environment variables: PATH = C:\emsdk;C:\emsdk\upstream\emscripten;C:\Program Files\Common Files\Oracle\Java\javapath;C:\WINDOWS\SYSTEM32;C:\WINDOWS;C:\WINDOWS\SYSTEM32\WBEM;C:\WINDOWS\SYSTEM32\WINDOWSPOWERSHELL\V1.0\;C:\WINDOWS\SYSTEM32\OPENSSH\;C:\PROGRAM FILES\NVIDIA CORPORATION\NVIDIA NVDLISR;C;C:\PROGRAM FILES\MONGODB\SERVER\4.4\BIN;C:\PROGRAM FILES (X86)\COMMON FILES\ULEAD SYSTEMS\MPEG;C:\PROGRAM FILES\NODEJS\;C:\PROGRAM FILES\GIT\CMD;C:\PROGRAM FILES\DOTNET\;E:\Program Files\Git\cmd;C:\Program Files\CMake\bin;C:\Users\8Observer8\.cargo\bin;E:\ProgramFiles\Python\Python38\Scripts\;E:\ProgramFiles\Python\Python38\;C:\Users\8Observer8\AppData\Local\Microsoft\WindowsApps;C:\Program Files\heroku\bin;E:\Program Files (installed)\sqlite-tools;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.1 Tools;E:\_Projects\node_modules\jasmine\bin;E:\bats;C:\Drivers\phantomjs-2.1.1-windows\bin;E:\_soft\upx-3.96-win32;C:\Users\8Observer8\AppData\Roaming\npm;C:\Qt\6.6.1\mingw_64\bin;C:\Qt\Tools\mingw1120_64\bin;E:\_soft\Converters\COLLADA2GLTF-v2.1.5-windows-Release-x64;E:\_Projects\node_modules\rollup\dist\bin;C:\Program Files (x86)\vim\vim80;C:\mongosh-1.6.0-win32-x64\bin;C:\Program Files\Sublime Text;C:\Qt\6.2.4\android_x86_64\bin;E:\Program Files (installed)\gradle-8.5\bin;E:\AppData\Android\SDK\cmdline-tools\latest\bin;E:\AppData\Android\SDK\platform-tools;E:\Program Files (installed)\fbx-conv;C:\Qt\Tools\Ninja;E:\Program Files (installed)\scrcpy-win64-v2.3.1;E:\AppData\Android\SDK\tools;E:\AppData\Android\SDK\ndk\25.1.8937393;C:\Qt\Tools\CMake_64\bin;E:\Program Files\Java\jdk-17;E:\AppData\Android\SDK; EMSDK = C:/emsdk EMSDK_NODE = C:\emsdk\node\16.20.0_64bit\bin\node.exe EMSDK_PYTHON = C:\emsdk\python\3.9.2-nuget_64bit\python.exe JAVA_HOME = C:\emsdk\java\8.152_64bit Clearing existing environment variable: EMSDK_PY The changes made to environment variables only apply to the currently running shell instance. Use the 'emsdk_env.bat' to re-enter this environment later, or if you'd like to register this environment permanently, rerun this command with the option --permanent.
-
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