Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ogre/src/orxonox/GraphicsEngine.cc @ 1244

Last change on this file since 1244 was 1244, checked in by rgrieder, 16 years ago
  • added some comments and COUTs
File size: 10.5 KB
RevLine 
[612]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
[1056]3 *                    > www.orxonox.net <
[612]4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
24 *   Co-authors:
[1032]25 *      Reto Grieder
[612]26 *
27 */
[1035]28
[612]29 /**
30    @file orxonox.cc
31    @brief Orxonox class
32  */
33
[1021]34#include "OrxonoxStableHeaders.h"
[1039]35#include "GraphicsEngine.h"
[612]36
37#include <OgreRoot.h>
[1021]38#include <OgreException.h>
[612]39#include <OgreConfigFile.h>
[1024]40#include <OgreLogManager.h>
[612]41#include <OgreTextureManager.h>
[1214]42#include "core/InputManager.h"
[1052]43#include "core/CoreIncludes.h"
44#include "core/ConfigValueIncludes.h"
[1214]45#include "core/Debug.h"
[1032]46
[612]47
48namespace orxonox {
49
[1032]50  /**
51    @brief Returns the singleton instance and creates it the first time.
52    @return The only instance of GraphicsEngine.
53  */
54  GraphicsEngine& GraphicsEngine::getSingleton()
55  {
56    static GraphicsEngine theOnlyInstance;
57    return theOnlyInstance;
58  }
59
60  /**
61    @brief Only use constructor to initialise variables and pointers!
62  */
[612]63  GraphicsEngine::GraphicsEngine()
64  {
[1021]65    RegisterObject(GraphicsEngine);
[612]66    // set to standard values
67    this->configPath_ = "";
[1021]68    this->root_ = 0;
69    this->scene_ = 0;
70    this->renderWindow_ = 0;
[1243]71    this->setConfigValues();
[1244]72    CCOUT(4) << "Constructed" << std::endl;
[612]73  }
74
[1032]75  /**
76    @brief Called after main() --> call destroyObjects()!
77  */
[612]78  GraphicsEngine::~GraphicsEngine()
79  {
[1032]80    this->destroy();
81  }
82
83  /**
84    @brief Destroys all the internal objects. Call this method when you
85           normally would call the destructor.
86  */
87  void GraphicsEngine::destroy()
88  {
[1244]89    COUT(4) << "Destroying objects..." << std::endl;
[1214]90    Ogre::WindowEventUtilities::removeWindowEventListener(this->renderWindow_, this);
[1024]91    if (this->root_)
[1021]92      delete this->root_;
[1032]93    this->root_ = 0;
94    this->scene_ = 0;
95    this->renderWindow_ = 0;
96    // delete the ogre log and the logManager (since we have created it).
[1052]97    if (Ogre::LogManager::getSingletonPtr() != 0)
[1024]98    {
[1052]99      Ogre::LogManager::getSingleton().getDefaultLog()->removeListener(this);
100      Ogre::LogManager::getSingleton().destroyLog(Ogre::LogManager::getSingleton().getDefaultLog());
101      delete Ogre::LogManager::getSingletonPtr();
[1024]102    }
[1244]103    COUT(4) << "Destroying objects done" << std::endl;
[612]104  }
105
[1021]106  void GraphicsEngine::setConfigValues()
107  {
[1090]108    SetConfigValue(dataPath_, "../../Media/").description("relative path to media data");
[1024]109    SetConfigValue(ogreLogfile_, "ogre.log").description("Logfile for messages from Ogre. Use \"\" to suppress log file creation.");
[1032]110    SetConfigValue(ogreLogLevelTrivial_ , 5).description("Corresponding orxonox debug level for ogre Trivial");
111    SetConfigValue(ogreLogLevelNormal_  , 4).description("Corresponding orxonox debug level for ogre Normal");
[1214]112    SetConfigValue(ogreLogLevelCritical_, 2).description("Corresponding orxonox debug level for ogre Critical");
[1021]113  }
114
[1024]115  /**
116    @brief Creates the Ogre Root object and sets up the ogre log.
117  */
[1243]118  bool GraphicsEngine::setup(std::string& dataPath)
[612]119  {
[1244]120    CCOUT(3) << "Setting up..." << std::endl;
[1243]121    // temporary overwrite of dataPath, change ini file for permanent change
122    if (dataPath != "")
123      dataPath_ = dataPath;
124    if (dataPath_ == "")
125      return false;
126    if (dataPath_[dataPath_.size() - 1] != '/')
127      dataPath_ += "/";
128
[612]129    //TODO: Check if file exists (maybe not here)
[1021]130#if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC && defined(_DEBUG)
[715]131    std::string plugin_filename = "plugins_d.cfg";
[679]132#else
[715]133    std::string plugin_filename = "plugins.cfg";
[679]134#endif
[1024]135
136    // create a logManager
[1062]137    Ogre::LogManager *logger;
138                if (Ogre::LogManager::getSingletonPtr() == 0)
139                        logger = new Ogre::LogManager();
[1024]140    else
[1062]141      logger = Ogre::LogManager::getSingletonPtr();
[1244]142    CCOUT(4) << "Ogre LogManager created/assigned" << std::endl;
[1024]143
144    // create our own log that we can listen to
[1062]145    Ogre::Log *myLog;
[1024]146    if (this->ogreLogfile_ == "")
147      myLog = logger->createLog("ogre.log", true, false, true);
148    else
149      myLog = logger->createLog(this->ogreLogfile_, true, false, false);
[1032]150    COUT(4) << "*** GraphicsEngine: Ogre Log created" << std::endl;
[1024]151
[1062]152    myLog->setLogDetail(Ogre::LL_BOREME);
153    myLog->addListener(this);
[1024]154
155    // Root will detect that we've already created a Log
[1244]156    CCOUT(4) << "Creating Ogre Root..." << std::endl;
[1052]157    root_ = new Ogre::Root(plugin_filename);
[1244]158    CCOUT(4) << "Creating Ogre Root done" << std::endl;
[612]159
[1243]160    // specify where Ogre has to look for resources. This call doesn't parse anything yet!
161    declareRessourceLocations();
[612]162
[1244]163    CCOUT(3) << "Set up done." << std::endl;
[612]164    return true;
165  }
166
[1243]167  void GraphicsEngine::declareRessourceLocations()
[612]168  {
[1244]169    CCOUT(4) << "Declaring Resources" << std::endl;
[612]170    //TODO: Specify layout of data file and maybe use xml-loader
171    //TODO: Work with ressource groups (should be generated by a special loader)
172    // Load resource paths from data file using configfile ressource type
[1052]173    Ogre::ConfigFile cf;
[1243]174    cf.load(dataPath_ + "resources.cfg");
[612]175
176    // Go through all sections & settings in the file
[1052]177    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
[612]178
[715]179    std::string secName, typeName, archName;
[612]180    while (seci.hasMoreElements())
181    {
182      secName = seci.peekNextKey();
[1052]183      Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
184      Ogre::ConfigFile::SettingsMultiMap::iterator i;
[612]185      for (i = settings->begin(); i != settings->end(); ++i)
186      {
187        typeName = i->first; // for instance "FileSystem" or "Zip"
188        archName = i->second; // name (and location) of archive
189
[1052]190        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
[1243]191                                           std::string(dataPath_ + archName),
[612]192                                           typeName, secName);
193      }
194    }
195  }
196
[1243]197  bool GraphicsEngine::loadRenderer()
198  {
[1244]199    CCOUT(4) << "Configuring Renderer" << std::endl;
[1243]200    if (!root_->restoreConfig() && !root_->showConfigDialog())
201      return false;
202
[1244]203    CCOUT(4) << "Creating render window" << std::endl;
[1243]204    this->renderWindow_ = root_->initialise(true, "OrxonoxV2");
205    if (!root_->isInitialised())
[1244]206    {
207      CCOUT(2) << "Error: Creating Ogre root object failed" << std::endl;
[1243]208      return false;
[1244]209    }
[1243]210    Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, this);
211    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
212    return true;
213  }
214
[1244]215  bool GraphicsEngine::initialiseResources()
[1243]216  {
[1244]217    CCOUT(4) << "Initialising resources" << std::endl;
[1243]218    //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
[1244]219    try
220    {
221      Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
222    }
223    catch (Ogre::Exception e)
224    {
225      CCOUT(2) << "Error: There was an Error when initialising the resources." << std::endl;
226      CCOUT(2) << "ErrorMessage: " << e.getFullDescription() << std::endl;
227      return false;
228    }
229    return true;
[1243]230  }
231
[1021]232  /**
[1243]233   * @brief Creates the SceneManager
234   */
235  bool GraphicsEngine::createNewScene()
236  {
[1244]237    CCOUT(4) << "Creating new SceneManager" << std::endl;
[1243]238    if (scene_)
[1244]239    {
240      CCOUT(2) << "SceneManager already exists! Skipping." << std::endl;
[1243]241      return false;
[1244]242    }
[1243]243    scene_ = root_->createSceneManager(Ogre::ST_GENERIC, "Default SceneManager");
[1244]244    CCOUT(3) << "Created SceneManager: " << scene_ << std::endl;
[1243]245    return true;
246  }
247
248  /**
[1021]249    Returns the window handle of the render window.
250    At least the InputHandler uses this to create the OIS::InputManager
251    @return The window handle of the render window
252  */
253  size_t GraphicsEngine::getWindowHandle()
254  {
255    if (this->renderWindow_)
256    {
[1024]257      size_t windowHnd = 0;
[1032]258      this->renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
[1024]259      return windowHnd;
260    }
[1021]261    else
262      return 0;
263  }
[612]264
[1021]265  /**
266    Get the width of the current render window
267    @return The width of the current render window
268  */
269  int GraphicsEngine::getWindowWidth() const
270  {
271    if (this->renderWindow_)
272      return this->renderWindow_->getWidth();
273    else
274      return 0;
275  }
276
277  /**
278    Get the height of the current render window
279    @return The height of the current render window
280  */
281  int GraphicsEngine::getWindowHeight() const
282  {
283    if (this->renderWindow_)
284      return this->renderWindow_->getHeight();
285    else
286      return 0;
287  }
288
[1024]289  /**
290    @brief Method called by the LogListener interface from Ogre.
291    We use it to capture Ogre log messages and handle it ourselves.
292    @param message The message to be logged
293    @param lml The message level the log is using
294    @param maskDebug If we are printing to the console or not
295    @param logName the name of this log (so you can have several listeners
296                   for different logs, and identify them)
297  */
298  void GraphicsEngine::messageLogged(const std::string& message,
[1052]299    Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName)
[1024]300  {
301    int orxonoxLevel;
302    switch (lml)
303    {
[1052]304      case Ogre::LML_TRIVIAL:
[1024]305        orxonoxLevel = this->ogreLogLevelTrivial_;
306        break;
[1052]307      case Ogre::LML_NORMAL:
[1024]308        orxonoxLevel = this->ogreLogLevelNormal_;
309        break;
[1052]310      case Ogre::LML_CRITICAL:
[1024]311        orxonoxLevel = this->ogreLogLevelCritical_;
312        break;
313      default:
314        orxonoxLevel = 0;
315    }
316    OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
[1243]317        << "Ogre: " << message << std::endl;
[1024]318  }
[1214]319
320    void GraphicsEngine::windowMoved(Ogre::RenderWindow *rw){
321        int w = rw->getWidth();
322        int h = rw->getHeight();
[1220]323        InputManager::setWindowExtents(w, h);
[1214]324    }
325
326    void GraphicsEngine::windowResized(Ogre::RenderWindow *rw){
327        int w = rw->getWidth();
328        int h = rw->getHeight();
[1220]329        InputManager::setWindowExtents(w, h);
[1214]330    }
331
332    void GraphicsEngine::windowFocusChanged(Ogre::RenderWindow *rw){
333        int w = rw->getWidth();
334        int h = rw->getHeight();
[1220]335        InputManager::setWindowExtents(w, h);
[1214]336    }
[612]337}
Note: See TracBrowser for help on using the repository browser.