Good morning,
I developed an application that renders a textured cube and rotates it using quaternions. I used Qt6 and QOpenGL functions to make this work.
Then I wanted to load a full 3D model ( without drawing it using shaders or opengl functions ). So I kept looking for many methods and ended up using an example with QT3D to load a file.PLY.
The problem is that I need the model matrix of the object so that I can perform transformations on it.
I know I can do it using QTransform class functions but I don't want to do that. Here is the code I used to load the ply file. It works perfectly
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);//projection
cameraEntity->setPosition(QVector3D(-40000, 40000, 40000.0f));
cameraEntity->setUpVector(QVector3D(0, 0, 1));
//cameraEntity->setViewCenter(QVector3D(0, 0, 10000));
cameraEntity->setViewCenter(QVector3D(0, 0, 10));
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("PATH/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);
Qt3DExtras::QPhongMaterial *bodyMaterial = new Qt3DExtras::QPhongMaterial();
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();
}
Now I think the bodyTransform in this example is equivalent to the model matrix since we can apply transformations on it. And the camera entity is equivalent to gluLookAt or lookAt( QopenGL function).
But in the old code where I can rotate the model, I'm working with QOpenGL functions and I don't want to change all of it.
My question is the following: Is it possible to keep working with QOpenGL and inside the paintGL function, use the QT3D library to just load the model and then assign a model view matrix to it that can be manipulated using QOpenGL functions and not QTransform.
In the example of QT3D, I tried to draw objects using the old OpenGL functions like glvertex but they weren't rendered in the scene.
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);
DrawOribtalFrame();
I mean I want to load both projection and modelview matrices into the openGL pipeline and use the modelview to draw and manipulate other objects.
Of course the code I wrote above isn't correct because bodyTransform is a QTransform and cameraEntity is a QCamera. they're not Matrices (QMatrix4x4 class).
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.
Thank you all for your help.