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.