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部分)
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