本篇讨论IrrlichtDevice,主要探讨以下几个问题:
->irrlicht对设备做了哪些抽象
->如何做到跨平台
->win32设备的实现细节
1)引擎的基石 - IrrlichtDevice
irrlicht
所指的设备是什么呢?探究IrrlichtDevice接口,irrlicht设备是对应用程序窗口环境的抽象,实际上对应了在各个平台上的应用程序框
架。在IrrlichtDevice接口中,有run(),closeDevice(),yield(),sleep()这样的应用程序生命周期操作,也
有setResizeAble(),setWindowCaption这样对窗口的操作,另外设备还持有了video driver,scene
manager,gui enviroment, file
system等对象,从接口看应该在实现的具体设备中完成这些对象的构造并管理这些对象。IrrlichtDevice可以算是引擎的基石,支撑起在目标
平台上3D引擎的运行,如果我们设计的引擎想要跨平台则必须要做这样的抽象。
2)如何实现设备跨平台
使用irrlicht引擎
时,首先要调用的一个全局函数:createDevice(),他的实现在源文件Irrlicht.cpp中,实际上真正完成工作的是
createDeviceEx(),这个函数的声明和createDevice()一样都在irrlicht.h中,但实现在不同的平台的
CIrrDeviceXXX.cpp中。irrlicht通过编译选项保证只有一个平台的相关代码被编译,所以不会出现多次
createDeviceEx()的定义。在windows平台上,_IRR_USE_WINDOWS_DEVICE_被定义,而其他如
_IRR_USE_LINUX_DEVICE_是没有定义的,所以设备相关的起作用的代码文件是CIrrDeviceWin32.h/.cpp。在
IrrCompileConfig.h中可以发现,如果定义了_IRR_USE_SDL_DEVICE_,就不会定义
_IRR_USE_WINDOWS_DEVICE_,此时将是SDL设备起作用。总之,只有一个平台会被定义,只有一种设备会被创建,只有一份
createDeviceEx()存在。通过编译选项和宏定义,编译器只会选择编译某一平台的代码,构建某一平台的irr设备。
3)Win32设备源码剖析
上面说了,在win32平台上,只有CIrrDeviceWin32.h/.cpp会被编译,查看源代码,首先发现:
class CIrrDeviceWin32 : public CIrrDeviceStub
查
词典,“计算机编程中,RMI中将客户辅助对象称之为Stub”,CIrrDeviceStub是个所有设备类型都能用上的公共功能的集合,是个辅助的基
类。那么先看下这个类,源码
CIrrDeviceStub.h/.cpp。这个类不会创建一个具体的IrrDevice(很显然,因为他是各平台共享的辅助类,当然不会关心某个具体
的设备),没有惊讶,这个类持有并管理了一些IrrDevice接口上可以看出的对象,如FileSystem,当然FileSystem本身就是跨平台
的实现,这是一种形式,另一种形式是stub提供了创建函数,但自己并没有调用它,具体的就是createGUIAndScene(),会创建
GUIEnvironment和SceneManager,这个函数会在子类中调用。另外stub还实现了getXXX()系列的接口。
stub只是尽量提取了一些各平台共有的操作,真正的东西还是需要各自平台自己实现。
下面分析win32设备。
<1>设备创建
首
先寻找createDeviceEx(),其中只是new了一个CIrrDeviceWin32对象,并检查是否成功,主要的创建还是在
CIrrDeviceWin32的构造函数中。构造函数中主要的工作是创建窗口(也可以使用外部传入的窗口HWND),创建driver,创建GUI和
SceneMgr(调用stub中的createGUIAndScene())。这里的重点是创建driver,irrlicht可以同时支持多种
driver并在运行前选择,也就是说这些driver都是编译好的(而不是像device那样只编译了一个),在createDriver()中,会根
据CreateParams决定创建哪种driver,其中创建硬件driver,如DX,OpenGL是在平台的代码中的,而创建软件driver和
NULL
driver是在stub中。在Linux版本的device中我们发现只有OpenGL这种硬件driver,当然了,Linux并不支持DX。
<2>运行和关闭设备
从最简短的例子可以看到,通过判断设备是否run()而进行游戏的主循环。win32版的run()如下:
os::Timer::tick()
用来记录系统时间,这是全局的,irrlicht引擎是基于时间而不是基于固定帧的,后面会有一篇专门分析这个问题。再下面是一个常用的
PeekMessage式windows消息循环。重点是返回值,只有窗口收到WM_QUIT消息,run()才返回false,而窗口的quit既可以
是直接关闭窗口,也可以是游戏调用device的closeDevice():
<3>其他接口
win32
device中内含的窗口消息处理函数WndProc中,会处理如键盘鼠标这样的事件,并转换成irrlicht的消息。device还实现了
IImagePresenter接口,这个接口只有一个方法present,只有软件driver会使用它,将buffer绘制到屏幕上。另外还有
sleep(),yield()这样的线程控制方法。
小结:一个游戏有一个device对象,device抽象了不同的游戏平台操作系
统,提供了运行和关闭的接口,封装了driver的创建,保存了driver, gui, scene manager, file
system等全局唯一的对象。试想,如果我们要给irrlicht增加一个新的游戏平台,比如ps3,我们要做什么呢?当然是符合irr语义的实现这些
接口即可,程序会照样的run起来,maybe you want to try.
分享到:
相关推荐
鬼火引擎源码(irrlicht-1.8.4) 是一个游戏引擎源码,欢迎各位下载学习。以前定价太高了,现在就当作福利送给大家吧。
irrlicht1.6的帮助手册-英文的帮助手册可惜没有中文的!
irrlicht-1.7.1. 引擎源码
irrlicht 3d 引擎 源代码-------绝对好用的轻巧3d引擎!!!!!!!!
irrlicht 3D 游戏引擎源码 实例 工具源码俱全! C++.NET精品!!
Irrlicht引擎是一个用C++书写的高性能实时的3D引擎,可以应用于C++程序或者.NET语言中。通过使用Direct3D(Windows平台),OpenGL 1.2或它自己的软件着色程序,可以实现该引擎的完全跨平台。尽管是开源的,该...
游戏开发初学者可以看看,全中文注释irrlicht-1.6引擎的第一个例子,后面的的例子正在翻译,敬请期待!
游戏开发初学者可以看看,全中文注释irrlicht-1.6引擎的第一个例子,后面的的例子正在翻译,敬请期待!
游戏开发初学者可以看看,全中文注释irrlicht-1.6引擎的第一个例子,后面的的例子正在翻译,敬请期待!
Irrlicht引擎是一个用C++书写的高性能实时的3D引擎,可以应用于C++程序或者.NET语言中。通过使用Direct3D(Windows平台),OpenGL 1.2或它自己的软件着色程序,可以实现该引擎的完全跨平台。尽管是开源的,该...
Irrlicht Engine中文学习指南、Irrlicht(鬼火引擎)入门教程、OpenGL开发环境配置过程、Visual_Studio_2008_中OpenGL_开发环境配置
本文档的主要内容详细介绍的是Irrlicht鬼火引擎入门教程免费下载。 Irrlicht引擎是一个用C 书写的高性能实时的3D引擎,可以应用于C 程序或者.NET语言中。通过使用Direct3D(Windows平台),OpenGL 1.2或...
游戏开发初学者可以看看,全中文注释irrlicht-1.6引擎的第一个例子,后面的的例子正在翻译,敬请期待!
Irrlicht引擎是一个用C++书写的高性能实时的3D引擎,可以应用于C++程序或者。NET语言中。通过使用Direct3D(Windows平台),OpenGL 1.2或它自己的软件着色程序,可以实现该引擎的完全跨平台。尽管是开源的,该...
irrlicht-1.8 Irrlicht引擎是一个用C++书写的高性能实时的3D引擎,可以应用于C++程序或者。NET语言中。通过使用Direct3D(Windows平台),OpenGL 1.2或它自己的软件着色程序,可以实现该引擎的完全跨平台。尽管是...
Irrlicht引擎中的 例子说明,这是一个中文的说明,很详细,是网上找的,我打了个包。里面有个说明是关于与其有关的物理引擎和声音引擎
Irrlicht引擎是一个用C++书写的高性能实时的3D引擎,可以应用于C++程序或者.NET语言中。通过使用Direct3D(Windows平台),OpenGL 1.2或它自己的软件着色程序,可以实现该引擎的完全跨平台。尽管是开源的,该...
用Irrlicht官方OpenGL-ES Branch Rebuild的iPhone版本,在4.0的模拟器上测试通过,增加对触摸事件的响应 相关参考链接:http://leosfantasyworld.blog.sohu.com/
3D游戏引擎irrlicht
学习Irrlicht载入网格文件,其实非常简单。通过我仿照例子写的一段代码,很简单地载入网格文件。 首先向大家介绍一下如何利用Irrlicht的源代码和...帮助文档在irrlicht-1.7.3/doctemp/html,找到index.html即可查看。