• 转:Irrlicht 0.1引擎源码分析与研究(一)


     

    Irrlicht引擎主要是由一个名叫Nikolaus Gebhardt奥地利人所设计,是sourceforge上的一个开源项目。 Irrlicht是一个德国神话故事中的一种动物的名字,它能够发光和飞翔,可以在大部分的沼泽地附近发现它。单词"Irrlicht"是两个德国单词("irr"意思是疯狂的;而"Licht"意思是光)的组合。在英语中,它被译为"鬼火"。

    Irrlicht采用C++封装该,是一款轻量级的、跨平台的、支持多种图形库的3D引擎,引擎本身精简强悍。irrlicht的设计很好的体现了接口和实现分离的原则,整个框架设计精巧清晰,是学习3d引擎设计的不错的教材。由于我研究这个引擎的目的主要是想分析其源代码,对3D引擎的结构及实现产生一个较直观深刻的认识,因此选择了该引擎的最早版本irrlicht0.1进行分析。本文中部分内容从Irrlicht文档或其它英文资料中翻译过来,由于并不是什么很严谨的科技文献,所以大部分地方采用意译的方法。

    在这个网站上你能够找到它所有版本的源代码、文档以及更多的信息:http://irrlicht.sourceforge.net。项目从2004开始一直至今,后期发展了许多相关工具,如irrklang(音效引擎),irrEdit(3D编辑器)等。

    主要技术特性

    Irrlicht是一款由c++编写的3D引擎,由于底层的代码封装良好,所以该引擎可以在多个平台上使用,如WINDOWS、LINUX等。

    整个引擎使用了类COM的中间件封装技术,这确保了引擎的跨平台使用和可扩展性,也就是当引擎内部被修改,原游戏逻辑代码不用改一行代码也可正常使用,而当需要向引擎添加新的技术特性,只需要符合它的规范和接口就可以很轻易的加入新的特性。

    3D引擎的常见问题在于速度,而irr引擎速度非常快。

    引擎概览

    先看下名字空间的划分,Irr总命名空间下有5个子命名空间,可以看到irr具有非常清晰的结构:

    irr Irrlicht引擎中的一切都在此命名空间下实现。除了它的5个子命名空间的内容之外,irr空间中提供了引擎的一些底层构架的支持,如事件处理系统,操作系统抽象,引用计数,设备抽象等。

    irr::core 提供了基础的数学和数据结构构件,如向量,矩阵,列表,数组等等。

    irr::gui 此命名空间包含了一些 创建一个简单的GUI所需的类

    irr::io 此命名空间提供输入/输出的接口:读/写文件,访问zip文件等等

    irr::scene 所有与场景管理相关的都可以在此命名空间中找到:camera, Mesh加载,像八叉树和广告牌之类特殊的场景结点,等等

    irr::video 此命名空间包含访问图形驱动器的一些类,所有的2D和3D渲染都在此完成。它将d3d,Opengl等绘图的部分进行封装,与外部隔离起来。

    我想重点剖析的是irr::video和irr::scene,这是3d引擎的核心部分,目的是分析irrlicht是如何将不同的图形API进行抽象的,以及如何进行引擎的运转,并将各种3d技术融入到这个体系中的。另外irr如何做到跨平台支持的也会进行剖析。

    Irrlicht的窗口管理

    Irrlicht窗口封装(仅分析Windows部分)

    首先看下文档中的Hello World 例子:

    IrrlichtDevice *device =

    createDevice(DT_SOFTWARE, dimension2d(512, 384), 16, false, 0);

    IVideoDriver* driver = device->getVideoDriver();

    ISceneManager* smgr = device->getSceneManager();

    上述代码显示了irrlicht最基本的几个对象-设备、图形驱动、场景管理器。简单看来,通过全局函数createDevice根据指定的驱动类型创建一个设备,之后可通过设备对象得到驱动对象以及场景管理器对象。

    device->setWindowCaption(L"Hello World!" );

    //设备对象具有一些设备相关的能力,比如这儿可以设置窗口标题。

    //加载md2模型

    IAnimatedMesh* mesh = smgr->getMesh("..//media//sydney.md2");

    IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );

    //设置材质和纹理

    if (node)

    {

    node->setMaterialFlag(EMF_LIGHTING, false);

    node->setFrameLoop(0, 310);

    node->setMaterialTexture( 0, driver->getTexture("..//media//sydney.bmp") );

    }

    // 添加一个像机

    smgr->addCameraSceneNode(0, vector3df(0,20,-60), vector3df(0,0,0));

    这几行代码显示了scene graph体系,ISceneNode是irrlicht场景中基础组成部分节点的抽象,这儿添加了一个动画mesh节点,和一个camera节点。节点具有材质属性(当然camera并不需要材质,但是ISceneNode作为一个抽象要尽量兼顾各种节点,为了让接口的层次简单些,这样做也是一个实用的方法)

    // 主循环,渲染

    while(device->run())

    {

    driver->beginScene(true, true, Color(0,100,100,100));

    smgr->drawAll();

    driver->endScene();

    }

    这几行是引擎运转的过程,首先引擎运转的条件是设备仍然在运转:device->run(),可通过closeDevice关闭设备。 smgr ->drawAll()执行了所有节点的渲染,节点的渲染不仅仅是draw,节点的transform计算,动画计算(包括骨骼动画),camera这种特殊节点的操作(特殊的节点还有光源等),都包含在渲染的范畴中,在drawAll中统一调用,各种节点实现各自的渲染,最终由 smgr统一管理(如排序)绘制,这正是基于scene graph架构的引擎的特点之一。

    device->drop();

    这一句体现了irrlicht的引用计数机制,通过grab,drop管理对象引用次数。这儿如果一切正常应该是引用drop为0,device销毁自己,退出程序。

    从这个很短的例子可以看到irrlicht的基本构件和运行过程。irrlicht提供了scene的管理机制,并提供了大量预定义好的scene nodes,实现了很多的功能,这样你就可以很方便的使用引擎。并且这种机制的好处是,节点可以不断的扩展,并可以在以后的项目中复用。

    整理参考:

    hellphenix的专栏:http://blog.csdn.net/hellphenix/archive/2008/03/19/2198226.aspx

    小时候可靓了:http://blog.csdn.net/wqjqepr/archive/2010/04/26/5528528.aspx

    游戏的行者:http://blog.csdn.net/n5/archive/2009/07/08/4329603.aspx

    游戏的行者:http://blog.csdn.net/n5/archive/2008/12/15/3516219.aspx

    游戏的行者:http://blog.csdn.net/n5/archive/2009/07/05/4323332.aspx

    游戏的行者:http://blog.csdn.net/n5/archive/2009/07/12/4342758.aspx

    Flyflyking:http://blog.csdn.net/flyflyking/archive/2011/03/30/6289698.aspx

  • 相关阅读:
    2020牛客暑期多校训练营(第五场)D 思维|最长上升子序列
    codeforces-1343E(贪心+BFS)
    2020牛客暑期多校训练营(第三场)C 计算几何
    codeforces-1385E(拓扑排序)
    2020牛客寒假算法基础训练营2
    2020牛客寒假算法基础训练营1
    codeforces-1295D(欧拉函数)
    codeforces-1283D(多源BFS)
    深入理解JVM之JVM内存区域与内存分配
    属性动画详解一(Property Animation)
  • 原文地址:https://www.cnblogs.com/skyofbitbit/p/4085154.html
Copyright © 2020-2023  润新知