Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jul 20, 2008, 7:49:26 PM (16 years ago)
Author:
rgrieder
Message:

merged input branch into gui test branch (was about time)
svn save (it's still a mess and CMLs haven't been updated)
I'll have to create a special project to create the tolua_bind files for tolua itself anyway..

Location:
code/branches/gui
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/gui

  • code/branches/gui/src/orxonox/GraphicsEngine.cc

    r1625 r1638  
    2727 */
    2828
    29  /**
    30     @file orxonox.cc
    31     @brief Orxonox class
    32   */
     29/**
     30@file
     31@brief
     32    Implementation of an partial interface to Ogre.
     33*/
    3334
    3435#include "OrxonoxStableHeaders.h"
     
    5051#include "core/CommandExecutor.h"
    5152#include "core/ConsoleCommand.h"
     53#include "core/Exception.h"
    5254
    5355#include "overlays/console/InGameConsole.h"
     
    5759#include "tools/WindowEventListener.h"
    5860
     61#include "objects/CameraHandler.h"
    5962
    6063namespace orxonox
    6164{
    62   /**
    63     @brief Returns the singleton instance and creates it the first time.
    64     @return The only instance of GraphicsEngine.
    65   */
    66   /*static*/ GraphicsEngine& GraphicsEngine::getSingleton()
    67   {
    68     static GraphicsEngine theOnlyInstance;
    69     return theOnlyInstance;
    70   }
    71 
    72   /**
    73     @brief Only use constructor to initialise variables and pointers!
    74   */
    75   GraphicsEngine::GraphicsEngine() :
    76     root_(0),
    77     scene_(0),
    78     renderWindow_(0)
    79   {
    80     RegisterObject(GraphicsEngine);
    81 
    82     this->detailLevelParticle_ = 0;
    83 
    84     this->setConfigValues();
    85     CCOUT(4) << "Constructed" << std::endl;
    86   }
    87 
    88   void GraphicsEngine::setConfigValues()
    89   {
    90     SetConfigValue(resourceFile_,    "resources.cfg").description("Location of the resources file in the data path.");
    91     SetConfigValue(ogreConfigFile_,  "ogre.cfg").description("Location of the Ogre config file");
    92     SetConfigValue(ogrePluginsFile_, "plugins.cfg").description("Location of the Ogre plugins file");
    93     SetConfigValue(ogreLogFile_,     "ogre.log").description("Logfile for messages from Ogre. \
    94                                                              Use \"\" to suppress log file creation.");
    95     SetConfigValue(ogreLogLevelTrivial_ , 5).description("Corresponding orxonox debug level for ogre Trivial");
    96     SetConfigValue(ogreLogLevelNormal_  , 4).description("Corresponding orxonox debug level for ogre Normal");
    97     SetConfigValue(ogreLogLevelCritical_, 2).description("Corresponding orxonox debug level for ogre Critical");
    98 
    99     unsigned int old = this->detailLevelParticle_;
    100     SetConfigValue(detailLevelParticle_, 2).description("O: off, 1: low, 2: normal, 3: high");
    101 
    102     if (this->detailLevelParticle_ != old)
    103       for (Iterator<ParticleInterface> it = ObjectList<ParticleInterface>::begin(); it; ++it)
    104         it->detailLevelChanged(this->detailLevelParticle_);
    105   }
    106 
    107   /**
    108     @brief Called after main() --> call destroyObjects()!
    109   */
    110   GraphicsEngine::~GraphicsEngine()
    111   {
    112     this->destroy();
    113   }
    114 
    115   /**
    116     @brief Destroys all the internal objects. Call this method when you
    117            normally would call the destructor.
    118   */
    119   void GraphicsEngine::destroy()
    120   {
    121     CCOUT(4) << "Destroying objects..." << std::endl;
    122     Ogre::WindowEventUtilities::removeWindowEventListener(this->renderWindow_, this);
    123     if (this->root_)
    124       delete this->root_;
    125     this->root_ = 0;
    126     this->scene_ = 0;
    127     this->renderWindow_ = 0;
    128     // delete the ogre log and the logManager (since we have created it).
    129     if (Ogre::LogManager::getSingletonPtr() != 0)
    130     {
    131       Ogre::LogManager::getSingleton().getDefaultLog()->removeListener(this);
    132       Ogre::LogManager::getSingleton().destroyLog(Ogre::LogManager::getSingleton().getDefaultLog());
    133       delete Ogre::LogManager::getSingletonPtr();
    134     }
    135     CCOUT(4) << "Destroying objects done" << std::endl;
    136   }
    137 
    138   /**
    139     @brief Creates the Ogre Root object and sets up the ogre log.
    140   */
    141   bool GraphicsEngine::setup()
    142   {
    143     CCOUT(3) << "Setting up..." << std::endl;
    144     // temporary overwrite of dataPath, change ini file for permanent change
    145 
    146 // TODO: LogManager doesn't work on specific systems. The why is unknown yet.
     65    GraphicsEngine* GraphicsEngine::singletonRef_s = 0;
     66
     67    /**
     68    @brief
     69        Returns the singleton instance.
     70    @return
     71        The only instance of GraphicsEngine.
     72    */
     73    /*static*/ GraphicsEngine& GraphicsEngine::getSingleton()
     74    {
     75        assert(singletonRef_s);
     76        return *singletonRef_s;
     77    }
     78
     79    /**
     80    @brief
     81        Non-initialising constructor.
     82    */
     83    GraphicsEngine::GraphicsEngine()
     84        : root_(0)
     85        , renderWindow_(0)
     86        , levelSceneManager_(0)
     87        , levelViewport_(0)
     88    {
     89        RegisterObject(GraphicsEngine);
     90
     91        singletonRef_s = this;
     92
     93        this->detailLevelParticle_ = 0;
     94
     95        this->setConfigValues();
     96        CCOUT(4) << "Constructed" << std::endl;
     97    }
     98
     99    void GraphicsEngine::setConfigValues()
     100    {
     101        SetConfigValue(resourceFile_,    "resources.cfg").description("Location of the resources file in the data path.");
     102        SetConfigValue(ogreConfigFile_,  "ogre.cfg").description("Location of the Ogre config file");
     103        SetConfigValue(ogrePluginsFile_, "plugins.cfg").description("Location of the Ogre plugins file");
     104        SetConfigValue(ogreLogFile_,     "ogre.log").description("Logfile for messages from Ogre. \
     105                                                                 Use \"\" to suppress log file creation.");
     106        SetConfigValue(ogreLogLevelTrivial_ , 5).description("Corresponding orxonox debug level for ogre Trivial");
     107        SetConfigValue(ogreLogLevelNormal_  , 4).description("Corresponding orxonox debug level for ogre Normal");
     108        SetConfigValue(ogreLogLevelCritical_, 2).description("Corresponding orxonox debug level for ogre Critical");
     109
     110        unsigned int old = this->detailLevelParticle_;
     111        SetConfigValue(detailLevelParticle_, 2).description("O: off, 1: low, 2: normal, 3: high");
     112
     113        if (this->detailLevelParticle_ != old)
     114            for (Iterator<ParticleInterface> it = ObjectList<ParticleInterface>::begin(); it; ++it)
     115                it->detailLevelChanged(this->detailLevelParticle_);
     116    }
     117
     118    /**
     119    @brief
     120        Destroys all the Ogre related objects
     121    */
     122    GraphicsEngine::~GraphicsEngine()
     123    {
     124        CCOUT(4) << "Destroying objects..." << std::endl;
     125        Ogre::WindowEventUtilities::removeWindowEventListener(this->renderWindow_, this);
     126        if (this->root_)
     127            delete this->root_;
     128        this->root_ = 0;
     129        this->levelSceneManager_ = 0;
     130        this->renderWindow_ = 0;
     131
    147132#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
    148     // create a logManager
    149     // note: If there's already a logManager, Ogre will complain by a failed assertation.
    150     // but that shouldn't happen, since this is the first time to create a logManager..
    151     Ogre::LogManager* logger = new Ogre::LogManager();
    152     CCOUT(4) << "Ogre LogManager created" << std::endl;
    153 
    154     // create our own log that we can listen to
    155     Ogre::Log *myLog;
    156     if (this->ogreLogFile_ == "")
    157       myLog = logger->createLog("ogre.log", true, false, true);
    158     else
    159       myLog = logger->createLog(this->ogreLogFile_, true, false, false);
    160     CCOUT(4) << "Ogre Log created" << std::endl;
    161 
    162     myLog->setLogDetail(Ogre::LL_BOREME);
    163     myLog->addListener(this);
     133        // delete the ogre log and the logManager (since we have created it).
     134        if (Ogre::LogManager::getSingletonPtr() != 0)
     135        {
     136            Ogre::LogManager::getSingleton().getDefaultLog()->removeListener(this);
     137            Ogre::LogManager::getSingleton().destroyLog(Ogre::LogManager::getSingleton().getDefaultLog());
     138            delete Ogre::LogManager::getSingletonPtr();
     139        }
     140        CCOUT(4) << "Destroying objects done" << std::endl;
    164141#endif
    165142
    166     // Root will detect that we've already created a Log
    167     CCOUT(4) << "Creating Ogre Root..." << std::endl;
    168 
    169     if (ogrePluginsFile_ == "")
    170     {
    171       COUT(1) << "Error: Ogre plugins file set to \"\". Cannot load." << std::endl;
    172       return false;
    173     }
    174     if (ogreConfigFile_ == "")
    175     {
    176       COUT(1) << "Error: Ogre config file set to \"\". Cannot load." << std::endl;
    177       return false;
    178     }
    179     if (ogreLogFile_ == "")
    180     {
    181       COUT(1) << "Error: Ogre log file set to \"\". Cannot load." << std::endl;
    182       return false;
    183     }
    184 
    185     try
    186     {
    187       root_ = new Ogre::Root(ogrePluginsFile_, ogreConfigFile_, ogreLogFile_);
    188     }
    189     catch (Ogre::Exception ex)
    190     {
    191       COUT(2) << "Error: There was an exception when creating Ogre Root." << std::endl;
    192       return false;
    193     }
    194 
    195     if (!root_->getInstalledPlugins().size())
    196     {
    197       COUT(1) << "Error: No plugins declared. Cannot load Ogre." << std::endl;
    198       COUT(0) << "Is the plugins file correctly declared?" << std::endl;
    199       return false;
    200     }
    201 
    202 #if 0
    203     // tame the ogre ouput so we don't get all the mess in the console
    204     Ogre::Log* defaultLog = Ogre::LogManager::getSingleton().getDefaultLog();
    205     defaultLog->setDebugOutputEnabled(false);
    206     defaultLog->setLogDetail(Ogre::LL_BOREME);
    207     defaultLog->addListener(this);
     143        singletonRef_s = 0;
     144    }
     145
     146    /**
     147    @brief
     148        Creates the Ogre Root object and sets up the ogre log.
     149    */
     150    void GraphicsEngine::setup()
     151    {
     152        CCOUT(3) << "Setting up..." << std::endl;
     153
     154        // TODO: LogManager doesn't work on linux platform. The why is yet unknown.
     155#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
     156        // create a new logManager
     157        Ogre::LogManager* logger = new Ogre::LogManager();
     158        CCOUT(4) << "Ogre LogManager created" << std::endl;
     159
     160        // create our own log that we can listen to
     161        Ogre::Log *myLog;
     162        if (this->ogreLogFile_ == "")
     163            myLog = logger->createLog("ogre.log", true, false, true);
     164        else
     165            myLog = logger->createLog(this->ogreLogFile_, true, false, false);
     166        CCOUT(4) << "Ogre Log created" << std::endl;
     167
     168        myLog->setLogDetail(Ogre::LL_BOREME);
     169        myLog->addListener(this);
    208170#endif
    209171
    210     CCOUT(4) << "Creating Ogre Root done" << std::endl;
    211 
    212     // specify where Ogre has to look for resources. This call doesn't parse anything yet!
    213     if (!declareRessourceLocations())
    214       return false;
    215 
    216     CCOUT(3) << "Set up done." << std::endl;
    217     return true;
    218   }
    219 
    220   bool GraphicsEngine::declareRessourceLocations()
    221   {
    222     CCOUT(4) << "Declaring Resources" << std::endl;
    223     //TODO: Specify layout of data file and maybe use xml-loader
    224     //TODO: Work with ressource groups (should be generated by a special loader)
    225 
    226     if (resourceFile_ == "")
    227     {
    228       COUT(1) << "Error: Resource file set to \"\". Cannot load." << std::endl;
    229       return false;
    230     }
    231 
    232     // Load resource paths from data file using configfile ressource type
    233     Ogre::ConfigFile cf;
    234     try
    235     {
    236       cf.load(Settings::getDataPath() + resourceFile_);
    237     }
    238     catch (Ogre::Exception ex)
    239     {
    240       COUT(1) << "Error: Could not load resources.cfg in path " << Settings::getDataPath() << std::endl;
    241       COUT(0) << "Have you forgotten to set the data path in orxnox.ini?" << std::endl;
    242       return false;
    243     }
    244 
    245     // Go through all sections & settings in the file
    246     Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
    247 
    248     std::string secName, typeName, archName;
    249     while (seci.hasMoreElements())
    250     {
    251       try
    252       {
    253         secName = seci.peekNextKey();
    254         Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
    255         Ogre::ConfigFile::SettingsMultiMap::iterator i;
    256         for (i = settings->begin(); i != settings->end(); ++i)
    257         {
    258           typeName = i->first; // for instance "FileSystem" or "Zip"
    259           archName = i->second; // name (and location) of archive
    260 
    261           Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
    262               std::string(Settings::getDataPath() + archName), typeName, secName);
    263         }
    264       }
    265       catch (Ogre::Exception ex)
    266       {
    267         COUT(2) << "Exception while reading resources.cfg. Proceeding.." << ex.getDescription() << std::endl;
    268       }
    269     }
    270     return true;
    271   }
    272 
    273   bool GraphicsEngine::loadRenderer()
    274   {
    275     CCOUT(4) << "Configuring Renderer" << std::endl;
    276 
    277     // check for file existence because Ogre displays exceptions if not
    278     std::ifstream probe;
    279     probe.open(ogreConfigFile_.c_str());
    280     if (!probe)
    281     {
    282       // create a zero sized file
    283       std::ofstream creator;
    284       creator.open(ogreConfigFile_.c_str());
    285       creator.close();
    286     }
    287     else
    288       probe.close();
    289 
    290     if (!root_->restoreConfig())
    291       if (!root_->showConfigDialog())
    292         return false;
    293 
    294     CCOUT(4) << "Creating render window" << std::endl;
    295     try
    296     {
    297       this->renderWindow_ = root_->initialise(true, "OrxonoxV2");
    298     }
    299     catch (Ogre::Exception ex)
    300     {
    301       COUT(2) << "Error: There was an exception when initialising Ogre Root." << std::endl;
    302       return false;
    303     }
    304 
    305     if (!root_->isInitialised())
    306     {
    307       CCOUT(2) << "Error: Initialising Ogre root object failed." << std::endl;
    308       return false;
    309     }
    310     Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, this);
    311     Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
    312     return true;
    313   }
    314 
    315   bool GraphicsEngine::initialiseResources()
    316   {
    317     CCOUT(4) << "Initialising resources" << std::endl;
    318     //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
    319     try
    320     {
    321       Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
    322       /*Ogre::StringVector str = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
    323       for (unsigned int i = 0; i < str.size(); i++)
    324       {
    325         Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(str[i]);
    326       }*/
    327     }
    328     catch (Ogre::Exception e)
    329     {
    330       CCOUT(2) << "Error: There was an Error when initialising the resources." << std::endl;
    331       CCOUT(2) << "ErrorMessage: " << e.getFullDescription() << std::endl;
    332       return false;
    333     }
    334     return true;
    335   }
    336 
    337   /**
    338    * @brief Creates the SceneManager
    339    */
    340   bool GraphicsEngine::createNewScene()
    341   {
    342     CCOUT(4) << "Creating new SceneManager..." << std::endl;
    343     if (scene_)
    344     {
    345       CCOUT(2) << "SceneManager already exists! Skipping." << std::endl;
    346       return false;
    347     }
    348     scene_ = root_->createSceneManager(Ogre::ST_GENERIC, "Default SceneManager");
    349     CCOUT(3) << "Created SceneManager: " << scene_ << std::endl;
    350     return true;
    351   }
    352 
    353   /**
    354     Returns the window handle of the render window.
    355     At least the InputHandler uses this to create the OIS::InputManager
    356     @return The window handle of the render window
    357   */
    358   size_t GraphicsEngine::getWindowHandle()
    359   {
    360     if (this->renderWindow_)
    361     {
    362       size_t windowHnd = 0;
    363       this->renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
    364       return windowHnd;
    365     }
    366     else
    367       return 0;
    368   }
    369 
    370   /**
    371     Get the width of the current render window
    372     @return The width of the current render window
    373   */
    374   int GraphicsEngine::getWindowWidth() const
    375   {
    376     if (this->renderWindow_)
    377       return this->renderWindow_->getWidth();
    378     else
    379       return 0;
    380   }
    381 
    382   /**
    383     Get the height of the current render window
    384     @return The height of the current render window
    385   */
    386   int GraphicsEngine::getWindowHeight() const
    387   {
    388     if (this->renderWindow_)
    389       return this->renderWindow_->getHeight();
    390     else
    391       return 0;
    392   }
    393 
    394   /**
    395     @brief Returns the window aspect ratio height/width.
    396     @return The ratio
    397   */
    398   float GraphicsEngine::getWindowAspectRatio() const
    399   {
    400     if (this->renderWindow_)
    401         return (float)this->renderWindow_->getHeight() / (float)this->renderWindow_->getWidth();
    402     else
    403         return 1.0f;
    404   }
    405 
    406   /**
    407     @brief Method called by the LogListener interface from Ogre.
    408     We use it to capture Ogre log messages and handle it ourselves.
    409     @param message The message to be logged
    410     @param lml The message level the log is using
    411     @param maskDebug If we are printing to the console or not
    412     @param logName the name of this log (so you can have several listeners
    413                    for different logs, and identify them)
    414   */
    415   void GraphicsEngine::messageLogged(const std::string& message,
    416     Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName)
    417   {
    418     int orxonoxLevel;
    419     switch (lml)
    420     {
    421       case Ogre::LML_TRIVIAL:
    422         orxonoxLevel = this->ogreLogLevelTrivial_;
    423         break;
    424       case Ogre::LML_NORMAL:
    425         orxonoxLevel = this->ogreLogLevelNormal_;
    426         break;
    427       case Ogre::LML_CRITICAL:
    428         orxonoxLevel = this->ogreLogLevelCritical_;
    429         break;
    430       default:
    431         orxonoxLevel = 0;
    432     }
    433     OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
    434         << "Ogre: " << message << std::endl;
    435   }
    436 
    437   /**
    438   * Window has moved.
    439   * @param rw The render window it occured in
    440   */
    441   void GraphicsEngine::windowMoved(Ogre::RenderWindow *rw)
    442   {
    443     for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
    444       it->windowMoved();
    445   }
    446 
    447   /**
    448   * Window has resized.
    449   * @param rw The render window it occured in
    450   * @note GraphicsEngine has a render window stored itself. This is the same
    451   *       as rw. But we have to be careful when using multiple render windows!
    452   */
    453   void GraphicsEngine::windowResized(Ogre::RenderWindow *rw)
    454   {
    455     for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
    456       it->windowResized(this->renderWindow_->getWidth(), this->renderWindow_->getHeight());
    457   }
    458 
    459   /**
    460   * Window has changed Focus.
    461   * @param rw The render window it occured in
    462   */
    463   void GraphicsEngine::windowFocusChanged(Ogre::RenderWindow *rw)
    464   {
    465     for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
    466       it->windowFocusChanged();
    467   }
    468 
    469   /**
    470   * Window was closed.
    471   * @param rw The render window it occured in
    472   */
    473   void GraphicsEngine::windowClosed(Ogre::RenderWindow *rw)
    474   {
    475     // using CommandExecutor in order to avoid depending on Orxonox.h.
    476     CommandExecutor::execute("exit", false);
    477   }
     172        // Root will detect that we've already created a Log
     173        CCOUT(4) << "Creating Ogre Root..." << std::endl;
     174
     175        if (ogrePluginsFile_ == "")
     176        {
     177            COUT(2) << "Warning: Ogre plugins file set to \"\". Defaulting to plugins.cfg" << std::endl;
     178            ModifyConfigValue(ogrePluginsFile_, tset, "plugins.cfg");
     179        }
     180        if (ogreConfigFile_ == "")
     181        {
     182            COUT(2) << "Warning: Ogre config file set to \"\". Defaulting to config.cfg" << std::endl;
     183            ModifyConfigValue(ogreConfigFile_, tset, "config.cfg");
     184        }
     185        if (ogreLogFile_ == "")
     186        {
     187            COUT(2) << "Warning: Ogre log file set to \"\". Defaulting to ogre.log" << std::endl;
     188            ModifyConfigValue(ogreLogFile_, tset, "ogre.log");
     189        }
     190
     191        root_ = new Ogre::Root(ogrePluginsFile_, ogreConfigFile_, ogreLogFile_);
     192
     193        if (!root_->getInstalledPlugins().size())
     194        {
     195            ThrowException(PluginsNotFound, "No Ogre plugins declared. Cannot load Ogre.");
     196        }
     197
     198#if 0 // Ogre 1.4.3 doesn't support setDebugOutputEnabled(.)
     199//#if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32
     200        // tame the ogre ouput so we don't get all the mess in the console
     201        Ogre::Log* defaultLog = Ogre::LogManager::getSingleton().getDefaultLog();
     202        defaultLog->setDebugOutputEnabled(false);
     203        defaultLog->setLogDetail(Ogre::LL_BOREME);
     204        defaultLog->addListener(this);
     205#endif
     206
     207        CCOUT(4) << "Creating Ogre Root done" << std::endl;
     208
     209        // specify where Ogre has to look for resources. This call doesn't parse anything yet!
     210        declareRessourceLocations();
     211
     212        CCOUT(3) << "Set up done." << std::endl;
     213    }
     214
     215    void GraphicsEngine::declareRessourceLocations()
     216    {
     217        CCOUT(4) << "Declaring Resources" << std::endl;
     218        //TODO: Specify layout of data file and maybe use xml-loader
     219        //TODO: Work with ressource groups (should be generated by a special loader)
     220
     221        if (resourceFile_ == "")
     222        {
     223            COUT(2) << "Warning: Ogre resource file set to \"\". Defaulting to resources.cfg" << std::endl;
     224            ModifyConfigValue(resourceFile_, tset, "resources.cfg");
     225        }
     226
     227        // Load resource paths from data file using configfile ressource type
     228        Ogre::ConfigFile cf;
     229        try
     230        {
     231            cf.load(Settings::getDataPath() + resourceFile_);
     232        }
     233        catch (Ogre::Exception& ex)
     234        {
     235            COUT(1) << ex.getFullDescription() << std::endl;
     236            COUT(0) << "Have you forgotten to set the data path in orxnox.ini?" << std::endl;
     237            throw;
     238        }
     239
     240        // Go through all sections & settings in the file
     241        Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
     242
     243        std::string secName, typeName, archName;
     244        while (seci.hasMoreElements())
     245        {
     246            try
     247            {
     248                secName = seci.peekNextKey();
     249                Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
     250                Ogre::ConfigFile::SettingsMultiMap::iterator i;
     251                for (i = settings->begin(); i != settings->end(); ++i)
     252                {
     253                    typeName = i->first; // for instance "FileSystem" or "Zip"
     254                    archName = i->second; // name (and location) of archive
     255
     256                    Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
     257                        std::string(Settings::getDataPath() + archName), typeName, secName);
     258                }
     259            }
     260            catch (Ogre::Exception& ex)
     261            {
     262                COUT(1) << ex.getFullDescription() << std::endl;
     263            }
     264        }
     265    }
     266
     267    bool GraphicsEngine::loadRenderer()
     268    {
     269        CCOUT(4) << "Configuring Renderer" << std::endl;
     270
     271        // check for file existence because Ogre displays exceptions if not
     272        std::ifstream probe;
     273        probe.open(ogreConfigFile_.c_str());
     274        if (!probe)
     275        {
     276            // create a zero sized file
     277            std::ofstream creator;
     278            creator.open(ogreConfigFile_.c_str());
     279            creator.close();
     280        }
     281        else
     282            probe.close();
     283
     284        if (!root_->restoreConfig())
     285            if (!root_->showConfigDialog())
     286                return false;
     287
     288        CCOUT(4) << "Creating render window" << std::endl;
     289        try
     290        {
     291            this->renderWindow_ = root_->initialise(true, "OrxonoxV2");
     292        }
     293        catch (...)
     294        {
     295            COUT(2) << "Error: There was an exception when initialising Ogre Root." << std::endl;
     296            return false;
     297        }
     298
     299        if (!root_->isInitialised())
     300        {
     301            CCOUT(2) << "Error: Initialising Ogre root object failed." << std::endl;
     302            return false;
     303        }
     304        Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, this);
     305        //Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
     306
     307        // create a full screen viewport in which to render the scene and the loading screen
     308        // The GUI uses its own one to be able to render on top of everything.
     309        // That explains why the Z order here is only 1 and not 0 (top most)
     310        this->levelViewport_ = this->renderWindow_->addViewport(0, 1);
     311
     312        return true;
     313    }
     314
     315    bool GraphicsEngine::initialiseResources()
     316    {
     317        CCOUT(4) << "Initialising resources" << std::endl;
     318        //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
     319        try
     320        {
     321            Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
     322            /*Ogre::StringVector str = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
     323            for (unsigned int i = 0; i < str.size(); i++)
     324            {
     325            Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(str[i]);
     326            }*/
     327        }
     328        catch (Ogre::Exception& e)
     329        {
     330            CCOUT(2) << "Error: There was an Error when initialising the resources." << std::endl;
     331            CCOUT(2) << "ErrorMessage: " << e.getFullDescription() << std::endl;
     332            return false;
     333        }
     334        return true;
     335    }
     336
     337    /**
     338    @brief
     339        Creates the SceneManager
     340    */
     341    bool GraphicsEngine::createNewScene()
     342    {
     343        CCOUT(4) << "Creating new SceneManager..." << std::endl;
     344        if (levelSceneManager_)
     345        {
     346            CCOUT(2) << "SceneManager already exists! Skipping." << std::endl;
     347            return false;
     348        }
     349        this->levelSceneManager_ = this->root_->createSceneManager(Ogre::ST_GENERIC, "LevelSceneManager");
     350        CCOUT(3) << "Created SceneManager: " << levelSceneManager_ << std::endl;
     351        return true;
     352    }
     353
     354    /**
     355    @brief
     356        Returns the window handle of the render window.
     357        At least the InputHandler uses this to create the OIS::InputManager
     358    @return
     359        The window handle of the render window
     360    */
     361    size_t GraphicsEngine::getWindowHandle()
     362    {
     363        if (this->renderWindow_)
     364        {
     365            size_t windowHnd = 0;
     366            this->renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
     367            return windowHnd;
     368        }
     369        else
     370            return 0;
     371    }
     372
     373    /**
     374    @brief
     375        Get the width of the render window
     376    @return
     377        The width of the render window
     378    */
     379    int GraphicsEngine::getWindowWidth() const
     380    {
     381        if (this->renderWindow_)
     382            return this->renderWindow_->getWidth();
     383        else
     384            return 0;
     385    }
     386
     387    /**
     388    @brief
     389        Get the height of the render window
     390    @return
     391        The height of the render window
     392    */
     393    int GraphicsEngine::getWindowHeight() const
     394    {
     395        if (this->renderWindow_)
     396            return this->renderWindow_->getHeight();
     397        else
     398            return 0;
     399    }
     400
     401    /**
     402    @brief
     403        Returns the window aspect ratio height/width.
     404    @return
     405        The window aspect ratio
     406    */
     407    float GraphicsEngine::getWindowAspectRatio() const
     408    {
     409        if (this->renderWindow_)
     410            return (float)this->renderWindow_->getHeight() / (float)this->renderWindow_->getWidth();
     411        else
     412            return 1.0f;
     413    }
     414
     415    /**
     416    @brief
     417        Method called by the LogListener interface from Ogre.
     418        We use it to capture Ogre log messages and handle it ourselves.
     419    @param message
     420        The message to be logged
     421    @param lml
     422        The message level the log is using
     423    @param maskDebug
     424        If we are printing to the console or not
     425    @param logName
     426        The name of this log (so you can have several listeners
     427        for different logs, and identify them)
     428    */
     429    void GraphicsEngine::messageLogged(const std::string& message,
     430        Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName)
     431    {
     432        int orxonoxLevel;
     433        switch (lml)
     434        {
     435        case Ogre::LML_TRIVIAL:
     436            orxonoxLevel = this->ogreLogLevelTrivial_;
     437            break;
     438        case Ogre::LML_NORMAL:
     439            orxonoxLevel = this->ogreLogLevelNormal_;
     440            break;
     441        case Ogre::LML_CRITICAL:
     442            orxonoxLevel = this->ogreLogLevelCritical_;
     443            break;
     444        default:
     445            orxonoxLevel = 0;
     446        }
     447        OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
     448            << "Ogre: " << message << std::endl;
     449    }
     450
     451    /**
     452    @brief
     453        Window has moved.
     454    @param rw
     455        The render window it occured in
     456    */
     457    void GraphicsEngine::windowMoved(Ogre::RenderWindow *rw)
     458    {
     459        for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
     460            it->windowMoved();
     461    }
     462
     463    /**
     464    @brief
     465        Window has resized.
     466    @param rw
     467        The render window it occured in
     468    @note
     469        GraphicsEngine has a render window stored itself. This is the same
     470        as rw. But we have to be careful when using multiple render windows!
     471    */
     472    void GraphicsEngine::windowResized(Ogre::RenderWindow *rw)
     473    {
     474        for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
     475            it->windowResized(this->renderWindow_->getWidth(), this->renderWindow_->getHeight());
     476    }
     477
     478    /**
     479    @brief
     480        Window focus has changed.
     481    @param rw
     482        The render window it occured in
     483    */
     484    void GraphicsEngine::windowFocusChanged(Ogre::RenderWindow *rw)
     485    {
     486        for (Iterator<orxonox::WindowEventListener> it = ObjectList<orxonox::WindowEventListener>::start(); it; ++it)
     487            it->windowFocusChanged();
     488    }
     489
     490    /**
     491    @brief
     492        Window was closed.
     493    @param rw
     494        The render window it occured in
     495    */
     496    void GraphicsEngine::windowClosed(Ogre::RenderWindow *rw)
     497    {
     498        // using CommandExecutor in order to avoid depending on Orxonox.h.
     499        CommandExecutor::execute("exit", false);
     500    }
    478501
    479502}
Note: See TracChangeset for help on using the changeset viewer.