[Orxonox-commit 954] r5677 - in code/branches/resource3/src: core orxonox/gamestates
rgrieder at orxonox.net
rgrieder at orxonox.net
Mon Aug 24 15:03:45 CEST 2009
Author: rgrieder
Date: 2009-08-24 15:03:44 +0200 (Mon, 24 Aug 2009)
New Revision: 5677
Modified:
code/branches/resource3/src/core/Core.cc
code/branches/resource3/src/core/Core.h
code/branches/resource3/src/core/GraphicsManager.cc
code/branches/resource3/src/core/GraphicsManager.h
code/branches/resource3/src/orxonox/gamestates/GSLevel.cc
Log:
Merged most of revision 5614 and its fixes from revisions 5628, 5658, 5662 and 5670:
- Creating Ogre::Root in non graphics mode as well. This allows to always make use of the ResourceGroupManager.
- Switched to smart pointers for the destruction code in GraphicsManager
Modified: code/branches/resource3/src/core/Core.cc
===================================================================
--- code/branches/resource3/src/core/Core.cc 2009-08-24 11:57:27 UTC (rev 5676)
+++ code/branches/resource3/src/core/Core.cc 2009-08-24 13:03:44 UTC (rev 5677)
@@ -312,6 +312,9 @@
// creates the class hierarchy for all classes with factories
Factory::createClassHierarchy();
+
+ // Load OGRE excluding the renderer and the render window
+ this->graphicsManager_.reset(new GraphicsManager(false));
}
/**
@@ -324,38 +327,44 @@
void Core::loadGraphics()
{
- if (bGraphicsLoaded_)
- return;
+ // Any exception should trigger this, even in upgradeToGraphics (see its remarks)
+ Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics);
- // Load OGRE including the render window
- scoped_ptr<GraphicsManager> graphicsManager(new GraphicsManager());
+ // Upgrade OGRE to receive a render window
+ graphicsManager_->upgradeToGraphics();
// The render window width and height are used to set up the mouse movement.
size_t windowHnd = 0;
- graphicsManager->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd);
+ graphicsManager_->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd);
// Calls the InputManager which sets up the input devices.
- scoped_ptr<InputManager> inputManager(new InputManager(windowHnd));
+ inputManager_.reset(new InputManager(windowHnd));
// load the CEGUI interface
- guiManager_.reset(new GUIManager(graphicsManager->getRenderWindow()));
+ guiManager_.reset(new GUIManager(graphicsManager_->getRenderWindow()));
- // Dismiss scoped pointers
- graphicsManager_.swap(graphicsManager);
- inputManager_.swap(inputManager);
+ unloader.Dismiss();
bGraphicsLoaded_ = true;
}
void Core::unloadGraphics()
{
- if (!bGraphicsLoaded_)
- return;
-
this->guiManager_.reset();;
this->inputManager_.reset();;
this->graphicsManager_.reset();
+ // Load Ogre::Root again, but without the render system
+ try
+ { this->graphicsManager_.reset(new GraphicsManager(false)); }
+ catch (...)
+ {
+ COUT(0) << "An exception occurred during 'new GraphicsManager' while "
+ << "another exception was being handled. This will lead to undefined behaviour!" << std::endl
+ << "Terminating the program." << std::endl;
+ abort();
+ }
+
bGraphicsLoaded_ = false;
}
Modified: code/branches/resource3/src/core/Core.h
===================================================================
--- code/branches/resource3/src/core/Core.h 2009-08-24 11:57:27 UTC (rev 5676)
+++ code/branches/resource3/src/core/Core.h 2009-08-24 13:03:44 UTC (rev 5677)
@@ -65,6 +65,7 @@
{
typedef Loki::ScopeGuardImpl0<void (*)()> SimpleScopeGuard;
friend class Singleton<Core>;
+ friend class Game;
public:
/**
@@ -82,9 +83,6 @@
bool preUpdate(const Clock& time) throw();
bool postUpdate(const Clock& time) throw();
- void loadGraphics();
- void unloadGraphics();
-
static int getSoftDebugLevel(OutputHandler::OutputDevice device = OutputHandler::LD_All);
static void setSoftDebugLevel(OutputHandler::OutputDevice device, int level);
static const std::string& getLanguage();
@@ -113,6 +111,9 @@
private:
Core(const Core&); //!< Don't use (undefined symbol)
+ void loadGraphics();
+ void unloadGraphics();
+
void checkDevBuild();
void setExecutablePath();
void createDirectories();
Modified: code/branches/resource3/src/core/GraphicsManager.cc
===================================================================
--- code/branches/resource3/src/core/GraphicsManager.cc 2009-08-24 11:57:27 UTC (rev 5676)
+++ code/branches/resource3/src/core/GraphicsManager.cc 2009-08-24 13:03:44 UTC (rev 5677)
@@ -36,11 +36,8 @@
#include "GraphicsManager.h"
#include <fstream>
-#include <memory>
#include <boost/filesystem.hpp>
-#include <boost/shared_ptr.hpp>
-#include <OgreCompositorManager.h>
#include <OgreConfigFile.h>
#include <OgreFrameListener.h>
#include <OgreRoot.h>
@@ -48,7 +45,6 @@
#include <OgreException.h>
#include <OgreRenderWindow.h>
#include <OgreRenderSystem.h>
-#include <OgreTextureManager.h>
#include <OgreViewport.h>
#include <OgreWindowEventUtilities.h>
@@ -67,8 +63,6 @@
namespace orxonox
{
- using boost::shared_ptr;
-
class OgreWindowEventListener : public Ogre::WindowEventListener
{
public:
@@ -88,68 +82,32 @@
@brief
Non-initialising constructor.
*/
- GraphicsManager::GraphicsManager()
- : ogreRoot_(0)
- , ogreLogger_(0)
+ GraphicsManager::GraphicsManager(bool bLoadRenderer)
+ : ogreWindowEventListener_(new OgreWindowEventListener())
, renderWindow_(0)
, viewport_(0)
- , ogreWindowEventListener_(new OgreWindowEventListener())
{
RegisterObject(GraphicsManager);
this->setConfigValues();
- // Ogre setup procedure
- setupOgre();
+ // Ogre setup procedure (creating Ogre::Root)
+ this->loadOgreRoot();
+ // load all the required plugins for Ogre
+ this->loadOgrePlugins();
+ // read resource declaration file
+ this->declareResources();
- try
- {
- // load all the required plugins for Ogre
- loadOgrePlugins();
- // read resource declaration file
- this->declareResources();
- // Reads ogre config and creates the render window
- this->loadRenderer();
-
- // TODO: Spread this
- this->initialiseResources();
-
- // add console commands
- FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
- functor1->setObject(this);
- ccPrintScreen_ = createConsoleCommand(functor1, "printScreen");
- CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
- }
- catch (...)
- {
- // clean up
- delete this->ogreRoot_;
- delete this->ogreLogger_;
- delete this->ogreWindowEventListener_;
- throw;
- }
+ if (bLoadRenderer)
+ this->upgradeToGraphics();
}
/**
@brief
- Destroys all the Ogre related objects
+ Destruction is done by the member scoped_ptrs.
*/
GraphicsManager::~GraphicsManager()
{
-/*
- delete this->ccPrintScreen_;
-*/
-
- // unload all compositors (this is only necessary because we don't yet destroy all resources!)
- Ogre::CompositorManager::getSingleton().removeAll();
-
- // Delete OGRE main control organ
- delete this->ogreRoot_;
-
- // delete the logManager (since we have created it in the first place).
- delete this->ogreLogger_;
-
- delete this->ogreWindowEventListener_;
}
void GraphicsManager::setConfigValues()
@@ -172,47 +130,29 @@
.description("Corresponding orxonox debug level for ogre Critical");
}
- void GraphicsManager::update(const Clock& time)
+ /**
+ @brief
+ Loads the renderer and creates the render window if not yet done so.
+ @remarks
+ This operation is irreversible without recreating the GraphicsManager!
+ So if it throws you HAVE to recreate the GraphicsManager!!!
+ It therefore offers almost no exception safety.
+ */
+ void GraphicsManager::upgradeToGraphics()
{
- Ogre::FrameEvent evt;
- evt.timeSinceLastFrame = time.getDeltaTime();
- evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
-
- // don't forget to call _fireFrameStarted to OGRE to make sure
- // everything goes smoothly
- ogreRoot_->_fireFrameStarted(evt);
-
- // Pump messages in all registered RenderWindows
- // This calls the WindowEventListener objects.
- Ogre::WindowEventUtilities::messagePump();
- // make sure the window stays active even when not focused
- // (probably only necessary on windows)
- this->renderWindow_->setActive(true);
-
- // Time before rendering
- uint64_t timeBeforeTick = time.getRealMicroseconds();
-
- // Render frame
- ogreRoot_->_updateAllRenderTargets();
-
- uint64_t timeAfterTick = time.getRealMicroseconds();
- // Subtract the time used for rendering from the tick time counter
- Game::getInstance().subtractTickTime(timeAfterTick - timeBeforeTick);
-
- // again, just to be sure OGRE works fine
- ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
+ if (renderWindow_ == NULL)
+ {
+ // Reads the ogre config and creates the render window
+ this->loadRenderer();
+ this->initialiseResources();
+ }
}
- void GraphicsManager::setCamera(Ogre::Camera* camera)
- {
- this->viewport_->setCamera(camera);
- }
-
/**
@brief
Creates the Ogre Root object and sets up the ogre log.
*/
- void GraphicsManager::setupOgre()
+ void GraphicsManager::loadOgreRoot()
{
COUT(3) << "Setting up Ogre..." << std::endl;
@@ -232,12 +172,12 @@
// create a new logManager
// Ogre::Root will detect that we've already created a Log
- std::auto_ptr<Ogre::LogManager> logger(new Ogre::LogManager());
+ ogreLogger_.reset(new Ogre::LogManager());
COUT(4) << "Ogre LogManager created" << std::endl;
// create our own log that we can listen to
Ogre::Log *myLog;
- myLog = logger->createLog(ogreLogFilepath.string(), true, false, false);
+ myLog = ogreLogger_->createLog(ogreLogFilepath.string(), true, false, false);
COUT(4) << "Ogre Log created" << std::endl;
myLog->setLogDetail(Ogre::LL_BOREME);
@@ -255,9 +195,7 @@
}
// Leave plugins file empty. We're going to do that part manually later
- ogreRoot_ = new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string());
- // In case that new Root failed the logger gets destroyed because of the std::auto_ptr
- ogreLogger_ = logger.release();
+ ogreRoot_.reset(new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string()));
COUT(3) << "Ogre set up done." << std::endl;
}
@@ -339,14 +277,21 @@
CCOUT(4) << "Creating render window" << std::endl;
this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
+ // Propagate the size of the new winodw
this->ogreWindowEventListener_->windowResized(renderWindow_);
- Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_);
+ Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_.get());
- Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(0);
-
// create a full screen default viewport
+ // Note: This may throw when adding a viewport with an existing z-order!
+ // But in our case we only have one viewport for now anyway, therefore
+ // no ScopeGuards or anything to handle exceptions.
this->viewport_ = this->renderWindow_->addViewport(0, 0);
+
+ // add console commands
+ FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
+ ccPrintScreen_ = createConsoleCommand(functor1->setObject(this), "printScreen");
+ CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
}
void GraphicsManager::initialiseResources()
@@ -369,6 +314,42 @@
//}
}
+ void GraphicsManager::update(const Clock& time)
+ {
+ Ogre::FrameEvent evt;
+ evt.timeSinceLastFrame = time.getDeltaTime();
+ evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
+
+ // don't forget to call _fireFrameStarted to OGRE to make sure
+ // everything goes smoothly
+ ogreRoot_->_fireFrameStarted(evt);
+
+ // Pump messages in all registered RenderWindows
+ // This calls the WindowEventListener objects.
+ Ogre::WindowEventUtilities::messagePump();
+ // make sure the window stays active even when not focused
+ // (probably only necessary on windows)
+ this->renderWindow_->setActive(true);
+
+ // Time before rendering
+ uint64_t timeBeforeTick = time.getRealMicroseconds();
+
+ // Render frame
+ ogreRoot_->_updateAllRenderTargets();
+
+ uint64_t timeAfterTick = time.getRealMicroseconds();
+ // Subtract the time used for rendering from the tick time counter
+ Game::getInstance().subtractTickTime(timeAfterTick - timeBeforeTick);
+
+ // again, just to be sure OGRE works fine
+ ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
+ }
+
+ void GraphicsManager::setCamera(Ogre::Camera* camera)
+ {
+ this->viewport_->setCamera(camera);
+ }
+
/**
@brief
Method called by the LogListener interface from Ogre.
Modified: code/branches/resource3/src/core/GraphicsManager.h
===================================================================
--- code/branches/resource3/src/core/GraphicsManager.h 2009-08-24 11:57:27 UTC (rev 5676)
+++ code/branches/resource3/src/core/GraphicsManager.h 2009-08-24 13:03:44 UTC (rev 5677)
@@ -41,11 +41,15 @@
#include <cassert>
#include <string>
#include <OgreLog.h>
+#include <boost/scoped_ptr.hpp>
+
#include "util/Singleton.h"
#include "OrxonoxClass.h"
namespace orxonox
{
+ using boost::scoped_ptr;
+
/**
@brief
Graphics engine manager class
@@ -54,25 +58,26 @@
{
friend class Singleton<GraphicsManager>;
public:
- GraphicsManager();
+ GraphicsManager(bool bLoadRenderer = true);
~GraphicsManager();
void setConfigValues();
void update(const Clock& time);
- inline Ogre::Viewport* getViewport()
- { return this->viewport_; }
- inline Ogre::RenderWindow* getRenderWindow()
- { return this->renderWindow_; }
+ Ogre::Viewport* getViewport() { return this->viewport_; }
+ Ogre::RenderWindow* getRenderWindow() { return this->renderWindow_; }
+ void upgradeToGraphics();
+ bool rendererLoaded() const { return renderWindow_ != NULL; }
+
void setCamera(Ogre::Camera* camera);
private:
GraphicsManager(GraphicsManager&); // don't mess with singletons
// OGRE initialisation
- void setupOgre();
+ void loadOgreRoot();
void loadOgrePlugins();
void declareResources();
void loadRenderer();
@@ -86,11 +91,11 @@
void printScreen();
private:
- Ogre::Root* ogreRoot_; //!< Ogre's root
- Ogre::LogManager* ogreLogger_;
+ scoped_ptr<OgreWindowEventListener> ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
+ scoped_ptr<Ogre::LogManager> ogreLogger_;
+ scoped_ptr<Ogre::Root> ogreRoot_; //!< Ogre's root
Ogre::RenderWindow* renderWindow_; //!< the one and only render window
Ogre::Viewport* viewport_; //!< default full size viewport
- OgreWindowEventListener* ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
// config values
std::string resourceFile_; //!< resources file name
Modified: code/branches/resource3/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/branches/resource3/src/orxonox/gamestates/GSLevel.cc 2009-08-24 11:57:27 UTC (rev 5676)
+++ code/branches/resource3/src/orxonox/gamestates/GSLevel.cc 2009-08-24 13:03:44 UTC (rev 5677)
@@ -29,6 +29,8 @@
#include "GSLevel.h"
+#include <OgreCompositorManager.h>
+
#include "core/input/InputManager.h"
#include "core/input/InputState.h"
#include "core/input/KeyBinder.h"
@@ -169,6 +171,11 @@
}
*/
+ if (GameMode::showsGraphics())
+ {
+ // unload all compositors (this is only necessary because we don't yet destroy all resources!)
+ Ogre::CompositorManager::getSingleton().removeAll();
+ }
// this call will delete every BaseObject!
// But currently this will call methods of objects that exist no more
More information about the Orxonox-commit
mailing list