Qt 3D教程(二)初步顯示3D的內容
Qt3D教程(二)初步顯示3D的內容
前一篇很easy,全然就沒有牽涉到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。
此外。當button按下的時候,我們能夠通過改變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項目來獲取到本套教程的全部源碼。
Qt 3D教程(二)初步顯示3D的內容