zoukankan      html  css  js  c++  java
  • 开源3D游戏引擎Irrlicht简介

    Irrlicht简介

    Irrlicht在国内也被叫做“鬼火”引擎,是一款用C++编写的开放源代码的高性能游戏引擎。而且是跨平台的,具有很好的移植性,Irrlicht支持OpenGl、Direcx3D渲染,引擎本身也实现了一套自己的渲染系统。在商业引擎中能够找到的艺术特性,Irrlicht基本都支持。目前有很多项目中都使用到它,Irrlicht社区也比较活跃,可以在互联网上找到不少Irrlicht增强工具,例如irrEdit、irrKlang等。在众多开源游戏引擎中,Irrlicht也是比较受笔者青睐的一款。

    Irrlicht官方网站:http://irrlicht.sourceforge.net/

    Irrlicht下载与使用

    Irrlicht目前最新稳定版本为1.8.1,项目发布在sourceforge平台上,用户可以通过sourceforge网站首页面搜索功能找到Irrlicht项目下载地址,或者从Irrlicht官网获取下载链接。

    下载地址:http://irrlicht.sourceforge.net/downloads/

    1.目录结构

    解压后目录结构如下:

    Irrlicht引擎目录结构

    bin:不同平台编译Irrlicht生成的可执行文件和动态库文件放在该目录中。
    doc : 该目录中为Irrlicht API文档。
    examples : Irrlicht官方提供的案例程序存放在该目录中。
    include : 存放引擎所有头文件。
    lib : 该目录存放Irrlicht引擎编译过后生成的静态库。
    media : 官方案例所需资源文件存放在此目录中。
    source : 存放引擎源码。
    tools : 该目录下为Irrlicht引擎相关工具。如irrEdit、GUIEditor等。

    2.官方案例

    Irrlicht使用起来是非常方便的,这也是笔者比较喜欢它的原因之一。为了方便用户学习和使用引擎,Irrlicht官方提供了大量的例子程序,而且都比较具有代表性。

    打开examples目录,Irrlicht已经为目前主流开发工具Windows平台下Visual Studio、MacOS下的Xcode以及Linux平台下的GNU MAKE做好了项目配置。

    这里写图片描述

    笔者是在Windows操作系统下使用VS2012进行演示,双击BuildAllExamples_vc11.sln打开解决方案,无需做任何配置即可编译运行程序。

    这里写图片描述

    编译运行Collision案例程序:

    这里写图片描述

    看起来效果是不是很炫呢?Irrlicht为我们做了大量的封装,即便看似如此复杂的程序,实际代码不超过200行。

    #include <irrlicht.h>
    #include "driverChoice.h"
    
    using namespace irr;
    
    #ifdef _MSC_VER
    #pragma comment(lib, "Irrlicht.lib")
    #endif
    enum
    {   
        ID_IsNotPickable = 0,
        IDFlag_IsPickable = 1 << 0,
        IDFlag_IsHighlightable = 1 << 1
    };
    int main()
    {
        video::E_DRIVER_TYPE driverType=video::EDT_OPENGL;//driverChoiceConsole();
        if (driverType==video::EDT_COUNT)
            return 1;
    
        IrrlichtDevice *device =
            createDevice(driverType, core::dimension2d<u32>(1024, 768), 16, false);
        if (device == 0)
            return 1; // could not create selected driver.
    
        video::IVideoDriver* driver = device->getVideoDriver();
        scene::ISceneManager* smgr = device->getSceneManager();
    
        device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
    
        scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");
        scene::IMeshSceneNode* q3node = 0;
    
        if (q3levelmesh)
            q3node = smgr->addOctreeSceneNode(q3levelmesh->getMesh(0), 0, IDFlag_IsPickable);
        scene::ITriangleSelector* selector = 0;
    
        if (q3node)
        {
            q3node->setPosition(core::vector3df(-1350,-130,-1400));
    
            selector = smgr->createOctreeTriangleSelector(
                    q3node->getMesh(), q3node, 128);
            q3node->setTriangleSelector(selector);
        }
    
        scene::ICameraSceneNode* camera =
            smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, ID_IsNotPickable, 0, 0, true, 3.f);
        camera->setPosition(core::vector3df(50,50,-60));
        camera->setTarget(core::vector3df(-70,30,-60));
    
        if (selector)
        {
            scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
                selector, camera, core::vector3df(30,50,30),
                core::vector3df(0,-10,0), core::vector3df(0,30,0));
            selector->drop(); // As soon as we're done with the selector, drop it.
            camera->addAnimator(anim);
            anim->drop();  
        }
    
        device->getCursorControl()->setVisible(false);
    
        scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
        bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
        bill->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
        bill->setMaterialFlag(video::EMF_LIGHTING, false);
        bill->setMaterialFlag(video::EMF_ZBUFFER, false);
        bill->setSize(core::dimension2d<f32>(20.0f, 20.0f));
        bill->setID(ID_IsNotPickable); // This ensures that we don't accidentally ray-pick it
    
        scene::IAnimatedMeshSceneNode* node = 0;
    
        video::SMaterial material;
    
        node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/faerie.md2"),
                            0, IDFlag_IsPickable | IDFlag_IsHighlightable);
        node->setPosition(core::vector3df(-90,-15,-140)); // Put its feet on the floor.
        node->setScale(core::vector3df(1.6f)); // Make it appear realistically scaled
        node->setMD2Animation(scene::EMAT_POINT);
        node->setAnimationSpeed(20.f);
        material.setTexture(0, driver->getTexture("../../media/faerie2.bmp"));
        material.Lighting = true;
        material.NormalizeNormals = true;
        node->getMaterial(0) = material;
    
        selector = smgr->createTriangleSelector(node);
        node->setTriangleSelector(selector);
        selector->drop(); // We're done with this selector, so drop it now.
        node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d"),
                            0, IDFlag_IsPickable | IDFlag_IsHighlightable);
        node->setScale(core::vector3df(10));
        node->setPosition(core::vector3df(-75,-66,-80));
        node->setRotation(core::vector3df(0,90,0));
        node->setAnimationSpeed(8.f);
        node->getMaterial(0).NormalizeNormals = true;
        node->getMaterial(0).Lighting = true;
        selector = smgr->createTriangleSelector(node);
        node->setTriangleSelector(selector);
        selector->drop();
    
        node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/dwarf.x"),
                            0, IDFlag_IsPickable | IDFlag_IsHighlightable);
        node->setPosition(core::vector3df(-70,-66,-30)); // Put its feet on the floor.
        node->setRotation(core::vector3df(0,-90,0)); // And turn it towards the camera.
        node->setAnimationSpeed(20.f);
        node->getMaterial(0).Lighting = true;
        selector = smgr->createTriangleSelector(node);
        node->setTriangleSelector(selector);
        selector->drop();
    
        node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/yodan.mdl"),
                            0, IDFlag_IsPickable | IDFlag_IsHighlightable);
        node->setPosition(core::vector3df(-90,-25,20));
        node->setScale(core::vector3df(0.8f));
        node->getMaterial(0).Lighting = true;
        node->setAnimationSpeed(20.f);
    
        // Just do the same as we did above.
        selector = smgr->createTriangleSelector(node);
        node->setTriangleSelector(selector);
        selector->drop();
    
        material.setTexture(0, 0);
        material.Lighting = false;
        scene::ILightSceneNode * light = smgr->addLightSceneNode(0, core::vector3df(-60,100,400),
            video::SColorf(1.0f,1.0f,1.0f,1.0f), 600.0f);
        light->setID(ID_IsNotPickable); // Make it an invalid target for selection.
    
        scene::ISceneNode* highlightedSceneNode = 0;
        scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
        int lastFPS = -1;
        material.Wireframe=true;
        while(device->run())
        if (device->isWindowActive())
        {
            driver->beginScene(true, true, 0);
            smgr->drawAll();
            if (highlightedSceneNode)
            {
                highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, true);
                highlightedSceneNode = 0;
            }
    
            core::line3d<f32> ray;
            ray.start = camera->getPosition();
            ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 1000.0f;
    
            core::vector3df intersection;
            core::triangle3df hitTriangle;
    
            scene::ISceneNode * selectedSceneNode =
                collMan->getSceneNodeAndCollisionPointFromRay(
                        ray,
                        intersection, 
                        hitTriangle, 
                        IDFlag_IsPickable, 
                        0);     
            if(selectedSceneNode)
            {
                bill->setPosition(intersection);
                driver->setTransform(video::ETS_WORLD, core::matrix4());
                driver->setMaterial(material);
                driver->draw3DTriangle(hitTriangle, video::SColor(0,255,0,0));
    
                if((selectedSceneNode->getID() & IDFlag_IsHighlightable) == IDFlag_IsHighlightable)
                {
                    highlightedSceneNode = selectedSceneNode;
                    highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, false);
                }
            }
            driver->endScene();
    
            int fps = driver->getFPS();
    
            if (lastFPS != fps)
            {
                core::stringw str = L"Collision detection example - Irrlicht Engine [";
                str += driver->getName();
                str += "] FPS:";
                str += fps;
    
                device->setWindowCaption(str.c_str());
                lastFPS = fps;
            }
        }
        device->drop();
    
        return 0;
    }
  • 相关阅读:
    字符串 date 转标准 yyyyMMdd 格式
    stringBuild置空方法
    composer 加速
    php7.0 Mongodb 查询
    PHP7 mongo 操作
    php 简单的对称加密
    PHP 百度关键字
    php redis 写入读取的两个class
    php ci 框架自定义函数
    app已损坏,打不开,你应该将它移动到废纸篓
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6469023.html
Copyright © 2011-2022 走看看