如何在标准GUI应用程序中使用Qt3D进行渲染?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在标准GUI应用程序中使用Qt3D进行渲染?相关的知识,希望对你有一定的参考价值。
我喜欢使用Qt3D,但我看到的所有示例都是全窗口应用程序。我从例子中无法理解的是如何将qt3d渲染窗口添加到常规qt gui应用程序中。
基本上我想要的是我的Qt5 Gui应用程序的一个小渲染小部件。
我查看了Qtgl小部件,但我真的想使用Qt3D的场景管理功能。
如何在qt Gui窗口内渲染为子窗口?
这可能吗?
更新
所以我把它添加到我的MainWindow.cpp它基于这个http://blog.qt.digia.com/blog/2013/02/19/introducing-qwidgetcreatewindowcontainer/松散
LoadModelView *view = new LoadModelView(); //Crashes on this. Will not compile with
// LoadModelView(this)
QWidget *container = QWidget::createWindowContainer(view);
container->setFocusPolicy(Qt::TabFocus);
ui->gridLayout->addWidget(container);
这似乎是对的。
我的load_model.cpp开头是这样的:
#include "qglmaterialcollection.h"
#include "qglmaterial.h"
#include "qglscenenode.h"
#include "qgllightmodel.h"
#include "qglabstractscene.h"
#include <QtGui/qmatrix4x4.h>
#include <QPropertyAnimation>
#include <QtCore/qmath.h>
#define DEGREE_TO_RAD (3.1415926/180.0)
LoadModelView::LoadModelView(QWindow *parent)
: QGLView(parent)
, m_pSTLScene(0)
{
loadModels();
camera()->setCenter(QVector3D(0, 0, 0));
camera()->setEye(QVector3D(0, 4, 10));
}
LoadModelView::~LoadModelView()
{
delete m_pSTLScene;
}
void LoadModelView::paintGL(QGLPainter *painter)
{
QMatrix4x4 stlWorld;
stlWorld.setToIdentity();
stlWorld.scale(0.1);
stlWorld.translate(QVector3D(2.0,0.0,0.0));
painter->setStandardEffect(QGL::LitMaterial);
painter->setFaceColor(QGL::AllFaces,QColor(170,202,0));
painter->modelViewMatrix() = camera()->modelViewMatrix() * stlWorld;
m_pSTLScene->mainNode()->draw(painter);
}
void FixNodesRecursive(int matIndex, QGLSceneNode* pNode)
{
if (pNode) {
pNode->setMaterialIndex(matIndex);
// pNode->setEffect(QGL::FlatReplaceTexture2D);
foreach (QGLSceneNode* pCh, pNode->children()) {
FixNodesRecursive(matIndex, pCh);
}
}
}
void LoadModelView::loadModels()
{
{
m_pSTLScene = QGLAbstractScene::loadScene(QLatin1String(":/models/Sheep.stl"), QString(),"CorrectNormals CorrectAcute");
Q_ASSERT(m_pSTLScene!=0);
QGLMaterial *mat = new QGLMaterial;
mat->setAmbientColor(QColor(170,202,0));
mat->setDiffuseColor(QColor(170,202,0));
mat->setShininess(128);
QGLSceneNode* pSTLSceneRoot = m_pSTLScene->mainNode();
int matIndex = pSTLSceneRoot->palette()->addMaterial(mat);
pSTLSceneRoot->setMaterialIndex(matIndex);
pSTLSceneRoot->setEffect(QGL::FlatReplaceTexture2D);
FixNodesRecursive(matIndex,pSTLSceneRoot);
}
}
它崩溃:该应用程序已请求运行时以不寻常的方式终止它。
并在qt应用程序输出中:传递给C运行时函数的无效参数。
编辑添加了相关课程的其余部分
我注意到在我调整http://doc.qt.digia.com/qt-quick3d-snapshot/qt3d-penguin-main-cpp.html的例子中,窗口初始化为:
LoadModelView view;
不过,说
LoadModelView *view = new LoadModelView(this)
崩溃
您可以继承QGLView类,它扩展了QGLWidget并支持3D查看:
class GLView : public QGLView
{
Q_OBJECT
public:
GLView(QWidget *parent = 0);
~GLView();
protected:
void initializeGL(QGLPainter *painter);
void paintGL(QGLPainter *painter);
private:
QGLAbstractScene *m_scene;
QGLSceneNode *m_rootNode;
};
GLView::GLView(QWidget *parent)
: QGLView(parent)
, m_scene(0)
, m_rootNode(0)
{
// Viewing Volume
camera()->setFieldOfView(25);
camera()->setNearPlane(1);
camera()->setFarPlane(1000);
// Position of the camera
camera()->setEye(QVector3D(0, 3, 4));
// Direction that the camera is pointing
camera()->setCenter(QVector3D(0, 3, 0));
}
GLView::~GLView()
{
delete m_scene;
}
void GLView::initializeGL(QGLPainter *painter)
{
// Background color
painter->setClearColor(QColor(70, 70, 70));
// Load the 3d model from the file
m_scene = QGLAbstractScene::loadScene("models/model1/simplemodel.obj");
m_rootNode = m_scene->mainNode();
}
void GLView::paintGL(QGLPainter *painter)
{
m_rootNode->draw(painter);
}
Qt 5.1引入了函数QWidget :: createWindowContainer()。一个为现有QWindow创建QWidget包装器的函数,允许它存在于基于QWidget的应用程序中。您可以使用QWidget :: createWindowContainer在QWidget中创建QWindow。这允许将QWindow子类放在Widget-Layouts中。这样您就可以将QGLView嵌入到窗口小部件中。
这就是我在Qt5.10上做到的。此示例显示具有长方体的场景。 Scene
你可以使用像按钮左右...使用此添加QT += 3dextras
到您的项目文件。
szene.h
#ifndef SCENE_H
#define SCENE_H
#include <QObject>
#include <QWidget>
class Scene
: public QWidget
{
Q_OBJECT
private:
QWidget *container;
public:
explicit Scene(QWidget *parent = nullptr);
protected:
// reimplementation needed to handle resize events
// http://doc.qt.io/qt-5/qwidget.html#resizeEvent
void
resizeEvent ( QResizeEvent * event );
public slots:
void
resizeView(QSize size);
};
#endif // SCENE_H
scene.cpp
#include "scene.h"
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QForwardRenderer>
#include <QQuaternion>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QCamera>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DExtras/QPhongMaterial>
Scene::Scene(QWidget *parent)
: QWidget(parent)
{
auto view = new Qt3DExtras::Qt3DWindow();
// create a container for Qt3DWindow
container = createWindowContainer(view,this);
// background color
view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x575757)));
// Root entity
auto rootEntity = new Qt3DCore::QEntity();
// Camera
auto camera = new Camera(rootEntity,view);
auto cameraEntity = view->camera();
cameraEntity->setPosition(QVector3D(0, 0, 50.0f));
cameraEntity->setUpVector(QVector3D(0, 1, 0));
cameraEntity->setViewCenter(QVector3D(0, 0, 0));
// Cuboid
auto cuboidMesh = new Qt3DExtras::QCuboidMesh();
// CuboidMesh Transform
auto cuboidTransform = new Qt3DCore::QTransform();
cuboidTransform->setScale(10.0f);
cuboidTransform->setTranslation(QVector3D(0.0f, 0.0f, 0.0f));
cuboidTransform->setRotation(QQuaternion(1,1.5,1,0).normalized());
auto cuboidMaterial = new Qt3DExtras::QPhongMaterial();
cuboidMaterial->setDiffuse(QColor(QRgb(0x005FFF)));
// assamble entity
auto cuboidEntity = new Qt3DCore::QEntity(rootEntity);
cuboidEntity->addComponent(cuboidMesh);
cuboidEntity->addComponent(cuboidMaterial);
cuboidEntity->addComponent(cuboidTransform);
// Set root object of the scene
view->setRootEntity(rootEntity);
}
void
Scene::resizeView(QSize size)
{
container->resize(size);
}
void
Scene::resizeEvent ( QResizeEvent * /*event*/ )
{
resizeView(this->size());
}
以上是关于如何在标准GUI应用程序中使用Qt3D进行渲染?的主要内容,如果未能解决你的问题,请参考以下文章