编写Ogre插件的一般方法
轉(zhuǎn)載請(qǐng)注明出處!Pulas
?http://www.cnblogs.com/pulas/archive/2012/02/18/2357663.html
?
??????? Ogre的插件可以是動(dòng)態(tài)鏈接庫,也可以是靜態(tài)鏈接庫。若是動(dòng)態(tài)鏈接庫,則可通過在插件配置文件(默認(rèn)為plugins.cfg)里添加插件名稱,然后在創(chuàng)建Root時(shí),會(huì)在Root的構(gòu)造函數(shù)里通過Root::loadPlugin(const String& pluginName)方法遍歷加載每一個(gè)插件。也可通過Root::loadPlugin(const String& pluginName)方法手動(dòng)加載自定義插件。
??????? 當(dāng)Root::loadPlugin(const String& pluginName)函數(shù)被調(diào)用時(shí),Ogre將加載該插件的dll,并從中查找并調(diào)用名為dllStartPlugin()的導(dǎo)出函數(shù)。對(duì)應(yīng)的,當(dāng)Root::unloadPlugin(const String& pluginName)函數(shù)被調(diào)用時(shí),Ogre將從該dll中調(diào)用dllStopPlugin()函數(shù),并將該dll卸載。所以每個(gè)插件在實(shí)現(xiàn)的時(shí)候,都必須提供上述的兩個(gè)C導(dǎo)出函數(shù)。其中,dllStartPlugin()負(fù)責(zé)創(chuàng)建插件實(shí)例,并調(diào)用Root::installPlugin(),將創(chuàng)建好的插件指針傳遞給Root對(duì)象。在這里,dllStartPlugin()實(shí)際可以創(chuàng)建多個(gè)插件實(shí)例,并依次調(diào)用Root::installPlugin(),這樣我們就可以在一個(gè)dll中包含多個(gè)插件了。在dllStopPlugin()時(shí),則需要調(diào)用 Root::uninstallPlugin(),并將插件dll中創(chuàng)建的plugin實(shí)例釋放掉。所以,若要實(shí)現(xiàn)一個(gè)四叉樹的場(chǎng)景管理器插件,則必須先實(shí)現(xiàn)這兩個(gè)C導(dǎo)出函數(shù)。
?
#include <OgreRoot.h> #include <QuadtreePlugin.h>#ifndef OGRE_STATIC_LIBnamespace Ogre { QuadtreePlugin* quadtreePlugin;extern "C" void _QuadtreePluginExport dllStartPlugin( void ) {// Create new scene managerquadtreePlugin = OGRE_NEW QuadtreePlugin();// RegisterRoot::getSingleton().installPlugin(quadtreePlugin); } extern "C" void _QuadtreePluginExport dllStopPlugin( void ) {Root::getSingleton().uninstallPlugin(quadtreePlugin);OGRE_DELETE quadtreePlugin; } }#endif?
?
在上述dllStartPlugin( void )函數(shù)中創(chuàng)建自定義插件。Ogre定義了一個(gè)抽象的Plugin插件接口,每一個(gè)插件都必須實(shí)現(xiàn)該插件接口。
?
class _OgreExport Plugin : public PluginAlloc{public:Plugin() {}virtual ~Plugin() {}/** Get the name of the plugin. @remarks An implementation must be supplied for this method to uniquelyidentify the plugin.*/virtual const String& getName() const = 0;/** Perform the plugin initial installation sequence. @remarks An implementation must be supplied for this method. It must performthe startup tasks necessary to install any rendersystem customisations or anything else that is not dependent on system initialisation, ieonly dependent on the core of Ogre. It must not perform anyoperations that would create rendersystem-specific objects at this stage,that should be done in initialise().*/virtual void install() = 0;/** Perform any tasks the plugin needs to perform on full systeminitialisation.@remarks An implementation must be supplied for this method. It is called just after the system is fully initialised (either after Root::initialiseif a window is created then, or after the first window is created)and therefore all rendersystem functionality is available at thistime. You can use this hook to create any resources which are dependent on a rendersystem or have rendersystem-specific implementations.*/virtual void initialise() = 0;/** Perform any tasks the plugin needs to perform when the system is shut down.@remarks An implementation must be supplied for this method.This method is called just before key parts of the system are unloaded, such as rendersystems being shut down. You should use this hook to free up resources and decouple custom objects from the OGRE system, whilst all theinstances of other plugins (e.g. rendersystems) still exist.*/virtual void shutdown() = 0;/** Perform the final plugin uninstallation sequence. @remarks An implementation must be supplied for this method. It must performthe cleanup tasks which haven't already been performed in shutdown()(e.g. final deletion of custom instances, if you kept them around incasethe system was reinitialised). At this stage you cannot be sure what otherplugins are still loaded or active. It must therefore not perform anyoperations that would reference any rendersystem-specific objects - thoseshould have been sorted out in the 'shutdown' method.*/virtual void uninstall() = 0;};?
Root::getSingleton().installPlugin(plugin)會(huì)負(fù)責(zé)調(diào)用插件的install()操作,并將插件的指針存放起來,以備卸載時(shí)使用。Root::initialise()會(huì)負(fù)責(zé)調(diào)用插件的initialise()操作。
Plugin::install()以及Plugin::initialise()則分別負(fù)責(zé)創(chuàng)建OgreMain提供擴(kuò)展功能接口的實(shí)例,以及將創(chuàng)建好的對(duì)象掛載到應(yīng)用程序當(dāng)中。
Root:: shutdown()會(huì)負(fù)責(zé)調(diào)用插件的shutdown()操作。Root::getSingleton().uninstallPlugin(plugin)會(huì)負(fù)責(zé)調(diào)用插件的uninstall()操作。
?
使用插件時(shí)幾個(gè)需要注意的地方:
1. 調(diào)用插件DLL方法創(chuàng)建的對(duì)象需要交由插件DLL釋放。(因?yàn)椴煌逆溄訂卧赡芫哂胁煌膬?nèi)存管理上下文環(huán)境,此處的new與彼處的new在語義上未必等同)
2. 調(diào)用插件DLL方法獲取的插件內(nèi)對(duì)象的引用或指針,在插件DLL卸載之后就是無效的,必須保證不再使用。(比較容易引發(fā)問題的一個(gè)典型例子是從插件中傳遞回一個(gè)引用計(jì)數(shù)字符串,當(dāng)DLL被卸載后,字符串內(nèi)指向?qū)嶋H數(shù)據(jù)的指針已經(jīng)無效,但是在該對(duì)象析構(gòu)時(shí),仍需要訪問該指針)
?
若插件是靜態(tài)鏈接庫,則可在任何時(shí)候創(chuàng)建插件,然后在創(chuàng)建Root后,調(diào)用Root::installPlugin(plugin)安裝插件。手動(dòng)調(diào)用Root::uninstallPlugin(plugin)卸載插件。
?
可以參考Ogre Wiki上的教程:
http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Creating+A+Plugin+DLL
Final Thoughts
??
It's up to you to do what you want inside the plugin, and keep in mind that it can be used to create plugins for your own game or application specific purposes. For example, in my game engine and editor most major pieces of functionality are loaded as plugins, including game objects, game systems, scene partitions, tool plugins for the editor, etc. All you need to do is have a clear set of base classes, a factory and a factory manager.
For example a simplified Factory system:
GameObject class in the plugin:
class GameObject {void tick(float deltaTime); };??
Class factory that creates GameObjects?in the plugin:
??
A manager class (in the game) that we can register factories with that will be used to create game objects:
??
You could now create new classes that derive from GameObject, such as MeshGameObject, and a factory that creates those objects such as MeshGameObjectFactory, and have your application create a GameObjectFactoryManager at startup. Then have a plugin that callsGameObjectFactoryManager::getSingleton().registerGameObjectFactory(meshGameObjectFactory)?during its?initialise()?call. Then from your game you can now create instances of new MeshGameObjects dynamically without ever having linked to the DLL.
?
轉(zhuǎn)載于:https://www.cnblogs.com/pulas/archive/2012/02/18/2357663.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的编写Ogre插件的一般方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VC++控制台程序中使用定时器
- 下一篇: js动态改变下拉菜单内容示例 .