Coin3D三维可视化教程1
上次介绍了Coin3D的安装和在VS 2019 +QT下的配置,后面讲逐步学习这个库的使用,采用的主要材料的The Inventor Mentor中文版。书中的代码时在Mac平台的开发,这里采用的用的是Windows,SoXt是Coin3D在Mac平台上的界面绑定库,SoQt是与Qt的绑定库,SoWin是用MFC的绑定库。
上次安装的测试中,使用了SoQtExaminerViewer这个常用的交互查看器,这个查看器封装了很多东西,这里讲从最基本的学起,学习画布、灯光、颜色、交互、动作响应等对象的创建和初步使用。
#include <QtWidgets/QApplication>
#include <Inventor/Qt/SoQt.h>
#include <Inventor/Qt/SoQtRenderArea.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoCone.h>
int main(int argc, char* argv[])
{
//Initialize Inventor. This returns a main window to use
QWidget* myWindow = SoQt::init(argc, argv, argv[0]);
if (myWindow == NULL)exit(1);
//Make a scene containing a red cone
SoSeparator* root = new SoSeparator;
SoPerspectiveCamera* myCamera = new SoPerspectiveCamera;
SoMaterial* myMaterial = new SoMaterial;
root->ref();
root->addChild(myCamera);
root->addChild(new SoDirectionalLight);
myMaterial->diffuseColor.setValue(1.0, 0.0, 0.0);
root->addChild(myMaterial);
root->addChild(new SoCone);
//Create a renderArea in which to see our scene graph
//The render area will appear within the main window
SoQtRenderArea* myRenderArea = new SoQtRenderArea(myWindow);
//Make myCamera see everything
myCamera->viewAll(root, myRenderArea->getViewportRegion());
//Put out scene in myRenderArea, change the title
myRenderArea->setSceneGraph(root);
myRenderArea->setTitle("Hello Cone");
myRenderArea->show();
SoQt::show(myWindow); //Display main window
SoQt::mainLoop(); //Main Inventor event loop
}
运行结果如下:
渲染结果是个固定的图像,不可以旋转和交互。
这个最简单的例子展示了使用Coin3D进行三维渲染要做的主要事情;
(1)通过QoQt::init初始化函数创建QWidget部件,作为显示窗口
(2)设置场景SoSeparator节点,并添加相机、材质、灯光,设置材质的颜色
(3)创建要显示的对象,并添加到SoSeparator节点
(4)设置画布,即渲染区域SoQtRenderArea,把场景添加到画布,并设置相机看到的区域,
(5)通过SoQt::show显示窗口,并通过SoQt::mainLoop 进入消息循环
下面这个例子展示如何实现旋转。一个引擎节点与一个SoRotationXYZ节点的角度数据域相关联。当实时时钟(real-time clock)发生变化时,引擎会同时修改在rotationXYZ节点中的角度数据。这样将导致圆锥不断地循环旋转。在每次修改后,场景会自动地被渲染区重新渲染。连续的旋转就可以达到我们想要的旋转圆锥的效果。需要说明的是,SoRotationXYZ需要设置在要渲染的物体之前。
#include "Coin3Dtest1.h"
#include <QtWidgets/QApplication>
#include <Inventor/Qt/SoQt.h>
#include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
#include <Inventor/Qt/SoQtRenderArea.h>
#include <Inventor/engines/SoElapsedTime.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoRotationXYZ.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoCone.h>
int main(int argc, char* argv[])
{
//Initialize Inventor. This returns a main window to use
QWidget* myWindow = SoQt::init(argc, argv, argv[0]);
if (myWindow == NULL)exit(1);
//Make a scene containing a red cone
SoSeparator* root = new SoSeparator;
SoPerspectiveCamera* myCamera = new SoPerspectiveCamera;
SoMaterial* myMaterial = new SoMaterial;
root->ref();
root->addChild(myCamera);
root->addChild(new SoDirectionalLight);
myMaterial->diffuseColor.setValue(1.0, 0.0, 0.0);
//This transformation is modified to rotate the cone
//This action should be set before the object to see
SoRotationXYZ* myRotXYZ = new SoRotationXYZ;
root->addChild(myRotXYZ);
root->addChild(myMaterial);
root->addChild(new SoCone);
//An engine rotates the object, The output of myCounter
//is the time in seconds since the program started
//Connect this output to the angle field of myRotXYZ
myRotXYZ->axis = SoRotationXYZ::Y; //rotate about X axis
SoElapsedTime* myCounter = new SoElapsedTime;
myRotXYZ->angle.connectFrom(&myCounter->timeOut);
//Create a renderArea in which to see our scene graph
//The render area will appear within the main window
SoQtRenderArea* myRenderArea = new SoQtRenderArea(myWindow);
//Make myCamera see everything
myCamera->viewAll(root, myRenderArea->getViewportRegion());
//Put out scene in myRenderArea, change the title
myRenderArea->setSceneGraph(root);
myRenderArea->setTitle("Engine Spin");
myRenderArea->show();
SoQt::show(myWindow); //Display main window
SoQt::mainLoop(); //Main Inventor event loop
}
渲染效果如下: