您的位置:首页 > 编程语言 > Qt开发

Qt 3D教程(二)初步显示3D的内容

2015-07-29 17:30 405 查看

Qt3D教程(二)初步显示3D的内容

       前一篇非常简单,完全就没有牵涉到3D的内容,它只是我们搭建3D应用的基本框架而已,而这一篇,我们将要利用它来初步地显示3D的内容了!本次目的是将程序中间的内容替换成3D的视图,而这一切也不过十几行代码。要不我们来试一试吧!

蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/47131099。欢迎同行前来探讨。

       首先我们需要对我们的MainWindow.cpp文件进行修改,在此基础上添加一些内容:

#include <QQmlAspectEngine>
#include <QRenderAspect>
#include <QInputAspect>
#include <QQmlContext>
#include <QWindow>

#include "MainWindow.h"
#include "ui_MainWindow.h"

class View3D: public QWindow
{
public:
View3D( QScreen* targetScreen = Q_NULLPTR ): QWindow( targetScreen )
{
setSurfaceType( QSurface::OpenGLSurface );

QSurfaceFormat format;
format.setSamples( 4 );
setFormat( format );

create( );
}
};

Settings::Settings( QObject* parent ): QObject( parent )
{
m_showModel = true;
}

void Settings::setShowModel( bool showModel )
{
if ( m_showModel == showModel ) return;
m_showModel = showModel;
emit showModelChanged( );
}

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

using namespace Qt3D;
using namespace Qt3D::Quick;
// 创建一个3D的视图
// 1
View3D* view3D = new View3D;

// 2
QQmlAspectEngine* engine = new QQmlAspectEngine( this );
engine->aspectEngine( )->registerAspect( new QRenderAspect );
engine->aspectEngine( )->registerAspect( new QInputAspect );

// 3
QVariantMap data;
data.insert( QStringLiteral( "surface" ),
QVariant::fromValue( static_cast<QSurface*>( view3D ) ) );
data.insert( QStringLiteral( "eventSource" ),
QVariant::fromValue( view3D ) );
engine->aspectEngine( )->setData( data );

// 4
engine->qmlEngine( )->rootContext( )->setContextProperty( "_settings", &m_settings );

// 5
engine->aspectEngine( )->initialize( );
engine->setSource( QUrl( "qrc:/qml/main.qml" ) );

QVBoxLayout* l = qobject_cast<QVBoxLayout*>( ui->centralwidget->layout( ) );
l->insertWidget( 0, QWidget::createWindowContainer( view3D ) );
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::on_showModelButton_clicked()
{
bool show = m_settings.showModel( );
show = !show;
ui->showModelButton->setText( show? "隐藏模型": "显示模型" );
m_settings.setShowModel( show );
}


       这里我们使用了QWindow来替代我们曾经使用的QWidget,并且使用了QWidget:: createWindowContainer()函数来将QWindow的内容嵌入QWidget框架中;紧接着我们在构造函数中创建了QQmlAspectEngine类实例,并且注册了QRenderAspect和QInputAspect;随后我们使用一个QVariantMap数据结构,将surface以及eventSource以键值对的形式存储起来供QAspectEngine使用;接着作为可选的内容,我们为了让C++这一部分控制QML,我们定义了一个Settings类,并且将m_settings注入QML环境作为上下文变量;最后我们使用initialize()函数初始化QAspectEngine,并且指定了我们需要展示的场景数据:main.qml。

       此外,当按钮按下的时候,我们可以通过改变m_settings的属性从而控制我们是否想要显示模型。

       同时我们还必须在main.qml中作一些设置:


import Qt3D 2.0
import Qt3D.Renderer 2.0

Entity
{
id: root

Camera
{
id: camera
position: Qt.vector3d( 0.0, 20.0, 100.0 )
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: 16.0 / 9.0
nearPlane : 0.1
farPlane : 1000.0
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
viewCenter: Qt.vector3d( 0.0, 20.0, 0.0 )
}

components: FrameGraph
{
ForwardRenderer
{
clearColor: Qt.rgba( 0.2, 0, 0, 1 )
camera: camera
}
}

Entity
{
Mesh
{
id: chestMesh
source: "qrc:/assets/Chest.obj"
enabled: _settings.showModel
}

components: [ chestMesh ]
}

Configuration
{
controlledCamera: camera
}
}


       如上面所示,我们在名为root的Entity中定义了一个摄像机、一个实体,还有一些必要的设置。同时我们通过绑定_settings.showModel来控制Mesh的显示或者隐藏。



本次教程的代码均在我的github中,感兴趣的同行们可以通过git clone或者是直接下载我的git项目来获取到本套教程的所有源代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  3d qt