History: Creating A Plugin DLL
Source of version: 6 (current)
Copy to clipboard
{maketoc}
!!Ogre Plugins Described
Plugins can be used for many purposes but the most useful purpose is to register class factories into an existing system. This [http://en.wikipedia.org/wiki/Factory_method_pattern|wikipedia article] explains this factory medthod pattern. Ogre itself uses factories for many things, including ((-SceneManager|SceneManagers)) and MovableObjects.
When ''Ogre::Root'' is created by your application, it reads the ''plugins.cfg'' file from the same directory the .exe is running from to get a list of DLL names that it will attempt to load. Ogre reads the DLL and gets the address of a function named "dllStartPlugin" and calls it if it exists.
When dllStartPlugin is called, the DLL itself should call ''Ogre::Root::getSingleton().installPlugin(Plugin*)'' to register an instance of a class that derives from ''Ogre::Plugin'' into Ogre's list of plugins. At this point, Ogre will then call various functions on the Plugin instance, such as ''Plugin::install()'', ''Plugin::intialise()'', ''Plugin::shutdown()'' and ''Plugin::uninstall()''.
Ogre will call ''install()'' immediately when it receives the ''Root::installPlugin(Plugin*)'' call, and ''initialise()'' after the Window that Ogre is hosted in is created. Then it'll call ''shutdown()'' and then ''uninstall()'' when Root is deleted.
When ''install()'' is called, the plugin will typically instantiate its member variables, such as a class factory. When ''initialise()'' is called, the plugin will typically register the class factories with the appropriate system using a singleton. When ''shutdown()'' is called, the plugin will typically unregister the class factory from the appropriate system, and when ''uninstall()'' is called the plugin will typically delete the class factory instance.
It's always a good idea to look at existing full examples inside Ogre to see how they are done. In this case, a good thing to look at is Plugin_BSPSceneManager project, specifically the OgreBspSceneManagerPlugin.h and .cpp files, and the OgreBspSceneManagerDll.cpp files which were used as a basis for this tutorial.
!Creating a Plugin using Visual Studio
Create a new DLL project in Visual Studio called "MyPlugin" and set up the appropriate header and LIB directories to Ogre. I'm not going to go into the details of how to do this, see other wiki tutorials for how it's done.
Create a new class which derives from Plugin, for example called MyPlugin.
Create a header file called
!!!MyPluginPrerequisites.h
{CODE(wrap="1", colors="c++")}#ifndef __MyPluginPrerequisites_H__
#define __MyPluginPrerequisites_H__
#include <OgrePrerequisites.h>
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
# ifdef MYPLUGIN_EXPORTS
# define _MyPluginExport __declspec(dllexport)
# else
# define _MyPluginExport __declspec(dllimport)
# endif
#else
# define _MyPluginExport
#endif
#endif
{CODE}
!!!MyPlugin.h
{CODE(wrap="1", colors="c++")}#include "MyPluginPrerequisites.h"
#include <Ogre.h>
#include <OgrePlugin.h>
using namespace Ogre;
class MyPlugin : public Plugin
{
public:
MyPlugin();
const String& getName() const;
void install();
void initialise();
void shutdown();
void uninstall();
};
{CODE}
!!!MyPlugin.cpp
{CODE(wrap="1", colors="c++")}#include "MyPlugin.h"
const String sPluginName = "MyPlugin";
//---------------------------------------------------------------------
MyPlugin::MyPlugin() : mLODGameSystemFactory(0)
{
}
//---------------------------------------------------------------------
const String& MyPlugin::getName() const
{
return sPluginName;
}
//---------------------------------------------------------------------
void MyPlugin::install()
{
//install called - create stuff here
}
//---------------------------------------------------------------------
void MyPlugin::initialise()
{
//intialise called - register stuff here
}
//---------------------------------------------------------------------
void MyPlugin::shutdown()
{
//shutdown called - unregister stuff here
}
//---------------------------------------------------------------------
void MyPlugin::uninstall()
{
//uninstall called - delete stuff here
}
{CODE}
!!!MyPluginDLL.cpp
Finally create a file called ''MyPluginDLL.cpp'' that looks like this:
{CODE(wrap="1", colors="c++")}#include "MyPlugin.h"
#include <OgreRoot.h>
//global variable
MyPlugin* myPlugin;
//-----------------------------------------------------------------------
extern "C" void _MyPluginExport dllStartPlugin(void)
{
// Create plugin
myPlugin = new MyPlugin();
// Register
Ogre::Root::getSingleton().installPlugin(myPlugin);
}
extern "C" void _MyPluginExport dllStopPlugin(void)
{
Ogre::Root::getSingleton().uninstallPlugin(myPlugin);
delete myPlugin;
}
{CODE}
!Configuring the Plugin
The project should compile into a DLL named MyPlugin.dll. Add an entry to ''Plugins.cfg'' with the following line:
{MONO()}Plugin=MyPlugin{MONO}
If that MyPlugin.dll is in the same folder as Ogre when it starts up, it will load up the plugin.
!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:
{CODE(wrap="1", colors="c++")}class GameObject
{
void tick(float deltaTime);
};
{CODE}
Class factory that creates GameObjects:
{CODE(wrap="1", colors="c++")}class GameObjectFactory
{
virtual bool supportsGameObjectType(const String& objectType) = 0;
virtual GameObject* createGameObject(const String& objectType) = 0;
};{CODE}
A manager that we can register factories with that will be used to create game objects:
{CODE(wrap="1", colors="c++")}class GameObjectFactoryManager : public Singleton<GameObjectFactoryManager>
{
void registerGameObjectFactory(GameObjectFactory* factory)
{
//add factory to an array
}
void unregisterGameObjectFactory(GameObjectFactory* factory)
{
//find and remove factory from mFactories
}
GameObject* createGameObject(const String& objectType)
{
//find a factory that supports this object type and then call createGameObject() on it
}
};{CODE}
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 calls ''GameObjectFactoryManager::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.
---
Alias: (alias(CreatingAPluginDLL))