Creating A Plugin DLL         This is a short example on how to create a plugin DLL that is loaded by Ogre at startup

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 wikipedia article explains this factory medthod pattern. Ogre itself uses factories for many things, including 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

#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

MyPlugin.h

#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();
};

MyPlugin.cpp

#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
}

MyPluginDLL.cpp

Finally create a file called MyPluginDLL.cpp that looks like this:

#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;
}

Configuring the Plugin

The project should compile into a DLL named MyPlugin.dll. Add an entry to Plugins.cfg with the following line:
Plugin=MyPlugin
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:

class GameObject
{
  void tick(float deltaTime);
};


Class factory that creates GameObjects:

class GameObjectFactory
{
  virtual bool supportsGameObjectType(const String& objectType) = 0;
  virtual GameObject* createGameObject(const String& objectType) = 0;
};


A manager that we can register factories with that will be used to create game objects:

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
  }
};


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: CreatingAPluginDLL