Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 10, 2008, 1:37:36 AM (16 years ago)
Author:
rgrieder
Message:

merged gui back to trunk.
update the media repository!

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/orxonox/GraphicsEngine.cc

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