How to extend the Cube OpenGL ES 2.0 example for 3D meshes?
-
I have gone through the code of Cube OpenGL ES 2.0 example which displays a cube that can be manipulated using the mouse.
How to extend the above example for a 3D mesh. . I need to compile for wasm.
In my little understanding, I need to modify the function named void GeometryEngine::initCubeGeometry (refer geometryengine.cpp)
Here the cube is represented as triangle strip primitives . How to do the same for a 3D mesh.? Is there any API for the same?
Or do we need to use other libraries such as assimp or Qt3D? I need to compile for wasmThe code for that function is as below:
void GeometryEngine::initCubeGeometry() { // For cube we would need only 8 vertices but we have to // duplicate vertex for each face because texture coordinate // is different. VertexData vertices[] = { // Vertex data for face 0 {QVector3D(-1.0f, -1.0f, 1.0f), QVector2D(0.0f, 0.0f)}, // v0 {QVector3D( 1.0f, -1.0f, 1.0f), QVector2D(0.33f, 0.0f)}, // v1 {QVector3D(-1.0f, 1.0f, 1.0f), QVector2D(0.0f, 0.5f)}, // v2 {QVector3D( 1.0f, 1.0f, 1.0f), QVector2D(0.33f, 0.5f)}, // v3 // Vertex data for face 1 {QVector3D( 1.0f, -1.0f, 1.0f), QVector2D( 0.0f, 0.5f)}, // v4 {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.33f, 0.5f)}, // v5 {QVector3D( 1.0f, 1.0f, 1.0f), QVector2D(0.0f, 1.0f)}, // v6 {QVector3D( 1.0f, 1.0f, -1.0f), QVector2D(0.33f, 1.0f)}, // v7 // Vertex data for face 2 {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.5f)}, // v8 {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(1.0f, 0.5f)}, // v9 {QVector3D( 1.0f, 1.0f, -1.0f), QVector2D(0.66f, 1.0f)}, // v10 {QVector3D(-1.0f, 1.0f, -1.0f), QVector2D(1.0f, 1.0f)}, // v11 // Vertex data for face 3 {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.0f)}, // v12 {QVector3D(-1.0f, -1.0f, 1.0f), QVector2D(1.0f, 0.0f)}, // v13 {QVector3D(-1.0f, 1.0f, -1.0f), QVector2D(0.66f, 0.5f)}, // v14 {QVector3D(-1.0f, 1.0f, 1.0f), QVector2D(1.0f, 0.5f)}, // v15 // Vertex data for face 4 {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.33f, 0.0f)}, // v16 {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.0f)}, // v17 {QVector3D(-1.0f, -1.0f, 1.0f), QVector2D(0.33f, 0.5f)}, // v18 {QVector3D( 1.0f, -1.0f, 1.0f), QVector2D(0.66f, 0.5f)}, // v19 // Vertex data for face 5 {QVector3D(-1.0f, 1.0f, 1.0f), QVector2D(0.33f, 0.5f)}, // v20 {QVector3D( 1.0f, 1.0f, 1.0f), QVector2D(0.66f, 0.5f)}, // v21 {QVector3D(-1.0f, 1.0f, -1.0f), QVector2D(0.33f, 1.0f)}, // v22 {QVector3D( 1.0f, 1.0f, -1.0f), QVector2D(0.66f, 1.0f)} // v23 }; // Indices for drawing cube faces using triangle strips. // Triangle strips can be connected by duplicating indices // between the strips. If connecting strips have opposite // vertex order then last index of the first strip and first // index of the second strip needs to be duplicated. If // connecting strips have same vertex order then only last // index of the first strip needs to be duplicated. GLushort indices[] = { 0, 1, 2, 3, 3, // Face 0 - triangle strip ( v0, v1, v2, v3) 4, 4, 5, 6, 7, 7, // Face 1 - triangle strip ( v4, v5, v6, v7) 8, 8, 9, 10, 11, 11, // Face 2 - triangle strip ( v8, v9, v10, v11) 12, 12, 13, 14, 15, 15, // Face 3 - triangle strip (v12, v13, v14, v15) 16, 16, 17, 18, 19, 19, // Face 4 - triangle strip (v16, v17, v18, v19) 20, 20, 21, 22, 23 // Face 5 - triangle strip (v20, v21, v22, v23) }; //! [1] // Transfer vertex data to VBO 0 arrayBuf.bind(); arrayBuf.allocate(vertices, 24 * sizeof(VertexData)); // Transfer index data to VBO 1 indexBuf.bind(); indexBuf.allocate(indices, 34 * sizeof(GLushort)); //! [1] }
-
@shome said in How to extend the Cube OpenGL ES 2.0 example for 3D meshes?:
Or do we need to use other libraries such as assimp or Qt3D?
It depends. Requirements vary and tastes differ. You can also use
Qt Quick 3D
: https://doc.qt.io/qt-6/qtquick3d-index.html I didn't try to buildQt Quick 3D
orQt 3D
to WASM. If you research what is difference betweenQt 3D
andQt Quick 3D
you can post your results in the topic: Qt 3D vs Qt Quick 3DThis is my example of loading an object from COLLADA: https://github.com/8Observer8/load-3d-models-dae-openglwindow-opengles2-qt6-cpp I parse XML using QDomDocument. You can run it on Web: https://6602ec1abe3c4d529f4f5c7a--chic-pasca-73d8ca.netlify.app/
How it look when you set samples to 4:
Like this:
surfaceFormat.setSamples(4);
-
I changed
QOpenGLWindow
withQOpenGLWidget
in the example above. See how it looks: https://clinquant-pastelito-7b506b.netlify.app/I had the same issue for
QOpenGLWindow
: https://bugreports.qt.io/browse/QTBUG-122145But it was solved by setting Depth buffer size to 24:
QSurfaceFormat surfaceFormat; surfaceFormat.setDepthBufferSize(24); surfaceFormat.setSamples(4); setFormat(surfaceFormat);
But I don't know how to solve the same issue for
QOpenGLWidget
. Maybe I should create another bug report toQOpenGLWidget
. It is why I likeQOpenGLWindow
. -
@8Observer8 said in How to extend the Cube OpenGL ES 2.0 example for 3D meshes?:
Maybe I should create another bug report to QOpenGLWidget.
I have created it: https://bugreports.qt.io/browse/QTBUG-123787
-
@8Observer8 said in How to extend the Cube OpenGL ES 2.0 example for 3D meshes?:
I have created it: https://bugreports.qt.io/browse/QTBUG-123787
This problem with the depth buffer on
QOpenGLWidget
was solved. You should call the next commands inpaintGL()
(not in 'initializeGL()' like you can make onQOpenGLWindow
):glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE);
But I found another problem with
QOpenGLWidget
. The setSamples() method doesn't work onQOpenGLWidget
for WebAssembly:QSurfaceFormat surfaceFormat; // surfaceFormat.setDepthBufferSize(24); // Doesn't work on QOpenGLWidget for WebAssembly surfaceFormat.setSamples(4); // Doesn't work on QOpenGLWidget for WebAssembly setFormat(surfaceFormat);
Compare the same examples on
QOpenGLWidget
andQOpenGLWindow
. This isQOpenGLWidget
: https://6604427c5c350c16aa4551c3--clinquant-pastelito-7b506b.netlify.app/ GitHub: https://github.com/8Observer8/load-3d-models-dae-openglwidget-opengles2-qt6-cpp
This is
QOpenGLWindow
: https://chic-pasca-73d8ca.netlify.app/ GitHub: https://github.com/8Observer8/load-3d-models-dae-openglwidget-opengles2-qt6-cpp -
I created this bug report about the problem above with anti-aliasing on QOpenGLWidget: The setSamples() method doesn't work on QOpenGLWidget for WebAssembly
@Even-Oscar-Andersen answered in the bug report comments:
reproduced on 6.6.2,
This might be fixed in the not yet released 6.8.x (you will have to build yourself from dev)
I think that rebuilding
Qt dev
from source may be useful for those who want to useQOpenGLWidget
with Qt GUI on WASM with anti-aliasing. Maybe some people don’t need anti-aliasing. I don't need Qt GUI for my current tasks but I need anti-aliasing. I prefer to useQOpenGLWindow
because it allows to make smooth animation for WASM withoutQTimer
(animation with timer isn't smooth) using thesetSwapInterval(1)
method and theframeSwapped
signal:OpenGLWindow.cpp
OpenGLWindow::OpenGLWindow() { setTitle("OpenGL ES 2.0, Qt6, C++"); resize(m_initialWindowWidth, m_initialWindowHeight); QSurfaceFormat surfaceFormat; surfaceFormat.setDepthBufferSize(24); surfaceFormat.setSamples(4); surfaceFormat.setSwapInterval(1); connect(this, SIGNAL(frameSwapped()), this, SLOT(update())); setFormat(surfaceFormat); }
OpenGLWindow.h
#include <QtCore/QElapsedTimer> class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions { private: QElapsedTimer m_elapsedTimer; } void OpenGLWindow::paintGL() { float dt = m_elapsedTimer.elapsed() / 1000.f; m_elapsedTimer.restart(); qDebug() << dt; }