Up until now, we only had one class, namely, ExampleApplication
. This time we need another one:
- Create a new class, name it
Example25FrameListener
, and let it inherit publicly fromOgre::FrameListener:
class Example25FrameListener : public Ogre::FrameListener { };
- Add a private member variable, which is an
Ogre::SceneNode
pointer, and name it_node:
private: Ogre::SceneNode* _node;
- Add a public constructor that takes an
Ogre::SceneNode
pointer as a parameter and assigns it to the member node pointer:public: Example25FrameListener(Ogre::SceneNode* node) { _node = node; }
- Add a new function called
frameStarted(FrameEvent & evt)
, which translates the member node with (0,0,0.1) and then returnstrue:
bool frameStarted(const Ogre::FrameEvent &evt) { _node->translate(Ogre::Vector3(0.1,0,0)); return true; }
- Add a new member variable to hold the pointer to the
FrameListener
, which we will create later:Ogre::FrameListener* FrameListener;
- Add a constructor which inits the pointer with
NULL
and a destructor which destroys theFrameListener
when the application is closed:Example25() { FrameListener = NULL; } ~Example25() { if(FrameListener) { delete FrameListener; } }
- Now create a new function in
ExampleApplication
calledcreateFrameListener
. In this function, create an instance of theFrameListener
we defined and add it usingmRoot:
void createFrameListener() { FrameListener = new Example25FrameListener(_SinbadNode); mRoot->addFrameListener(FrameListener); }
- Compile and run the application. You should see the same scene as seen earlier, but this time, the instance of Sinbad moves right and you can't move the camera or close the application with the Escape key. To close the application, click the X button on the console windows, or if you started the application from a console, you can use CTRL+C.
The new concept we have encountered here is the concept of FrameListeners
. As the name suggests, a FrameListener
is based on the observer pattern. We can add a class instance which inherits from the Ogre::FrameListener
interface to our Ogre 3D root instance using the addFrameListener()
method of Ogre::Root
. When this class instance is added, our class gets notified when certain events happen. In this example, we overrode the frameStarted()
method. Before a frame (by frame, we mean a single picture of the scene) is rendered, Ogre::Root
iterates over all added FrameListeners
and calls the frameStarted()
method of each one. In our implementation (see step 4) of this function, we translated the node 0.1 units on the x-axis. This node was passed to the Framelistener
in its constructor. Therefore, each time the scene is rendered, the node is translated a bit, and as a result, the model moves.
As we have seen during the running of the application, we can't move our camera or exit our application using the Escape key. This is because these things were done by the FrameListener
, which comes with the ExampleApplication
framework. The ExampleApplication
framework comes with the SDK. Now that we have replaced it with our own implementation, we can't use the functions the FrameListener
offers any longer. But we will reimplement most of them in this chapter, so no worries. If needed, we could still call the functions of the base class to get our default behavior back.
In step 4, our function returns true
. If it returned false
, Ogre 3D would interpret this as a signal to drop out of the render loop, and with this, the application would be closed. We will use this fact to reimplement the "press Escape to exit the application" function.