编写Ogre插件的一般方法
轉載請注明出處!Pulas
?http://www.cnblogs.com/pulas/archive/2012/02/18/2357663.html
?
??????? Ogre的插件可以是動態鏈接庫,也可以是靜態鏈接庫。若是動態鏈接庫,則可通過在插件配置文件(默認為plugins.cfg)里添加插件名稱,然后在創建Root時,會在Root的構造函數里通過Root::loadPlugin(const String& pluginName)方法遍歷加載每一個插件。也可通過Root::loadPlugin(const String& pluginName)方法手動加載自定義插件。
??????? 當Root::loadPlugin(const String& pluginName)函數被調用時,Ogre將加載該插件的dll,并從中查找并調用名為dllStartPlugin()的導出函數。對應的,當Root::unloadPlugin(const String& pluginName)函數被調用時,Ogre將從該dll中調用dllStopPlugin()函數,并將該dll卸載。所以每個插件在實現的時候,都必須提供上述的兩個C導出函數。其中,dllStartPlugin()負責創建插件實例,并調用Root::installPlugin(),將創建好的插件指針傳遞給Root對象。在這里,dllStartPlugin()實際可以創建多個插件實例,并依次調用Root::installPlugin(),這樣我們就可以在一個dll中包含多個插件了。在dllStopPlugin()時,則需要調用 Root::uninstallPlugin(),并將插件dll中創建的plugin實例釋放掉。所以,若要實現一個四叉樹的場景管理器插件,則必須先實現這兩個C導出函數。
?
#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 )函數中創建自定義插件。Ogre定義了一個抽象的Plugin插件接口,每一個插件都必須實現該插件接口。
?
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)會負責調用插件的install()操作,并將插件的指針存放起來,以備卸載時使用。Root::initialise()會負責調用插件的initialise()操作。
Plugin::install()以及Plugin::initialise()則分別負責創建OgreMain提供擴展功能接口的實例,以及將創建好的對象掛載到應用程序當中。
Root:: shutdown()會負責調用插件的shutdown()操作。Root::getSingleton().uninstallPlugin(plugin)會負責調用插件的uninstall()操作。
?
使用插件時幾個需要注意的地方:
1. 調用插件DLL方法創建的對象需要交由插件DLL釋放。(因為不同的鏈接單元可能具有不同的內存管理上下文環境,此處的new與彼處的new在語義上未必等同)
2. 調用插件DLL方法獲取的插件內對象的引用或指針,在插件DLL卸載之后就是無效的,必須保證不再使用。(比較容易引發問題的一個典型例子是從插件中傳遞回一個引用計數字符串,當DLL被卸載后,字符串內指向實際數據的指針已經無效,但是在該對象析構時,仍需要訪問該指針)
?
若插件是靜態鏈接庫,則可在任何時候創建插件,然后在創建Root后,調用Root::installPlugin(plugin)安裝插件。手動調用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.
?
轉載于:https://www.cnblogs.com/pulas/archive/2012/02/18/2357663.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的编写Ogre插件的一般方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VC++控制台程序中使用定时器
- 下一篇: ubuntu server 10.04