




















































Read more about this book |
(For more resources on this subject, see here.)
When a scene is rendered, it isn't normally rendered directly to the buffer, which is displayed on the monitor. Normally, the scene is rendered to a second buffer and when the rendering is finished, the buffers are swapped. This is done to prevent some artifacts, which can be created if we render to the same buffer, which is displayed on the monitor. The FrameListener function, frameRenderingQueued, is called after the scene has been rendered to the back buffer, the buffer which isn't displayed at the moment. Before the buffers are swapped, the rendering result is already created but not yet displayed. Directly after the frameRenderingQueued function is called, the buffers get swapped and then the application gets the return value and closes itself. That's the reason why we see an image this time.
Now, we will see what happens when frameRenderingQueued also returns true.
Once again we modify the code to test the behavior of the Frame Listener
bool frameRenderingQueued (const Ogre::FrameEvent& evt)
{
std::cout << «Frame queued» << std::endl;
return true;
}
Now that the frameRenderingQueued handler returns true, it will let Ogre 3D continue to render until the frameEnded handler returns false.
Like in the last example, the render buffers were swapped, so we saw the scene for a short period of time. After the frame was rendered, the frameEnded function returned false, which closes the application and, in this case, doesn't change anything from our perspective.
Now let's test the last of three possibilities.
bool frameEnded (const Ogre::FrameEvent& evt)
{
std::cout << «Frame ended» << std::endl;
return true;
}
Now, all event handlers returned true and, therefore, the application will never be closed; it would run forever as long as we aren't going to close the application ourselves.
We have an application running forever and have to force it to close; that's not neat. Let's add input and the possibility to close the application by pressing Escape.
Now that we know how the FrameListener works, let's add some input.
#include "OISOIS.h"
OIS::InputManager* _InputManager;
OIS::Keyboard* _Keyboard;
MyFrameListener(Ogre::RenderWindow* win)
{
OIS::ParamList parameters;
unsigned int windowHandle = 0;
std::ostringstream windowHandleString;
win->getCustomAttribute("WINDOW", &windowHandle);
windowHandleString << windowHandle;
parameters.insert(std::make_pair("WINDOW", windowHandleString.
str()));
_InputManager = OIS::InputManager::createInputSystem(parameters);
_Keyboard = static_cast<OIS::Keyboard*>(_InputManager-
>createInputObject( OIS::OISKeyboard, false ));
~MyFrameListener()
{
_InputManager->destroyInputObject(_Keyboard);
OIS::InputManager::destroyInputSystem(_InputManager);
}
bool frameStarted(const Ogre::FrameEvent& evt)
{
_Keyboard->capture();
if(_Keyboard->isKeyDown(OIS::KC_ESCAPE))
{
return false;
}
return true;
}
_listener = new MyFrameListener(window);
_root->addFrameListener(_listener);
We added input processing capabilities to our FrameListener but we didn't use any example classes, except our own versions.