项目中需要加载简单的3D场景。资深老前辈推荐使用开源小巧的引擎irrlicht。
关于irrlicht,来之百度百科
Irrlicht引擎是一个用C++书写的高性能实时的3D引擎,可以应用于C++程序或者.NET语言中。通过使用Direct3D(Windows平台),OpenGL 1.2或它自己的软件着色程序,可以实现该引擎的完全跨平台。尽管是开源的,该Irrlicht库提供了可以在商业级的3D引擎上具有的艺术特性,例如动态的阴影,粒子系统,角色动画,室内和室外技术以及碰撞检测等。
具体信息 百度百科。
如何使用,
首先使用Qt建立工程,略过。
在Qt pro工程文件总中加入引擎头文件路径,和库文件路径。
#包含鬼火3D引擎需要的头文件路劲 INCLUDEPATH +=D:\irrlicht-1.8.3\include #连接开发需要用到的库文件 LIBS +=D:\irrlicht-1.8.3\lib\Win32-gcc\libIrrlicht.a
剩下的就是一般的核心代码部分了,
包含头文件部分
#include <QObject> #include <QWidget> #include <QApplication> #include <irrlicht.h>
using namespace irr; using namespace core; using namespace scene; using namespace video; using namespace io; using namespace gui;
引擎初始化
void Irr_Device::init_Dev() { if(m_Device != NULL) { return; } SIrrlichtCreationParameters params; params.AntiAlias = 0; params.Bits = 32; params.DeviceType = EIDT_BEST; params.Doublebuffer = true; params.DriverType = EDT_OPENGL; params.EventReceiver = 0; params.Fullscreen = false; params.HighPrecisionFPU = false; params.IgnoreInput = false; params.LoggingLevel = ELL_INFORMATION; params.Stencilbuffer = true; params.Stereobuffer = false; params.Vsync = false; // Specify which window/widget to render to // 指定哪个窗口小部件呈现 params.WindowId = reinterpret_cast<void*>(winId()); params.WindowSize.Width = width(); params.WindowSize.Height = height(); params.WithAlphaChannel = true; params.ZBufferBits = 16; // Create the Irrlicht Device with the previously specified parameters // 创建Irrlicht设备的使用与前面指定的参数 m_Device = createDeviceEx(params); /* 获取视频设备,场景管理器和用户图形环境的指针并存储起来。 */ video_Driver = m_Device->getVideoDriver(); scene_Msnsger = m_Device->getSceneManager(); guienv = m_Device->getGUIEnvironment(); //smgr->loadScene qDebug()<< scene_Msnsger->loadScene("123.irr"); /* Now we'll create a camera, and give it a collision response animator that's built from the mesh nodes in the scene we just loaded. */ /* 现在我们将创建一个相机,给它一个碰撞响应动画师 由网格节点的现场加载。 */ m_Camera = scene_Msnsger->addCameraSceneNodeFPS(0,50.f,0.1f); /* Now we will find all the nodes in the scene and create triangle selectors for all suitable nodes. Typically, you would want to make a more informed decision about which nodes to performs collision checks on; you could capture that information in the node name or Id. */ /* 现在我们将在现场找到的所有节点并创建三角形 选择合适的节点。通常,您会想要 更明智的决定哪些节点执行碰撞检查 ;你可以捕捉信息的节点名称或Id。 */ scene::IMetaTriangleSelector* meta = scene_Msnsger->createMetaTriangleSelector(); // core::array<scene::ISceneNode*> nodes; // scene_Msnsger->getSceneNodeFromType(scene::ESNT_ANY, nodes); core::array<scene::ISceneNode *> nodes; scene_Msnsger->getSceneNodesFromType(scene::ESNT_ANY, nodes); // Find all nodes for(u32 i =0;i<nodes.size();++i) { scene::ISceneNode* node = nodes[i]; scene::ITriangleSelector* selector =0; switch (node->getType()) { case scene::ESNT_CUBE: case scene::ESNT_ANIMATED_MESH: // Because the selector won't animate with the mesh, // and is only being used for camera collision, we'll just use an approximate // bounding box instead of ((scene::IAnimatedMeshSceneNode*)node)->getMesh(0) // 因为选择器不会与网格动画, // 和仅用于相机碰撞,我们只使用一个近似 // 边界框代替((场景::IAnimatedMeshSceneNode *)节点)- > getMesh(0) selector = scene_Msnsger->createTriangleSelectorFromBoundingBox(node); break; case scene::ESNT_MESH: case scene::ESNT_SPHERE: selector = scene_Msnsger->createTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(),node); break; case scene::ESNT_TERRAIN: selector = scene_Msnsger->createTerrainTriangleSelector((scene::ITerrainSceneNode*)node); break; case scene::ESNT_OCTREE: selector = scene_Msnsger->createOctreeTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(),node); break; default: break; } if(selector) { meta->addTriangleSelector(selector); selector->drop(); } } /* Now that the mesh scene nodes have had triangle selectors created and added to the meta selector, create a collision response animator from that meta selector. */ /* 现在有三角形网格场景节点选择器创建和添加 元选择器,创建一个元的碰撞响应动画选择器。 */ scene::ISceneNodeAnimator* anim = scene_Msnsger->createCollisionResponseAnimator( meta,m_Camera,core::vector3df(5,5,5),core::vector3df(0,0,0)); meta->drop(); m_Camera->addAnimator(anim); anim->drop(); m_Camera->setPosition(core::vector3df(0.f,20.f,0.f)); scene::ISceneNode*cube = scene_Msnsger->getSceneNodeFromType(scene::ESNT_CUBE); if(cube) { m_Camera->setTarget(cube->getAbsolutePosition()); } m_Device->getCursorControl()->setVisible(false); connect(this,SIGNAL(sigUpdateIrrlicht(irr::IrrlichtDevice*)), this,SLOT(slotUpdateIrrlicht(irr::IrrlichtDevice*))); startTimer(0); }保证实时刷新界面部分
void Irr_Device::slotUpdateIrrlicht(IrrlichtDevice *device) { if(device != 0) { if (isVisible() && isEnabled()/*&&device->isWindowActive()*/) { device->getTimer()->tick();//在没有用IrrlichtDevice::run()的情况下,必须加上这句,否则键盘不响应 SColor color (255,100,100,140); device->getVideoDriver()->beginScene(true, true, color); device->getSceneManager()->drawAll(); device->getVideoDriver()->endScene(); } else { device->yield(); } } } void Irr_Device::timerEvent(QTimerEvent *event) { if (m_Device != NULL) { emit sigUpdateIrrlicht(m_Device); } event->accept(); }
软件运行截图如图
Demo 链接:http://download.csdn.net/detail/z609932088/9504584