一、开篇
当在软件界面中加入3D元素,能够使软件的设计用途和效果更加具体,用户的视觉体验效果也较好,例如下图所示的界面效果:
本文以上图为效果原图为目标,分享Qt 3D开发的步骤和过程总结。
二、实现过程总结
(2-1)效果
(2-2)核心思路
1、使用3D建模软件进行人物模型制作,并将模型导出为xxx.obj的文件格式,如下图所示:
2、在QtCreator工程中,创建3D相关的类对象,核心代码如下:
#include "meshloader.h"
MeshObjWidget::MeshObjWidget(QWidget *parent)
: QWidget(parent)
{
initializate3DView();
}
MeshObjWidget::~MeshObjWidget()
{
SAFE_DELETE(objs.m_windowOn3D)
SAFE_DELETE(objs.m_rootEntity)
SAFE_DELETE(objs.m_material)
SAFE_DELETE(objs.m_trans)
SAFE_DELETE(objs.m_input)
}
void MeshObjWidget::initializate(const QString & mesh_url)
{
QWidget *container = QWidget::createWindowContainer(objs.m_windowOn3D);
objs.m_windowOn3D->defaultFrameGraph()->setClearColor(QColor(0,191,255));
container->setMinimumSize(QSize(200, 100));
QHBoxLayout *hLayout = new QHBoxLayout(this);
QVBoxLayout *vLayout = new QVBoxLayout();
vLayout->setAlignment(Qt::AlignTop);
hLayout->addWidget(container, 1);
hLayout->addLayout(vLayout);
objs.m_windowOn3D->registerAspect(objs.m_input);
// 设置观测视角
objs.m_windowOn3D->camera()->lens()->setPerspectiveProjection(45.0f, 16.0f / 9.0f, 0.1f, 1000.0f);
// 设置相机位置
objs.m_windowOn3D->camera()->setPosition(QVector3D(0, 0, 20.0f));
objs.m_windowOn3D->camera()->setUpVector(QVector3D(0, 1, 0));
// 设置视角中心
objs.m_windowOn3D->camera()->setViewCenter(QVector3D(0, 0, 0));
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(objs.m_rootEntity);
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
light->setColor(QColor(119,136,153));
light->setIntensity(1);
lightEntity->addComponent(light);
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
lightTransform->setTranslation(objs.m_windowOn3D->camera()->position());
lightEntity->addComponent(lightTransform);
objs.m_trans->setScale(0.04f);
objs.m_trans->setTranslation(QVector3D(0.0f, 0.0f, 19.45f));
//创建Mesh
Qt3DRender::QMesh *mesh = new Qt3DRender::QMesh();
//设置Mesh路径
mesh->setSource(QUrl(mesh_url));
Qt3DExtras::QPhongMaterial *material = new Qt3DExtras::QPhongMaterial(objs.m_rootEntity);
objs.m_rootEntity->addComponent(mesh);
objs.m_rootEntity->addComponent(material);
objs.m_rootEntity->addComponent(objs.m_trans);
Qt3DExtras::QFirstPersonCameraController *camController = new Qt3DExtras::QFirstPersonCameraController(objs.m_rootEntity);
camController->setCamera(objs.m_windowOn3D->camera());
objs.m_windowOn3D->setRootEntity(objs.m_rootEntity);
this->setStyleSheet("background:#00BFFF;");
}
void MeshObjWidget::initializate3DView()
{
objs.m_windowOn3D = new Qt3DWindow();
objs.m_rootEntity = new QtEntity();
objs.m_material = new QtMaterial();
objs.m_trans = new QtTransform();
objs.m_input = new QtInputAspect();
}
3、将导出的xxx.obj文件加载进软件中:
QString curDir = QGuiApplication::applicationDirPath();
objWidget.initializate(QString("file:%1").arg(curDir)+"/mesh/hbm.obj");
这一步需要注意:
(1)xxx.obj文件的路径可以是文件的绝对路径
(2)不要把xxx.obj文件放入Qt的资源系统中,因为3D文件往往很大,当Qt在进行编译构建时,如果将3D文件放入资源系统中,编译出的中间文件较大且生成的exe文件也较大;如果达到几十兆的3D文件,可能会直接编译崩溃退出,无法完成编译构建!!!
(3)路径前面的file
字符串是必须的,可参考QUrl
类。
搜索关注【嵌入式小生】wx公众号,回复【1071】即可获取本文源码工程,也可获取更多精彩内容。