• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

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

武飞扬头像
麒麟子MrKylin
帮助1

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;

}

}

一切都明了了……

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

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhicijaj
系列文章
更多 icon
同类精品
更多 icon
继续加载