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

it2022-05-05  95

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

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;   //鼠标多击(比双击还多)从以上类成员就可以看出设备里面包含些什么下面是针对各种不同平台的实现类CIrrDeviceConsoleCIrrDeviceLinuxCIrrDeviceSDLCIrrDeviceWin32从类名可以看出是针对哪个平台的。CIrrDeviceConsole是控制台上面几个平台的实现还除了派生于CIrrDeviceStub外,还派生于IImagePresenterIImagePresenter只有一个函数//! presents a surface in the client areavirtual 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;}}一切都明了了……这里并没有作详细的研究,只是一个简单的介绍,算是一个导读吧。大家根据这个思路去读源码,相信很快就能研究明白了~~~

转载于:https://www.cnblogs.com/qilinzi/archive/2010/04/26/1940509.html

相关资源:各显卡算力对照表!

最新回复(0)