yzwalkman 发表于 2012-12-30 11:52:25

Ogre源代码浅析——插件(Plugin)工作原理

<div id="cnblogs_post_body">      Ogre引擎由多个模块组成,从不同角度来划分可以得到不同的结果。从功能上看Ogre可大致分为资源管理、场景管理和渲染管理三大模块;而从可执行部分的组织方式看,Ogre引擎则是由多个dll动态链接库组合而成的。
      组成Ogre的各动态库基本上可以分为以下几部分:核心库、渲染层、场景管理逻辑层。核心库(OgreMain.dll,一般debug版会生成OgreMain_d.dll文件)负责资源加载和管理,并根据实际情况选择和加载对应的渲染层模块及场景管理层模块,同时调度协调各模块共同对场景进行渲染操作。渲染层主要是对不同的底层渲染引擎进行封装,使不同的底层渲染引擎如:DirectX、OpenGL、OpenGLES等能够支持相同的渲染接口,以实现核心层用统一的方式对不同底层渲染引擎的调用。这种技术有点类似《设计模式》中提到的Adapter模式。为了支持不同的底层渲染引擎,Ogre要有针对性地生成不同的动态链接库如:RenderSystem_Direct3D9.dll、RenderSystem_Direct3D11.dll、RenderSystem_GL.dll、 RenderSystem_GLES.dll等。场景管理层则主要根据实际需要,采用不同的算法来实现对场景对象的快速裁剪,比如若要用八叉树对场景进行管理时一般要生成并调用Plugin_OctreeSceneManager.dll库,而要用BSP算法则需要生成并调用Plugin_BSPSceneManager.dll库等。
   以上所说的这些动态库要能协调一致地工作,需要首先解决以下两个问题:1. 如果不考虑跨平台并假设是在Windows平台上运行,如何实现各动态库与核心库的衔接?Ogre是用面向对象的技术开发的,Windows平台只提供了动态加载动态链接库及调用其中库函数的相关技术,并没有现成的对动态加载的动态库函数中对象的访问方法。2. 如果考虑跨平台的问题,那么该如何对动态库的动态加载过程作进一步的抽象?(另外,如果要考虑将渲染引擎引入到IOS平台上,那么除了要对加载过程进行适当抽象外,还要考虑到IOS并不支持动态链接库的实际情况,而只能采用静态库的使用方法。此问题不在本文的讨论范围之内)
   对于以上问题,Ogre采用了称之为插件(Plugin)的技术来加以解决,这种方法本身比较巧妙,而且对我们以后的模块化编程有一定的借鉴意义,所以值得详细分析一下。
   首先Oger对要加载的动态库作了一个抽象,用DynLib类来表示,一个动态库就是一个DynLib类对象。同时Ogre又定义了一个DynLibManager类,用来管理所有加载的DynLib类对象,它负责根据动态库文件名对相应的库进行加载,并保存加载后的DynLib对象指针。
   此处采用的是Oger1.8的相关代码。
<div class="cnblogs_Highlighter">OgreRoot.cpp


void Root::loadPlugin(const String& pluginName){#if OGRE_PLATFORM != OGRE_PLATFORM_NACL   // Load plugin library   DynLib* lib = DynLibManager::getSingleton().load( pluginName );   // Store for later unload   // Check for existence, because if called 2+ times DynLibManager returns existing entry
   if (std::find(mPluginLibs.begin(), mPluginLibs.end(), lib) == mPluginLibs.end())   {
       mPluginLibs.push_back(lib);      // Call startup function      DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)lib->getSymbol("dllStartPlugin");      if (!pFunc)OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find symbol dllStartPlugin in library " + pluginName,"Root::loadPlugin");      // This must call installPlugin      pFunc();    }#endif}
页: [1]
查看完整版本: Ogre源代码浅析——插件(Plugin)工作原理