Irrlicht(鬼火引擎)中多设备的支持

理清一个引擎,不得不先理清它的层次结构,进而理清渲染流程。 本文给出了鬼火引擎中的设备抽象层,有助于对鬼火引擎源码的快速阅读。

IrrlichtDevice *device =
  createDevice(driverType, core::dimension2d<u32>(640, 480),
  16, false, shadows);
这个函数大家都很熟悉,那闲话不多说,我们就从这里开始。。。

IrrlichtDevice 设备的顶层接口
CIrrDeviceStub  实现设备顶层接口类,所有设备都从此派生,这里的设备是指和平台相关的设备
类成员:
video::IVideoDriver* VideoDriver;//   图形接口
gui::IGUIEnvironment* GUIEnvironment;// GUI接口
scene::ISceneManager* SceneManager;//场景节点接口
ITimer* Timer; //定时器,保证了一个设备持有一个定时器
gui::ICursorControl* CursorControl; //鼠标控制器
IEventReceiver* UserReceiver;//事件处理器
CLogger* Logger;//日志
IOSOperator* Operator; //系统操作相关
io::IFileSystem* FileSystem; //文件系统
scene::ISceneManager* InputReceivingSceneManager;   //
video::CVideoModeList VideoModeList;   //图形模式列表
SIrrlichtCreationParameters CreationParams;//创建图形设备时的参数
SMouseMultiClicks MouseMultiClicks;   //鼠标多击(比双击还多)
从以上类成员就可以看出设备里面包含些什么

下面是针对各种不同平台的实现类
CIrrDeviceConsole
CIrrDeviceLinux
CIrrDeviceSDL
CIrrDeviceWin32
从类名可以看出是针对哪个平台的。CIrrDeviceConsole是控制台
上面几个平台的实现还除了派生于CIrrDeviceStub外,还派生于IImagePresenter
IImagePresenter只有一个函数
//! presents a surface in the client area
virtual bool present(video::IImage* surface, void* windowId=0, core::rect<s32>* src=0 ) = 0;
输出到目标客户区。。。

对于平台相关的设备的实现,拿WIN32的来说
下面是类成员:
core::position2d<s32> CursorPos;
core::dimension2d<u32> WindowSize;
core::dimension2d<f32> InvWindowSize;
bool IsVisible;
HWND HWnd;
s32 BorderX, BorderY;
bool UseReferenceRect;
core::rect<s32> ReferenceRect;
可以看出,即是持有与平台相关的数据。平台无关的都被CIrrDeviceStub搞定啦
下面我们来仔细看看createDevice函数做了些什么。
用法示例:
IrrlichtDevice *device =
  createDevice(driverType, core::dimension2d<u32>(640, 480),
  16, false, shadows);

createDevice函数的参数意思就不多说了,会用API的人都知道。
实现如下:
IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice(video::E_DRIVER_TYPE driverType,
   const core::dimension2d<u32>& windowSize,
   u32 bits, bool fullscreen,
   bool stencilbuffer, bool vsync, IEventReceiver* res)
{
SIrrlichtCreationParameters p;
p.DriverType = driverType;
p.WindowSize = windowSize;
p.Bits = (u8)bits;
p.Fullscreen = fullscreen;
p.Stencilbuffer = stencilbuffer;
p.Vsync = vsync;
p.EventReceiver = res;
return createDeviceEx(p);
}
可以看出,它将参数赋值给SIrrlichtCreationParameters结构,然后调用createDeviceEx
关键就是这个createDeviceEx,实现了对应平台的创建
主要代码如下
IrrlichtDevice* dev = 0;
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
  if (params.DeviceType == EIDT_WIN32 || (!dev && params.DeviceType == EIDT_BEST))
   dev = new CIrrDeviceWin32(params);
#endif
#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
  if (params.DeviceType == EIDT_OSX || (!dev && params.DeviceType == EIDT_BEST))
   dev = new CIrrDeviceMacOSX(params);
#endif
#ifdef _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_
  if (params.DeviceType == EIDT_WINCE || (!dev && params.DeviceType == EIDT_BEST))
   dev = new CIrrDeviceWinCE(params);
#endif
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
  if (params.DeviceType == EIDT_X11 || (!dev && params.DeviceType == EIDT_BEST))
   dev = new CIrrDeviceLinux(params);
#endif
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
  if (params.DeviceType == EIDT_SDL || (!dev && params.DeviceType == EIDT_BEST))
  dev = new CIrrDeviceSDL(params);
#endif
#ifdef _IRR_COMPILE_WITH_CONSOLE_DEVICE_
  if (params.DeviceType == EIDT_CONSOLE || (!dev && params.DeviceType == EIDT_BEST))
  dev = new CIrrDeviceConsole(params);
#endif
根据宏定义决定了平台相关系,从而创建出相应的平台。。。。。
请大家注意上面代码中的params参数,他就是一个SIrrlichtCreationParameters结构体,这个参数决定了创建图形设备的信息。我们以WIN32为例,来继续探究IRR是如何实现平台、图形API无关的。
CIrrDeviceWin32(const SIrrlichtCreationParameters& params);
这是CIrrDeviceWin32它的构造函数,从而可知,params决定了一切,而params除了包含用户指定的API信息以外,并未有平台相关的信息,所以,平台创建是无关的,而params决定了图形API的选择,当然,图形API的选择也可以通过类似的方案来实现,比如:在用户创建设备(调用createDevice)前,可以先测试是否支持D3D,如果不是再选择OPEGNL。。。。
扯远了,继续说一下是怎么创建的。。
下面我们进入他的构造函数的实现
构造函数将params传给了他的父类。。。。,而它自已实现了WINDOWS相关的创建工作,如窗口类注册,创建等。。。
params在父类中由CreationParams;//保存(如果忘了,请看贴子开头的地方)。。。
构造函数还调用了另一个函数(当然不止一个,我只是说,这是一个与CreationParams相关的函数)
好了,就是它:createDriver();这个函数实现的代码大致如下
void CIrrDeviceWin32::createDriver()
{
switch(CreationParams.DriverType)
{
case video::EDT_DIRECT3D8:
  #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_
  VideoDriver = video::createDirectX8Driver
  break;
case video::EDT_DIRECT3D9:
  #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
  VideoDriver = video::createDirectX9Driver
  break;
case video::EDT_OPENGL:
  #ifdef _IRR_COMPILE_WITH_OPENGL_
  VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this);
  break;
case video::EDT_SOFTWARE:
  #ifdef _IRR_COMPILE_WITH_SOFTWARE_
  VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, 
  break;
case video::EDT_BURNINGSVIDEO:
  #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
  VideoDriver = video::createSoftwareDriver2
  break;
case video::EDT_NULL:
  // create null driver
  VideoDriver = video::createNullDriver
  break;
}
}
一切都明了了……

这里并没有作详细的研究,只是一个简单的介绍,算是一个导读吧。大家根据这个思路去读源码,相信很快就能研究明白了~~~

作者:码瘾少年·麒麟子 
出处:http://www.cnblogs.com/geniusalex/ 
蛮牛专栏:麒麟子 
简介:09年入行,喜欢游戏和编程,对3D游戏和引擎尤其感兴趣。 
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/geniusalex/archive/2010/04/26/1940509.html

时间: 2024-09-16 00:17:58

Irrlicht(鬼火引擎)中多设备的支持的相关文章

使用WEBLOGIC PORTAL规则引擎中实现动态业务逻辑

web|动态 简介 业务应用的需求总是随着业务环境的变化趋势而不断地改变.决策很少是一成不变的,并且竞争压力要求业务逻辑的设计和实现具有灵活性,以快速地适应不断变化的需求.通常,对业务逻辑的更改必须由开发人员来完成,然后进行多次彻底的测试,而这将是一个很耗时的过程.在应用程序的修改工作完成后,需要将其重新部署到服务器,需要留出预定的停机时间,以防应用程序对用户不可用. 对于这个问题,更好的解决方案是通过应用程序之外的一组规则来实现某些业务决策.这些规则并没有被编译到应用程序中,而是在运行时读取并

浅谈Linux 中字符设备的注册

Linux中字符设备的注册过程是比较简单的.我们通常可以调用misc_register()函数来注册一个字符设备.Misc设备是一种字符设备,通过该设备可以将fops请求转发给注册的misc设备,从而实现字符设备的功能.用户调用该接口注册Misc字符设备时,可以动态分配设备Minor号,当获取Minor号之后调用class_simple_device_add()或者device_create()函数完成字符设备的创建.Misc字符设备注册函数如下所示: int misc_register(str

全志平台boot框架中增加设备驱动过程分析

全志平台boot框架中增加设备驱动过程分析          在boot启动阶段,大家都知道他的主要目的就是引导uboot,uboot在引导内核,从而让整个系统运作起来.全志的boot阶段,对应平板这一块,它会驱动LCD,显示一些开机LOGO,这个过程很快,也就1-2秒钟的时间.然而对于车载行业应用来说,可能需要再boot阶段做一些事情.比如,机器冷启动,大家都知道android启动时间还是比较长的,那么怎么使得客户能快速的用上倒车影像的功能呢?这就需要动脑筋了. /**************

安卓手机安装软件提示“您的设备不支持add-on属性”的解决方法

园子今天使用安卓手机安装游戏时,遇到了提示"您的设备不支持add-on属性"的情况,出现提示后软件就安装不了了.本文分享下使用安卓手机安装软件时出现"您的设备不支持add-on属性"的解决方法. 在网上搜索一番,发现有不少机友也出现了类似情况.出现这种错误提醒大多是因为安装的软件带有运动追踪器.基站定位等功能的软件,主要原因是因为手机中缺少谷歌的服务造成的.使用安卓手机的机友一般比较喜欢刷机,刷的ROM包很多都去掉了谷歌服务套件,部分软件中所带有的类似运动追踪的功能

在 IIS 中配置 SQL XML 支持

首先,说一下我们的例子目的--一让数据库输出XML,并且在.net体系下调用出来.      这个系统的数据层是用SQL server数据库,中间层就用SQL自带的工具"在 IIS 中配置SQL XML 支持"实现就可以了.好的,现在我们开始来做了,首先配置让SQL 输出 XML :      这个东西听起来似乎有些神秘,其实就是在我们普通的查询语句后边增加:FOR XML AUTO 就可以了.     举一个例子:       SELECT TOP 100 topic,name,ti

EasyJWeb Tools业务引擎中分页的设计及实现

web|分页|设计 在Web应用开发中,不管是有没有数据库,经常要用到分页处理问题.EasyJWeb中通过引入IPageList接口来轻松解决我们的遇到的各种分页问题,包括对数据库记录分页.文件目录分页.数组或者Java对象分页等. EasyJWeb作为一个Web框架,其MVC核心中本身没有包含分页的内容,我们这里所说的分页设计是指在EasyJWeb Tools业务引擎中关于分页需求应用的设计. 1.应用示例代码 首先们看看该分页设计的有关应用示例代码,该示例的完整代码可在http://www.

JDK/JRE5.0中对于IPv6的支持-解读JDK5.0对IPv6网络编程的支持

编程|网络 JDK5.0 Document:Networking IPv6 User Guide for JDK/JRE 5.0This document covers the following topics:Overview Supported Operating Systems Using IPv6 in Java Details on IPv6 Support in Java Special IPv6 Address Types IPv6-Related System Propertie

ASP.NET中的错误处理支持(转)

asp.net|错误|错误处理 ASP.NET中的错误处理支持 ASP.NET具有一个很好的新功能:它对运行时间错误的处理和跟踪提供了丰富支持.特别是,它为管理人员提供了一种很简单的方法,可以保证那些令人恐惧的"ASP 43433ax"十六进制形式的错误永远也不会被显示到客户面前.相反,它允许显示一个较为定制化的信息,比如"对不起,这个站点不可用".ASP.NET还提供了一种强大的方法,使开发人员可以对他们的代码进行装备,向管理人员提供发生在工作站点问题的额外信息与

Windows 操作系统中的 .NET Framework 支持(正文)

window Windows 操作系统中的 .NET Framework 支持 Hans VerbeeckMicrosoft EMEA 2002 年 9 月 适用于:   Microsoft .NET Framework   Microsoft Windows 操作系统 摘要:本文提供了有关能够安装 Microsoft .NET Framework 的 Microsoft Windows 版本的信息,同时还列出了 .NET Framework 的软件要求以及常规平台支持的某些例外情况.此外,还解