青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Ogre源碼剖析3–可擴展性&插件機制

Posted on 2009-07-01 13:54 RichardHe 閱讀(1829) 評論(0)  編輯 收藏 引用 所屬分類: OGRE
Ogre源碼剖析3–可擴展性&插件機制

 

Ogre是一個跨操作系統平臺的開源3D引擎,既支持DirectX,也支持使用OpenGL,支持可替換的場景管理算法(BSP, OCT)。為Ogre提供這些靈活可擴展性的基礎之一就是其面向插件的設計。

 

很多常用的軟件大都提供了插件接口,用以擴展應用程序設計者最初未想到的功能,比較常見的譬如PhotoShop的濾鏡,After Effect中的各種插件(最有名的比如shine),3dMax的插件譬如渲染器,魔獸世界的輔助插件等等。

通常,插件本身通常也需要實現主應用程序所需要的必要接口,從而使得插件可以被應用程序加載執行。此外,插件的實現也需要由主應用程序提供一些接口api,通過這些接口,插件可以對主應用程序的功能進行調用。

插件可以是動態鏈接庫(win32平臺上為DLL文件),也可以是以腳本的形式提供的,比如魔獸世界中的插件就是使用lua編寫的,插件也可能是某種應用程序自定義的文件,只要該應用程序提供了創建該類文件的方法并實現解析、執行功能即可。(不同的實現形式各有利弊,具體需要參考插件及應用程序所處的運行環境進行取舍)

采用插件的一個巨大的好處,以及很多應用程序中使用插件的主要目的就是,我們可以在不需要改動應用程序本身的情況下擴展應用程序的功能。

 

在Ogre中,插件被用來提供渲染子系統(RenderSystem),不同類別的圖形API被封裝在不同的渲染子系統的視線當中,Ogre默認提供了DX和OpenGL的實現,甚至,如果我們樂意,甚至可以只用繪點函數實現一套純軟件的渲染子系統提供給Ogre使用。以此為例,用簡單的形式來展示這種實現大概類似于下面這樣:

class RenderSystem

{

         
// … operations that a render system need to support

};

// In DX_RenderSystem.dll (in plugin dx rendersystem )

class DX_RenderSystem : public RenderSystem

{

         
// … implementation & override of the operations from RenderSystem using DirectX

};

// In GL_RenderSystem.dll (in plugin openGL rendersystem)

class GL_RenderSystem : public RenderSystem

{

         
// … implementation & override of the operations from RenderSystem using OpenGL

};

// …. We could implement any other rendersystem as we like

 

在引擎的內部(OgreMain),插件在初始化的時候,將一個渲染子系統的實例創建出來(可能是DX_RenderSystem,也可能是 GL_RenderSystem,也可能是其他),并將之掛接到OgreMain的Root對象當中。此后,OgreMain中的Root所有的渲染操作也就可以通過該接口訪問插件中創建的渲染子系統了。

 

         本文接下來分析Ogre是如何實現插件的,以及插件是如何與OgreMain主引擎進行配合的。

         事實上,想編寫一個插件是很簡單的,我們只需要約定幾個接口,插件將這些接口實現了,主應用程序通過某種機制(配置文件
/遍歷某個目錄)加載插件,并查找接口在插件中是否被實現了,如果實現了,則調用之即可。

 

一個簡單的例子如下:

// in xx.dll

__declspec(dllexport) 
extern “C”    // __declspec(dllexport)告知編譯器需要將該函數導出

                                                                 
// extern “C” 告知編譯器不要對函數做C++名字重整

const char* GetPluginName(void)

{

         
return “Test Plugin”;

}

 

// in application

HMODULE hInst 
= LoadLibrary(”xx.dll”);

if (!hInst) return;

typedef 
const char* (*GetPluginNameFunc)(void);

GetPluginNameFunc pFunc 
= GetProcAddress(hInst, “GetPluginName”);

if (!pFunc) return;

const char* szPluginName = pFunc();

// … do other things

 

事實上,在C語言里,我們就可以通過這種方式,約定一套需要實現的接口,交給插件實現即可。在這里,插件的功能都是在dll中實現的,我們需要加載 dll,保存句柄,并在插件卸載的時候釋放相應的資源。在C
++中,我們顯然可以做的更好一點,比如將dll模塊相關的功能以及資源封裝起來:

 

class DynLib

{

public:

         
bool Load(const char* szPluginPath);

         
void* GetProcAddress(const char* szProcName);

private:

         HMODULE m_hInst;

};

 

bool DynLib::Load(const char* szPluginPath)

{

m_hInst 
= LoadLibrary(szPluginPath);

return m_hInst != NULL;

}

 

void* DynLib::GetProcAddress(const char* szProcName)

{

         
return ::GetProcAddress(m_hInst, szProcName);

}

 

這樣一來,我們就有了一個DLL的簡單封裝。

但是一個dll里未必只能有一個插件,假若我們簡單的把插件接口設計為一套C導出函數,我們就不得不面對這種局限。經典的做法依舊是抽象,Ogre中定義了一個插件接口,每一個實現了插件接口的實例都代表了一個插件,如下:

 

class Plugin

{

public:

         
virtual const String& getName() = 0;

         
virtual void install() = 0;

         
virtual void initialize() = 0;

         
virtual void shutdown() = 0;

         
virtual void uninstall() = 0;

};

 

Ogre的每一個插件都需要實現以上接口。該接口提供的功能包括:

install 插件被加載時調用。

initialize 插件被初始化時調用。

shutdown 插件被反初始化時調用。

uninstall 插件被卸載時調用。

 

不過,單有這個接口,插件還是無法工作。插件中還需要提供兩個約定的C導出函數。這個稍后再說。

 

Ogre在Root對象中統一管理插件,因此Root對象提供了以下與插件相關的接口:

class Root

{

         
// …

void loadPlugin(const String& pluginName);

void unloadPlugin(const String& pluginName);

void installPlugin(Plugin* plugin);

void uninstallPlugin(Plugin* plugin);

// 以及對應的處理多個插件的接口

         
// …

};

 

當loadPlugin函數被調用時,Ogre將加載該插件的dll,從中查找并調用名為dllStartPlugin的導出函數。

對應的,當unloadPlugin函數被調用時,Ogre將從該dll中調用dllStopPlugin函數。并將該dll卸載。

 

每個插件在實現的時候,都必須提供上述的兩個C導出函數。其中,dllStartPlugin負責創建插件實例,并調用 Root::installPlugin,將創建好的插件指針傳遞給Root對象。在這里,dllStartPlugin實際可以創建多個插件實例,并依次調用Root::installPlugin,這樣我們就可以在一個DLL中包含多個插件了。在dllStopPlugin時,則需要調用 Root::uninstallPlugin,并將插件DLL中創建的plugin實例釋放掉。

 

一個典型的dllStartPlugin的實現像這樣:

 

class D3D9Plugin : public Plugin

{

         
//

};

 

D3D9Plugin
* plugin;

__declspec(dllexport) 
extern “C”

void dllStrartPlugin(void)

{

         plugin 
= new D3D9Plugin();

         Root::getSingleton().installPlugin(plugin);

}

 

__declspec(dllexport) 
extern “C”

void dllStopPlugin(void)

{

Root::getSingleton().uninstallPlugin(plugin);

delete plugin;

}

 

Root::getSingleton().installPlugin(plugin)會負責調用插件的install以及initialise操作,并將插件的指針存放起來,以備卸載時使用。

 

Plugin::install以及Plugin::initialise則分別負責創建OgreMain提供擴展功能接口的實例,以及將創建好的對象掛載到應用程序當中。

 

一個典型的Plugin的行為像這樣:

 

void BspSceneManagerPlugin::install()

{

         mBspFactory 
= new BspSceneManagerFactory();

}

 

void BspSceneManagerPlugin::initialise()

{

         Root::getSingleton().addSceneManagerFactory(mBspFactory);

}

 

其中,BspSceneManagerFactory是繼承自OgreMain中的SceneManagerFactory的派生類。

class BspSceneManagerFactory : public SceneManagerFactory {…} )

 

通過將場景管理器工廠添加到Root對象當中,插件動態的將其功能添加到了OgreMain當中。

 

PS: SceneManagerFactory是一個用于創建SceneManager的工廠。SceneManager則是被用于場景管理的管理器。具體的 SceneManager也根據算法不同而不同,Ogre自帶提供了兩種類型的場景管理算法插件:Bsp以及Octree(實現了兩個對應的插件,分別是 Plugin_BSPSceneManager以及Plugin_OctreeSceneManager)。

 

通過上述方式,OgreMain核心引擎并不需要關心場景管理算法的具體實現,不需要關心渲染子系統的具體實現,不需要關心粒子系統的具體實現,等等。一切這些擴展性的功能都通過插件實現,并在加載時動態掛載到OgreMain當中,供OgreMain的引擎核心使用。

 

使用插件時幾個需要注意的地方:

1,  調用插件DLL方法創建的對象需要交由插件DLL釋放。(因為不同的鏈接單元可能具有不同的內存管理上下文環境,此處的new與彼處的new在語義上未必等同)

2,  調用插件DLL方法獲取的插件內對象的引用或指針,在插件DLL卸載之后就是無效的,必須保證不再使用。(比較容易引發問題的一個典型例子是從插件中傳遞回一個引用計數字符串,當DLL被卸載后,字符串內指向實際數據的指針已經無效,但是在該對象析構時,仍需要訪問該指針)

posts - 94, comments - 138, trackbacks - 0, articles - 94

Copyright © RichardHe

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            噜噜噜在线观看免费视频日韩| 野花国产精品入口| 国产麻豆日韩| 一区二区三区四区精品| 欧美sm视频| 久久男人资源视频| 激情成人综合网| 老司机久久99久久精品播放免费| 亚洲欧美日韩网| 国产日韩欧美| 久久亚洲一区二区| 久久久噜噜噜久久中文字免| 国产综合色一区二区三区| 先锋影音国产精品| 亚洲图中文字幕| 国产农村妇女精品一区二区| 欧美一区二区三区视频免费播放| 亚洲私人影院在线观看| 国产欧美高清| 久久综合网络一区二区| 久久亚洲风情| 在线一区二区三区做爰视频网站| 亚洲欧洲综合另类| 欧美精品三区| 亚洲欧美日韩一区二区| 欧美一区二区三区久久精品茉莉花| 很黄很黄激情成人| 亚洲国产影院| 国产精品热久久久久夜色精品三区| 欧美一区二区三区四区高清| 欧美亚洲综合在线| 91久久在线观看| 在线视频一区观看| 国语精品中文字幕| 亚洲人成网站色ww在线| 国产精品久久久久影院亚瑟 | 欧美电影资源| 欧美女人交a| 久久精品青青大伊人av| 欧美高潮视频| 久久精品一二三| 欧美激情四色 | 欧美三级在线视频| 久久精品国产久精国产爱| 免费成人黄色片| 亚洲午夜久久久久久尤物 | 欧美精彩视频一区二区三区| 亚洲一区二区三区精品动漫| 久久国产精彩视频| 亚洲午夜影视影院在线观看| 久久影院午夜论| 香蕉成人伊视频在线观看| 麻豆精品在线播放| 欧美一级在线视频| 欧美久久影院| 久久免费精品视频| 国产精品久久久久久一区二区三区| 免费在线国产精品| 国产拍揄自揄精品视频麻豆| 亚洲美女在线视频| 亚洲欧洲久久| 久久国产精品第一页| 亚洲一区二区网站| 欧美激情a∨在线视频播放| 久久久最新网址| 国产精品色午夜在线观看| 亚洲高清久久久| 一区在线免费观看| 午夜精品电影| 亚洲欧美日韩精品在线| 欧美人与禽性xxxxx杂性| 欧美成人亚洲成人日韩成人| 国产亚洲欧美激情| 午夜伦欧美伦电影理论片| 亚洲色在线视频| 欧美激情久久久久| 亚洲国产另类 国产精品国产免费| 黄色一区三区| 久久九九精品| 久久亚洲综合网| 亚洲黄色尤物视频| 欧美日韩另类在线| 亚洲高清精品中出| 亚洲国产成人久久综合一区| 久久激情综合| 久久久夜精品| 狠狠色丁香婷婷综合久久片| 午夜在线观看免费一区| 性做久久久久久| 国产精品久久久久9999高清| 日韩一区二区久久| 亚洲欧美第一页| 国产精品卡一卡二| 亚洲男女毛片无遮挡| 国内综合精品午夜久久资源| 欧美专区在线观看| 国产精品推荐精品| 午夜精品免费在线| 久久精品99无色码中文字幕| 国产一区二区日韩| 久久亚洲综合| 亚洲精品一区在线| 亚洲免费伊人电影在线观看av| 国产精品香蕉在线观看| 鲁鲁狠狠狠7777一区二区| 亚洲国产欧美一区| 99re国产精品| 亚洲剧情一区二区| 亚洲欧美日韩国产中文 | 国产亚洲一区二区三区在线播放| 亚洲视频一区二区免费在线观看| 亚洲欧美日本国产有色| 国产精品一区免费观看| 欧美在线观看网址综合| 欧美www视频| 亚洲手机视频| 国产在线不卡| 欧美剧在线观看| 亚洲欧美视频一区二区三区| 久久久久久久欧美精品| 91久久嫩草影院一区二区| 国产精品www994| 久久国产福利国产秒拍| 亚洲黄一区二区三区| 亚洲欧美中文日韩在线| 精品96久久久久久中文字幕无| 国产欧美韩日| 狠狠操狠狠色综合网| 精品成人国产在线观看男人呻吟| 久久一区二区三区超碰国产精品| 国产精品日韩久久久| 欧美一区二区三区电影在线观看| 欧美gay视频| 香蕉久久夜色精品国产使用方法| 一区二区在线视频| 欧美先锋影音| 美女国产精品| 午夜视频精品| 日韩视频在线观看一区二区| 久久久99国产精品免费| 中文日韩在线| 亚洲精品国产精品乱码不99按摩 | 国产精品女人久久久久久| 久久婷婷国产综合国色天香| 一区二区三区导航| 蜜桃av一区二区在线观看| 老司机67194精品线观看| 麻豆精品在线播放| 欧美视频在线观看 亚洲欧| 可以看av的网站久久看| 国产精品久久二区| 美女精品在线| 香蕉久久a毛片| 日韩视频一区二区三区| 麻豆精品网站| 欧美影院视频| 亚洲伊人网站| 一区二区三区高清在线| 国一区二区在线观看| 国产精品呻吟| 国产精品久久久久久久一区探花| 欧美国产日韩视频| 久久婷婷国产麻豆91天堂| 亚洲欧美日本视频在线观看| 亚洲免费观看| 日韩视频一区二区三区| 日韩视频免费观看高清在线视频| 一区二区在线观看av| 亚洲欧美日韩一区二区三区在线观看 | 久久久久久久一区| 欧美中文在线观看| 欧美一级黄色网| 亚洲欧美日韩精品综合在线观看| 中文精品一区二区三区| 一区二区三区欧美日韩| 99综合精品| 亚洲图片欧美一区| 亚洲欧美日韩精品| 欧美一区二区三区视频| 香蕉久久夜色精品国产| 久久精品99| 乱码第一页成人| 欧美激情视频在线播放| 亚洲国产欧美在线| 亚洲欧洲日本mm| 91久久视频| 一本色道久久综合亚洲91| 亚洲一区二区不卡免费| 欧美亚洲午夜视频在线观看| 久久久99久久精品女同性| 麻豆av一区二区三区| 欧美激情精品久久久久久变态 | 亚洲一区免费视频| 香蕉尹人综合在线观看| 久久久久久电影| 亚洲国产日韩欧美在线动漫| 99re6热只有精品免费观看| 亚洲图片欧美日产| 久久久91精品国产一区二区三区 | 国内自拍视频一区二区三区|