zoukankan      html  css  js  c++  java
  • Qt 使用irrlicht(鬼火)3D引擎

    项目中需要加载简单的3D场景。资深老前辈推荐使用开源小巧的引擎irrlicht。

    关于irrlicht,来之百度百科

    Irrlicht引擎是一个用C++书写的高性能实时的3D引擎,可以应用于C++程序或者.NET语言中。通过使用Direct3D(Windows平台),OpenGL 1.2或它自己的软件着色程序,可以实现该引擎的完全跨平台。尽管是开源的,该Irrlicht库提供了可以在商业级的3D引擎上具有的艺术特性,例如动态的阴影,粒子系统,角色动画,室内和室外技术以及碰撞检测等。

     

    具体信息 百度百科

    如何使用,

    首先使用Qt建立工程,略过。

    在Qt pro工程文件总中加入引擎头文件路径,和库文件路径。

     

    #包含鬼火3D引擎需要的头文件路劲
    INCLUDEPATH +=D:irrlicht-1.8.3include
    #连接开发需要用到的库文件
    LIBS +=D:irrlicht-1.8.3libWin32-gcclibIrrlicht.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


  • 相关阅读:
    九.Protobuf3特殊类型
    八.Protobuf3更新消息类型(添加新的字段)
    七.Protobuf3 嵌套类型
    六.Protobuf3引入其他.proto文件
    五.Protobuf3 枚举
    四.Protobuf3 缺省值
    VC 在调用main函数之前的操作
    Windows下的代码注入
    C 堆内存管理
    VC++ 崩溃处理以及打印调用堆栈
  • 原文地址:https://www.cnblogs.com/DreamDog/p/9160132.html
Copyright © 2011-2022 走看看