Is openGL, GLU, GLUT not supported in qt for wasm
-
OS: ubuntu 22.04, QT: 6.6.2, qt for wasm
While compiling a QT code for wasm I get error:
wasm-ld: error: MyGLCanvas.o: undefined symbol: gluPerspective wasm-ld: error: MyGLCanvas.o: undefined symbol: glShadeModel wasm-ld: error: MyGLCanvas.o: undefined symbol: glLightModelfv wasm-ld: error: MyGLCanvas.o: undefined symbol: glLightfv wasm-ld: error: MyGLCanvas.o: undefined symbol: glColorMaterial wasm-ld: error: MyGLCanvas.o: undefined symbol: glMaterialfv wasm-ld: error: MyGLCanvas.o: undefined symbol: glLightModeli wasm-ld: error: MyGLCanvas.o: undefined symbol: glTranslatef wasm-ld: error: MyGLCanvas.o: undefined symbol: glMultMatrixd
relevant parts of the pro file:
CONFIG += c++17 QMAKE_CXXFLAGS += -fPIC QT += widgets core gui opengl openglwidgets INCLUDEPATH += /usr/local/Qt6/include SOURCES += main.cpp \ MyGLCanvas.cpp HEADERS += MyGLCanvas.h LIBS += -lGL -lGLU -lglut -lGLESv2
I am linking to OpenGL, GLU and GLUT. However definitions for OpenGL functions such as gluPerspective, glShadeModel, glLightModelfv, glLightfv, glColorMaterial, glMaterialfv, glLightModeli, glTranslatef, and glMultMatrixd are missing.
Is openGL, GLU, GLUT not supported in qt for wasm ?
Or the .pro file is not able to find the corresponding libs.
How do I overcome these linking errors? -
@Ronel_qtmaster if Qt for wasm did not support OpenGL it would be problematic for Qt Quick applications to run. You are likely referring to the QOpenGLWidget issue which is reportedly fixed.
What likely happens here is that @shome is linking to its host OpenGL libraries hence the missing symbols errors.
That said, why use GLU and GLUT directly ? Use the Qt infrastructure especially if you want to compile for wasm.
-
@SGaist : My actual code uses the opengl functions gluPerspective, glShadeModel, glLightModelfv, glLightfv, glColorMaterial, glMaterialfv, glLightModeli, glTranslatef, and glMultMatrixd.
I have the following MWE which uses each of the above functions. It compiles and runs fine if I use qt6.6.2 (NOt for wasm). However it gives linker errors when I try to compile with qt for web assembly.
How to compile the example below for qt for wasm?
main.cpp
#include <QApplication> #include <QOpenGLWidget> #include <GL/glut.h> #include <GL/glu.h> class GLWidget : public QOpenGLWidget { protected: void initializeGL() override { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Enable depth testing glEnable(GL_DEPTH_TEST); // Set shading model to smooth glShadeModel(GL_SMOOTH); // Set ambient light GLfloat ambientLight[] = {0.2, 0.2, 0.2, 1.0}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); // Set a light source GLfloat lightPosition[] = {0.0, 0.0, 10.0, 1.0}; GLfloat lightColor[] = {1.0, 1.0, 1.0, 1.0}; glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); // Enable color tracking glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_DIFFUSE); // Set material properties GLfloat matSpecular[] = {1.0, 1.0, 1.0, 1.0}; glMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular); glMaterialf(GL_FRONT, GL_SHININESS, 50.0); // Set the perspective projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, 800.0 / 600.0, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); } void resizeGL(int w, int h) override { glViewport(0, 0, w, h); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); // Move the teapot back a bit glTranslatef(0.0f, 0.0f, -5.0f); // Rotate the teapot static float angle = 0.0f; angle += 1.0f; glRotatef(angle, 0.0f, 1.0f, 0.0f); // Draw the teapot glutSolidTeapot(1.0); } }; int main(int argc, char *argv[]) { // Initialize GLUT glutInit(&argc, argv); QApplication app(argc, argv); GLWidget widget; widget.resize(800, 600); widget.show(); return app.exec(); }
QT += core gui opengl openglwidgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = OpenGLWidget TEMPLATE = app SOURCES += main.cpp LIBS += -lGL -lGLU -lglut
When I compile with qt for wasm, I get error:
em++ -s 'ASYNCIFY_IMPORTS=qt_asyncify_suspend_js,qt_asyncify_resume_js' -s WASM=1 -s MAX_WEBGL_VERSION=2 -s ERROR_ON_UNDEFINED_SYMBOLS=1 --bind -s FETCH=1 -s MODULARIZE=1 -s EXPORT_NAME=createQtAppInstance -s WASM_BIGINT=1 -s STACK_SIZE=5MB -O2 -s EXPORTED_RUNTIME_METHODS=UTF16ToString,stringToUTF16,JSEvents,specialHTMLTargets,FS -sALLOW_MEMORY_GROWTH -s INITIAL_MEMORY=50MB /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledFreetype.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledLibpng.a -o OpenGLWidget.js main.o openglwidget.js_plugin_import.o -lGL -lGLU -lglut /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/plugins/platforms/wasm/CMakeFiles/QWasmIntegrationPlugin_resources_1.dir/./.rcc/qrc_wasmfonts.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/plugins/platforms/wasm/CMakeFiles/QWasmIntegrationPlugin_resources_2.dir/./.rcc/qrc_wasmwindow.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/gui/CMakeFiles/Gui_resources_1.dir/./.rcc/qrc_qpdf.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/gui/CMakeFiles/Gui_resources_2.dir/./.rcc/qrc_gui_shaders.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/plugins/platforms/libqwasm.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/plugins/imageformats/libqgif.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/plugins/imageformats/libqico.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/plugins/imageformats/libqjpeg.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledLibjpeg.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/widgets/CMakeFiles/Widgets_resources_1.dir/./.rcc/qrc_qstyle.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/widgets/CMakeFiles/Widgets_resources_2.dir/./.rcc/qrc_qstyle1.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/widgets/CMakeFiles/Widgets_resources_3.dir/./.rcc/qrc_qmessagebox.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6OpenGLWidgets.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6OpenGL.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6Widgets.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6Gui.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledHarfbuzz.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledFreetype.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledLibpng.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6Core.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledZLIB.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledPcre2.a -lembind wasm-ld: error: main.o: undefined symbol: glShadeModel wasm-ld: error: main.o: undefined symbol: glLightModelfv wasm-ld: error: main.o: undefined symbol: glLightfv wasm-ld: error: main.o: undefined symbol: glLightfv wasm-ld: error: main.o: undefined symbol: glColorMaterial wasm-ld: error: main.o: undefined symbol: glMaterialfv wasm-ld: error: main.o: undefined symbol: glMaterialf wasm-ld: error: main.o: undefined symbol: gluPerspective wasm-ld: error: main.o: undefined symbol: glTranslatef wasm-ld: error: main.o: undefined symbol: glRotatef wasm-ld: error: main.o: undefined symbol: glutSolidTeapot em++: error: '/home/neo/Desktop/softwares/emsdk/upstream/bin/wasm-ld -o OpenGLWidget.wasm /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledFreetype.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledLibpng.a main.o openglwidget.js_plugin_import.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/plugins/platforms/wasm/CMakeFiles/QWasmIntegrationPlugin_resources_1.dir/./.rcc/qrc_wasmfonts.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/plugins/platforms/wasm/CMakeFiles/QWasmIntegrationPlugin_resources_2.dir/./.rcc/qrc_wasmwindow.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/gui/CMakeFiles/Gui_resources_1.dir/./.rcc/qrc_qpdf.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/gui/CMakeFiles/Gui_resources_2.dir/./.rcc/qrc_gui_shaders.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/plugins/platforms/libqwasm.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/plugins/imageformats/libqgif.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/plugins/imageformats/libqico.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/plugins/imageformats/libqjpeg.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledLibjpeg.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/widgets/CMakeFiles/Widgets_resources_1.dir/./.rcc/qrc_qstyle.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/widgets/CMakeFiles/Widgets_resources_2.dir/./.rcc/qrc_qstyle1.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/src/widgets/CMakeFiles/Widgets_resources_3.dir/./.rcc/qrc_qmessagebox.cpp.o /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6OpenGLWidgets.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6OpenGL.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6Widgets.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6Gui.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledHarfbuzz.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledFreetype.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledLibpng.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6Core.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledZLIB.a /home/neo/Desktop/softwares/qt662_wasm/qt6/qtbase/lib/libQt6BundledPcre2.a -L/home/neo/Desktop/softwares/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten --whole-archive -lfetch -lembind-rtti -lGL-webgl2 --no-whole-archive -lal -lhtml5 -lstubs -lnoexit -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmpe90fcei8libemscripten_js_symbols.so --strip-debug --export-if-defined=main --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=__main_argc_argv --export=stackSave --export=stackRestore --export=stackAlloc --export=__errno_location --export=malloc --export=free --export=__wasm_call_ctors --export-table -z stack-size=5242880 --initial-memory=52428800 --no-entry --max-memory=2147483648 --global-base=1024' failed (returned 1) make: *** [Makefile:171: OpenGLWidget.js] Error 1
-
-
As explained before, you are linking your desktop libraries to your wasm project. It does not work like that.
You should go through emscripten documentation about OpenGL support.
-
@shome said in Is openGL, GLU, GLUT not supported in qt for wasm:
My actual code uses the opengl functions gluPerspective, glShadeModel, glLightModelfv, glLightfv, glColorMaterial, glMaterialfv, glLightModeli, glTranslatef, and glMultMatrixd.
WebGL doesn't support these functions. You should use OpenGL ES, shaders and QMatrix4x4 instead.
My example can help you. It draws a triangle. You can run it in the browser: https://65fb01d024b197009c29122c--lustrous-croissant-656612.netlify.app/ It is a free hosting: netlify.com My example uses QOpenGLWindow instead of QOpenGLWidget. QOpenGLWindow is better for WebAssembly.
pro:
QT += core gui opengl widgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp
main.cpp
#include <QtGui/QOpenGLFunctions> #include <QtGui/QSurfaceFormat> #include <QtOpenGL/QOpenGLBuffer> #include <QtOpenGL/QOpenGLWindow> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtWidgets/QApplication> class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions { public: OpenGLWindow() { resize(350, 350); setTitle("OpenGL ES 2.0 Triangle"); } private: void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.4f, 0.8f, 0.9f, 1.f); qDebug() << "OpenGL Version:" << (const char*) glGetString(GL_VERSION) << "\n"; qDebug() << "GLSL Version:" << (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION) << "\n"; qDebug() << "OpenGL Vendor:" << (const char*) glGetString(GL_VENDOR) << "\n"; 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::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL); QApplication app(argc, argv); OpenGLWindow w; w.show(); return app.exec(); }