• 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项目来获取到本套教程的全部源码。

  • 相关阅读:
    怎么在sublime里面显示编码格式
    鸟哥的Linux私房菜——第十七章:Linux 账号与身份管理
    反复
    鸟哥的Linux私房菜——第十六章:学习Shell Scripts
    鸟哥的Linux私房菜——第十五章:正规表示法
    鸟哥的Linux私房菜——第十四章:Bash Shell
    鸟哥的Linux私房菜——第十三章:Vim编译器
    Expression Blend实例中文教程(10)
    Expression Blend实例中文教程(9)
    Expression Blend实例中文教程(8)
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6915444.html
Copyright © 2020-2023  润新知