在QT中實現3D繪制的方式:
1) 使用QT OpenGL模塊(QOpenGLWidget等)
2) 使用QT 3D C++類(QEntity等)
3) 使用QT 3D QML類(Entity等)
QT3D場景提供了一種快速設置3D場景的一種方式,用戶憑借着封裝好的實體可以快速的在頂層實體(畫布)當中增加各種各樣的實體,並且通過3DMax軟件構造的OBJ文件與QT3D實現信息交互可以的幫助用戶擺脫OpenGL的用代碼繪制圖形的繁瑣。
下面以QT Demo “Basic Shapes C++ Example”為例來講解下創建3D場景的一般步驟和用到的具體C++類:
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
int main(int argc, char **argv)
{ QApplication app(argc, argv); // 1、創建3D場景視圖窗口view Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow(); view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f))); // 2、創建放置3D場景視圖窗口的容器,場景view需要先放在一個容器中 QWidget *container = QWidget::createWindowContainer(view); QSize screenSize = view->screen()->size(); container->setMinimumSize(QSize(200, 100)); container->setMaximumSize(screenSize); // 3、創建一個主窗口Widget,進行適當布局操作 QWidget *widget = new QWidget; QHBoxLayout *hLayout = new QHBoxLayout(widget); QVBoxLayout *vLayout = new QVBoxLayout(); vLayout->setAlignment(Qt::AlignTop); // 4、將3D場景容器加入布局當中 hLayout->addWidget(container, 1); hLayout->addLayout(vLayout); // 給應用程序主窗口設置一個標題 widget->setWindowTitle(QStringLiteral("Basic shapes")); // 5、創建根實體(Root Entity)對象,即所謂的“畫布”,並將其設置到3D場景視圖中去 Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity(); view->setRootEntity(rootEntity); // 6、在顯示3D圖形的過程當中,攝像機是必不可少的,只有攝像機擺放的合適人眼才能看到3D建模的樣子 Qt3DRender::QCamera *cameraEntity = view->camera(); cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f / 9.0f, 0.1f, 1000.0f); cameraEntity->setPosition(QVector3D(0, 0, 20.0f)); cameraEntity->setUpVector(QVector3D(0, 1, 0)); cameraEntity->setViewCenter(QVector3D(0, 0, 0)); // 7、在“畫布”中加入子實體“光照light” Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity); // 定義一種光源對象,這里定義的是“點光”,此外還有“定向光”以及“聚集光”可選 Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity); light->setColor("white"); light->setIntensity(1); lightEntity->addComponent(light); // 定義光照實體的變換(設置光照顯示位置等) Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity); lightTransform->setTranslation(cameraEntity->position()); lightEntity->addComponent(lightTransform); // 8、攝像機控制配置(這里配置以第一人稱視角控制場景攝影機) Qt3DExtras::QFirstPersonCameraController *camController = new Qt3DExtras::QFirstPersonCameraController(rootEntity); camController->setCamera(cameraEntity); // 9、現在就可以繪制各種3D場景的實體圖形了 // 在這里有如下的幾種方法可以選擇, // 首先就是用OpenGL畫出實體(適合OpenGL的老手,不適於新手), // 然后就是用Qt自帶的基本實體(容易構造,簡單易學), // 最后就是用例如3DMax導出的OBJ文件實現與QT之間的信息交互(容易上手,成為越來越多人的首選)。 // 本例采用的就是Qt基本實體去創建(以球體為例) // 在Qt中任何實體加入到三維模型中最為簡單的配置方法分為以下幾步: // 首先再根實體中創建實體[設置實體名稱可選], Qt3DCore::QEntity *sphereEntity = new Qt3DCore::QEntity(rootEntity); m_ sphereEntity ->setObjectName("Sphere"); // 然后配置渲染(輪廓形狀Mesh、材質Materials、變換Transform)方面與實體相關的元素, // Mesh(實體輪廓形狀,由一個個網格組成,網格越多顯示效果越好) Qt3DExtras::QSphereMesh *sphereMesh = new Qt3DExtras::QSphereMesh(); sphereMesh->setRings(20); sphereMesh->setSlices(20); sphereMesh->setRadius(2); // 僅僅有Mesh,一個實體只會顯示一片黑,Material提供了實體表面的呈現
// Material(表面貼圖等材質顯示,有多種不同類型的材質可選) Qt3DExtras::QPhongMaterial *sphereMaterial = new Qt3DExtras::QPhongMaterial(); sphereMaterial->setDiffuse(QColor(QRgb(0xff0000))); // Transform(縮放大小、旋轉以及在三維模型中的位置等) // 實現實體旋轉功能說明: // void setRotation(const QQuaternion &rotation) 繞點旋轉 // void setRotationX(float rotationX) 繞X軸旋轉 // void setRotationY(float rotationY) 繞Y軸旋轉 // void setRotationZ(float rotationZ) 繞Z軸旋轉 Qt3DCore::QTransform *sphereTransform = new Qt3DCore::QTransform(); sphereTransform->setScale(1.3f); sphereTransform->setTranslation(QVector3D(0.0f, .0.f, 0.0f)); // 可選:給實體加入鼠標拾取功能 Qt3DRender::QObjectPicker *picker = new Qt3DRender::QObjectPicker(sphereEntity); picker->setHoverEnabled(true); picker->setEnabled(true); connect(picker, &Qt3DRender::QObjectPicker::clicked, this, &SceneModifier::mouseClicked); connect(picker, &Qt3DRender::QObjectPicker::pressed, this, &SceneModifier::mousePressed); connect(picker, &Qt3DRender::QObjectPicker::released, this, &SceneModifier::mouseReleased); connect(picker, &Qt3DRender::QObjectPicker::entered, this, &SceneModifier::mouseEntered); connect(picker, &Qt3DRender::QObjectPicker::exited, this, &SceneModifier::mouseExited); // 最后將各渲染組件加入到實體list中去。 sphereEntity->addComponent(sphereMesh); sphereEntity->addComponent(sphereMaterial); sphereEntity->addComponent(sphereTransform); sphereEntity->addComponent(picker); // 10、設置實體可顯示 sphereEntity ->setEnabled(true); // 顯示主窗口 widget->show(); widget->resize(1200, 800); return app.exec(); } |
附截圖一張