如何混合QT3D和Qopengl
早上好,
我开发了一个应用程序,该应用程序呈现纹理的立方体,并使用四局旋转它。 我使用QT6和Qopengl函数来完成这项工作。
然后,我想加载完整的3D模型(不使用着色器或OpenGL功能绘制它)。因此,我一直在寻找许多方法,最终使用QT3D的示例来加载文件。
问题是我需要对象的模型矩阵,以便可以在其上执行转换。
我知道我可以使用qtransform类功能来做到这一点,但我不想这样做。 这是我用来加载ply文件的代码。它的工作原理
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();
}
现在我认为此示例中的BodyTransform等效于模型矩阵,因为我们可以在其上应用转换。 相机实体等于glulookat或lookat(qopengl函数)。
但是在可以旋转模型的旧代码中,我正在使用Qopengl功能,但我不想更改所有功能。
我的问题是: 是否可以继续使用Qopengl并在PaintGl函数内部使用,使用QT3D库加载模型,然后为其分配模型视图矩阵,可以使用Qopengl函数进行操作,而不是Qtransform。
在QT3D的示例中,我尝试使用旧的OpenGL函数绘制对象,例如Glvertex,但它们没有在场景中呈现。
我想做这样的事情:
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();
我的意思是我想将投影和模型视图矩阵加载到OpenGL管道中,并使用ModelView绘制和操纵其他对象。
当然,我上面编写的代码不是正确的,因为BodyTransform是Qtransform,摄影机是QCAMERA。它们不是矩阵(qmatrix4x4类)。
编辑: 我做的是我存储了类似的投影和模型矩阵值:
projection=cameraEntity->projectionMatrix();
viewmatrix=cameraEntity->viewMatrix();
model=bodyTransform->matrix();
然后,我计算了ModelView矩阵(ViewMatrix和Model的产品)
,然后:
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
我将它们加载到OpenGL管道中,并试图绘制坐标系统,但没有'工作。
谢谢大家的帮助。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
回答您的问题有点困难,因为它充满了东西,但我还是会尝试回答:
也许关于您的问题“可以将QT3D和OpenGL结合起来吗?”?好吧,这绝对是可能的,但是您必须获取已在QT3D中加载的所有数据并将其传输到OpenGL,这将是很多工作。
因此,有几个建议/备注:
qsceneloader
在QT3D中加载模型。这将自动加载所有相应的材料等。QT3D在后台使用Assimp。当然,您也可以使用Assimp来为您的现有代码加载模型。但这是很多工作,我坚持QT3D。qtransform
?对我来说,似乎最大的一步是加载模型并展示它。添加简单的功能以使用转换矩阵旋转对象不应该很难。就像您甚至已经提到的一样,您可以从转换中获取矩阵并将其设置。表示您可以将其作为4x4矩阵操作,并将结果设置为转换。这是一个很好的第一个问题,您提出了很多示例和代码,也许只是尝试使它更简洁,下次很难回答这样的问题;)制作)
It's a bit difficult to answer your question because it's so packed with things but I'll try to answer anyways:
Maybe regarding your question "is it possible to combine Qt3D and OpenGL"? Well, it's definitely possible but you'd have to get all the data that has been loaded in Qt3D and transfer it to OpenGL, that's going to be a lot of work.
So a couple of suggestions/remarks:
QSceneLoader
to load models in Qt3D. This will automatically load all respective materials, etc. Qt3D uses Assimp in the background. You could of course also use Assimp for your existing code to load the model. But it's a lot of work, I'd stick to Qt3D.QTransform
? For me it seems the biggest step was to load the model and show it. Adding simple functionality to rotate the object using the transform's matrix shouldn't be hard. Like you even already mentioned, you can get the matrix from the transform and also set it. Means you can manipulate it as a 4x4 matrix and set the result on the transform.It's a good first question you asked with a lot of examples and code, maybe just try to make it a bit more concise next time it's a bit difficult to answer like this ;) (which I guess is apparent in the many points I wanted to make)