Advertisement

[Mixing QT3D and QOpenGL]

Started by July 05, 2022 08:03 AM
0 comments, last by ogldev1 2 years, 5 months ago

Hello,

I hope you're all doing well.

So I've been developing this application that renders a textured cube and rotates using quaternions. [I'm working with Qt6 and I'm using QOpenGL].

Then I wanted to chnage the cube with another textured 3D model that I loaded using QT3D. this means I didn't draw the cube then add the texture, I loaded the full model.

I've looked for several solutions to do that, I found a tutorial that has 21 episodes and followed every steps but the application kept crashing and I felt really exhasuted because I couldn't rewatch 21 episodes that last about 1 hour.

So I kept searching for an easier way to load the 3D model and found an example with QT3D. It finally worked ( I created a new project and followed the same steps). I tried to draw some other objects ( not load them) using opengl but that didn't work.

Now I want to integrate this part in the main project however I'm not sure about mising QT3D and QOpenGL together.

So I'm wondering if there is a way to do that.

Load the model using QT3D then continue to work on it ( apply transformations and add other objects) using QOpenGL.

The example I worked with uses QT3D and QTransform class to apply transformation on the model and the fix the position of the camera.

Here is how I loaded the model with QT3D: (sorry for the long code)

#include <QApplication>

#include <Qt3DCore/QEntity>

#include <Qt3DRender/QCamera>

#include <Qt3DRender/QCameraLens>

#include <Qt3DCore/QTransform>

#include <Qt3DCore/QAspectEngine>

#include <QWidget>

#include <QPainter>

#include <QHBoxLayout>

#include <Qt3DInput/QInputAspect>

#include <QScreen>

#include <Qt3DRender/QRenderAspect>

#include <Qt3DRender/QGeometryRenderer>

#include <Qt3DExtras/QForwardRenderer>

#include <Qt3DExtras/QPhongMaterial>

#include <Qt3DExtras/QSphereMesh>

#include <Qt3DExtras/QTorusMesh>

#include <Qt3DRender/QPointLight>

#include <QPropertyAnimation>

#include <QFileInfo>

#include "qt3dwindow.h"

#include "Orbittransformcontroller.h"

#include "qorbitcameracontroller.h"

#include <QDir>

#include <QMatrix4x4>

#include <GL/gl.h>

#include <GL/glu.h>

#include <QOpenGLFunctions>

int main(int argc, char* argv[])

{

QApplication app(argc, argv);

Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();

//view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));

view->defaultFrameGraph()->setClearColor(QColor(255,255,255,1));

QWidget *container = QWidget::createWindowContainer(view);

QSize screenSize = view->screen()->size();

container->setMinimumSize(QSize(200, 100));

container->setMaximumSize(screenSize);

QWidget *widget = new QWidget;

QHBoxLayout *hLayout = new QHBoxLayout(widget);

hLayout->addWidget(container, 1);

widget->setWindowTitle(QStringLiteral("Satellite"));

Qt3DInput::QInputAspect *input = new Qt3DInput::QInputAspect;

view->registerAspect(input);

// Root entity

Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();

// Camera

Qt3DRender::QCamera *cameraEntity = view->camera();

cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 100000.0f);

cameraEntity->setPosition(QVector3D(-40000, 40000, 40000.0f));

cameraEntity->setUpVector(QVector3D(0, 0, 1));

//cameraEntity->setViewCenter(QVector3D(0, 0, 10000));

cameraEntity->setViewCenter(QVector3D(0, 0, 100000));

Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);

Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);

light->setColor("white");

light->setIntensity(1);

lightEntity->addComponent(light);

Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);

lightTransform->setTranslation(cameraEntity->position());

lightEntity->addComponent(lightTransform);

//Loading .ply data

const QUrl data = QUrl::fromLocalFile("C:/Users/nahra/3DModel_qt3d/Model3D/challengeone.PLY");

qDebug() << data << data.isValid() << data.toLocalFile() << QFileInfo(data.toLocalFile()).exists() << data.fileName();

qDebug() << QDir::currentPath();

Qt3DRender::QMesh *bodyMesh = new Qt3DRender::QMesh();

bodyMesh->setMeshName("bodyMesh");

bodyMesh->setSource(data);

Qt3DCore::QTransform *bodyTransform = new Qt3DCore::QTransform;

bodyTransform->setScale3D(QVector3D(90.0, 90.0, 90.0));

bodyTransform->setRotationX(90.0);

// bodyTransform->setRotation(QQuaternion(0.7,0.0,0.7,0.0));

bodyTransform->setTranslation(QVector3D(0.0,0.0,5.0)); //translation doesn't work

Qt3DExtras::QPhongMaterial *bodyMaterial = new Qt3DExtras::QPhongMaterial();

// bodyMaterial->setDiffuse(QColor(QRgb(0x928327)));

Qt3DCore::QEntity *plyEntity = new Qt3DCore::QEntity(rootEntity);

plyEntity->addComponent(bodyMesh);

plyEntity->addComponent(bodyMaterial);

plyEntity->addComponent(bodyTransform);

// Set root object of the scene

view->setRootEntity(rootEntity);

// Show window

widget->show();

widget->resize(1200, 800);

return app.exec();

}

I think that camera entity here is the equivalent of gluLookAt in opengl or lookAt in QOpenGL.

And bodyTransform is the equivalent of the model matrix.

I just want to load the model and keep working on it using QOpenGL functions.

I want to do something like this:

glMatrixMode(GL_PROJECTION);

glLoadMatrixf(cameraEntity->lens());
glMatrixMode(GL_MODELVIEW);

glLoadMatrixf(bodyTransform);

gluLookAt(2.0,2.0,0.0,0.0,0.0,-5.0,0.0,1.0,0.0);

glTranslatef(0.0,0.0,-5.0);
glRotatef(180.0,0.0,1.0,0.0);

glRotatef(-90.0,1.0,0.0,0.0);
glScalef(0.4,0.4,0.4);

drawOrbitalFrame

I want to load the modelview and projection matrices into the opengl pipeline.

I can't do that because cameraEntity→lens() is a QCamera and bodyTransform is a QTransform. These are not matrices.

EDIT: What I did is that I store the projection and model matrices values like this:
projection=cameraEntity->projectionMatrix();

viewmatrix=cameraEntity->viewMatrix();

model=bodyTransform->matrix();

then I calculated the modelview matrix ( product of viewmatrix and model)

And then:

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(projection.constData());

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(modelview.constData());
glTranslatef(0.0,0.0,-5.0);

glRotatef(180.0,0.0,1.0,0.0);
glRotatef(-90.0,1.0,0.0,0.0);

glScalef(0.4,0.4,0.4);

// draw coordinate system

I loaded them in the OpenGL pipeline and tried to draw a coordinate system but that didn't work.

Please help.

Thank you all.

This topic is closed to new replies.

Advertisement