OGRE 1 7 例子程式分析

2021-05-23 06:46:06 字數 4108 閱讀 4117

如果你自己都不清楚所談論的東西,就根本不可能精確的描述它——馮諾依曼

今天我就試著來表述一件眾人皆知的事情,以測試自己到底有沒有明白這件事情。

ogre是著名的設計模式大師,這已是不爭的事實。可以說ogre裡將設計模式用得淋漓盡致。 在這裡我就不批判設計模式該不該用了。反正ogre已經用了,並且沒有出現什麼不好的結果。適合的就是最好的,ogre證明了這一點。

隨著ogre  1.7的發布,大家熟悉的demo程式不見了,換來的是乙個個的dll庫。 而這些庫,就是作為ogre的乙個外掛程式而存在。 拿skybox為例,(不要問為什麼拿skybox,如果真要知道 ,我只能說,我剛好看上它了。)我們可以在skybox.cpp裡發現如下**。

sampleplugin* sp;

sample* s;

extern "c" _ogresampleexport void dllstartplugin()

s = new sample_skybox;

sp = ogre_new sampleplugin(s->getinfo()["title"] + " sample");

sp->addsample(s);

root::getsingleton().installplugin(sp);

extern "c" _ogresampleexport void dllstopplugin()

root::getsingleton().uninstallplugin(sp);

ogre_delete sp;

delete s;

dllstartplugin  和 dllstopplugin 是外掛程式的載入和解除安裝介面。 可以看到,當呼叫dllstartplugin 時,它先新建了乙個sample_skybox例項,這就是我們真正的示例程式。緊接著,它又新建了乙個外掛程式。外掛程式的名字則以例項的title資訊加上sample來標誌。 隨後,這個示例程式的例項被加入外掛程式中,然後呼叫root::getsingleton().installplugin(sp);函式初始化我們的外掛程式。

顯然,我們需要看看installplugin幹了些什麼。

void root::installplugin(plugin* plugin)

logmanager::getsingleton().logmessage("installing plugin: " + plugin->getname());

mplugins.push_back(plugin);

plugin->install();

// if rendersystem is already initialised, call rendersystem init too

if (misinitialised)

plugin->initialise();

logmanager::getsingleton().logmessage("plugin successfully installed");

不難看出,ogre在 這個函式中將外掛程式加入了自己的外掛程式容器中,並呼叫外掛程式的初始化介面。以及輸出相關log資訊。

而又是在何時呼叫這個dllstartplugin來載入外掛程式的呢。 我們開啟samplebrowser.h找到virtual sample* loadsamples()函式。在這個函式中的前幾句便 反應了它所做的工作。

sample* startupsample = 0;

ogre::stringvector unloadedsampleplugins;

ogre::configfile cfg;

cfg.load(mfslayer->getconfigfilepath("samples.cfg"));

ogre::string sampledir = cfg.getsetting("samplefolder");        // mac os x just uses resources/ directory

ogre::stringvector samplelist = cfg.getmultisetting("sampleplugin");

ogre::string startupsampletitle = cfg.getsetting("startupsample");

samplefolder=.

sampleplugin=sample_bezierpatch_d

sampleplugin=sample_bsp_d

sampleplugin=sample_cameratrack_d

sampleplugin=sample_celshading_d

sampleplugin=sample_character_d

sampleplugin=sample_compositor_d

sampleplugin=sample_deferredshading_d

這些正好是我們的例子外掛程式的dll檔名。 loadsamples函式在讀取了這些資訊後,將其放入 stringvector samplelist 中,然後依次遍歷這個容器,並呼叫外掛程式載入函式。 **如下

// loop through all sample plugins...

for (ogre::stringvector::iterator i = samplelist.begin(); i != samplelist.end(); i++)

mroot->loadplugin(sampledir + *i);

按照我們分析問題的方案(我們總是從程式的行為進行跟蹤分析)。於是我們看看loadplugin函式做了些什麼。

void root::loadplugin(const string& pluginname)

//根據名字載入動態庫

dynlib* lib = dynlibmanager::getsingleton().load( pluginname );

//查詢是否已經載入,如果沒有存在,則加入其中。並且取得入口函式並執行。

if (std::find(mpluginlibs.begin(), mpluginlibs.end(), lib) == mpluginlibs.end())

mpluginlibs.push_back(lib);

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");

pfunc();//執行dllstartplugin( )

此時我們會考慮,如果我們想要新增乙個例子,應該如何去做? 於是,我們需要先看看sample_skybox 以及sampleplugin.

開啟sample_skybox.h 我們便會看到

class _ogresampleclas***port sample_skybox : public sdksample

protected:

void setupcontent()

//實現**

上面**說明了,sample_skybox繼承自sdksample,並且實現了setupcontent函式。

我們再開啟sampleplugin可以看到有些空函式,說明在我們的例子中,sampleplugin並沒有做太多的初始化工作。 於是,我們得到如下的關係

1、      sample_skybox派生自sdksample

2、      sampleplugin派生自plugin

3、      sampleplugin持有sample_skybox例項指標

4、      sampleplugin會註冊到root的外掛程式管理中

5、      sample_skybox應該被加入到samples_d.cfg中。

於是,我們可以看到,如果我們想實現乙個簡單的例子。則只需要自sdksample派生乙個實現類,並至少實現setupcontent函式。然後學著sample_skybox的樣子寫好dllstartplugin和dllstopplugin函式,並匯出成dll,然後將dll名字新增到smaples_d.cfg中。

以上描述均是debug版本下。如果是release,則去掉後面的_d即可。

OGRE 1 7 例子程式分析

如果你自己都不清楚所談論的東西,就根本不可能精確的描述它 馮諾依曼 今天我就試著來表述一件眾人皆知的事情,以測試自己到底有沒有明白這件事情。ogre 是著名的設計模式大師,這已是不爭的事實。可以說 ogre 裡將設計模式用得淋漓盡致。在這裡我就不批判設計模式該不該用了。反正 ogre 已經用了,並且...

ogre1 7中文路徑bug處理

ogre1.7在編譯完成後,執行例子時,在完成配置介面後,會出現乙個錯誤對話方塊 顯示ogreroot.cpp line 382 錯誤。經過除錯發現,ogre要向 我的文件 寫ogre的配置資訊,就是配置介面中設定的資訊,而在本人的電腦上,我的文件 這個資料夾的路徑是 d backup 我的文件 若...

多型(二) 例子

有乙個動物類,1.0版本只有吃 睡得方法。而1.1時代動物類就有了很多子類,這些子類都有他們各自吃睡得方法,但是行為跟父類是一樣的,屬於方法的過載。因為動物太多了,我可以每次都去建立物件,但是每次呼叫物件的方法都是相同的過程,所以1.2時代,我可以把這個過程抽取出來,放在另外乙個工具類中,把我每次呼...