Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/orxonox/GraphicsEngine.cc @ 1494

Last change on this file since 1494 was 1494, checked in by rgrieder, 17 years ago
  • set the svn:eol-style property to all files so, that where ever you check out, you'll get the right line endings (had to change every file with mixed endings to windows in order to set the property)
  • Property svn:eol-style set to native
File size: 14.2 KB
RevLine 
[612]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
[1293]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
[1349]11 *   of the License, or (at your option) any later version.
12 *
[612]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"
[1293]43#include "core/CoreIncludes.h"
44#include "core/ConfigValueIncludes.h"
45#include "core/Debug.h"
[1494]46#include "core/CommandExecutor.h"#include "core/TclBind.h"
[1446]47#include "console/InGameConsole.h"
[1032]48
[1466]49#include "core/ConsoleCommand.h"
50#include <OgreSceneManager.h>
51#include <OgreCompositorManager.h>
52#include <OgreViewport.h>
53
[612]54namespace orxonox {
[1032]55  /**
56    @brief Returns the singleton instance and creates it the first time.
57    @return The only instance of GraphicsEngine.
58  */
[1293]59  /*static*/ GraphicsEngine& GraphicsEngine::getSingleton()
[1032]60  {
61    static GraphicsEngine theOnlyInstance;
62    return theOnlyInstance;
63  }
64
65  /**
66    @brief Only use constructor to initialise variables and pointers!
67  */
[1293]68  GraphicsEngine::GraphicsEngine() :
69    root_(0),
70    scene_(0),
71    renderWindow_(0),
72    //configPath_(""),
73    dataPath_(""),
74    ogreLogfile_("")
[612]75  {
[1021]76    RegisterObject(GraphicsEngine);
[1293]77
[1021]78    this->setConfigValues();
[1293]79    CCOUT(4) << "Constructed" << std::endl;
[612]80  }
81
[1293]82  void GraphicsEngine::setConfigValues()
83  {
84    SetConfigValue(dataPath_, "../../Media/").description("relative path to media data");
85    SetConfigValue(ogreLogfile_, "ogre.log").description("Logfile for messages from Ogre. Use \"\" to suppress log file creation.");
86    SetConfigValue(ogreLogLevelTrivial_ , 5).description("Corresponding orxonox debug level for ogre Trivial");
87    SetConfigValue(ogreLogLevelNormal_  , 4).description("Corresponding orxonox debug level for ogre Normal");
[1494]88    SetConfigValue(ogreLogLevelCritical_, 2).description("Corresponding orxonox debug level for ogre Critical");    TclBind::getInstance().setDataPath(this->dataPath_);
[1293]89  }
90
[1032]91  /**
92    @brief Called after main() --> call destroyObjects()!
93  */
[612]94  GraphicsEngine::~GraphicsEngine()
95  {
[1032]96    this->destroy();
97  }
98
99  /**
100    @brief Destroys all the internal objects. Call this method when you
101           normally would call the destructor.
102  */
103  void GraphicsEngine::destroy()
104  {
[1293]105    CCOUT(4) << "Destroying objects..." << std::endl;
[1214]106    Ogre::WindowEventUtilities::removeWindowEventListener(this->renderWindow_, this);
[1024]107    if (this->root_)
[1021]108      delete this->root_;
[1032]109    this->root_ = 0;
110    this->scene_ = 0;
111    this->renderWindow_ = 0;
112    // delete the ogre log and the logManager (since we have created it).
[1052]113    if (Ogre::LogManager::getSingletonPtr() != 0)
[1024]114    {
[1052]115      Ogre::LogManager::getSingleton().getDefaultLog()->removeListener(this);
116      Ogre::LogManager::getSingleton().destroyLog(Ogre::LogManager::getSingleton().getDefaultLog());
117      delete Ogre::LogManager::getSingletonPtr();
[1024]118    }
[1293]119    CCOUT(4) << "Destroying objects done" << std::endl;
[612]120  }
121
[1024]122  /**
123    @brief Creates the Ogre Root object and sets up the ogre log.
124  */
[1293]125  bool GraphicsEngine::setup(std::string& dataPath)
[612]126  {
[1293]127    CCOUT(3) << "Setting up..." << std::endl;
128    // temporary overwrite of dataPath, change ini file for permanent change
129    if (dataPath != "")
130      dataPath_ = dataPath;
131    if (dataPath_ == "")
132      return false;
133    if (dataPath_[dataPath_.size() - 1] != '/')
134      dataPath_ += "/";
135
[612]136    //TODO: Check if file exists (maybe not here)
[1021]137#if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC && defined(_DEBUG)
[715]138    std::string plugin_filename = "plugins_d.cfg";
[679]139#else
[715]140    std::string plugin_filename = "plugins.cfg";
[679]141#endif
[1024]142
[1486]143// TODO: LogManager doesn't work on specific systems. The why is unknown yet.
144#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
145    // create a logManager
[1293]146    // note: If there's already a logManager, Ogre will complain by a failed assertation.
147    // but that shouldn't happen, since this is the first time to create a logManager..
148    Ogre::LogManager* logger = new Ogre::LogManager();
149    CCOUT(4) << "Ogre LogManager created" << std::endl;
[1024]150
151    // create our own log that we can listen to
[1062]152    Ogre::Log *myLog;
[1024]153    if (this->ogreLogfile_ == "")
154      myLog = logger->createLog("ogre.log", true, false, true);
155    else
[1493]156      myLog = logger->createLog(this->ogreLogfile_, true, false, false);
[1293]157    CCOUT(4) << "Ogre Log created" << std::endl;
[1024]158
[1062]159    myLog->setLogDetail(Ogre::LL_BOREME);
[1486]160    myLog->addListener(this);
161#endif
[1024]162
163    // Root will detect that we've already created a Log
[1293]164    CCOUT(4) << "Creating Ogre Root..." << std::endl;
[1493]165
166    root_ = new Ogre::Root(plugin_filename, "ogre.cfg", this->ogreLogfile_);
167
168#if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32
169    // tame the ogre ouput so we don't get all the mess in the console
170    Ogre::Log* defaultLog = Ogre::LogManager::getSingleton().getDefaultLog();
171    defaultLog->setDebugOutputEnabled(false);
172    defaultLog->setLogDetail(Ogre::LL_BOREME);
173    defaultLog->addListener(this);
174#endif
175
[1293]176    CCOUT(4) << "Creating Ogre Root done" << std::endl;
[612]177
[1293]178    // specify where Ogre has to look for resources. This call doesn't parse anything yet!
179    declareRessourceLocations();
[612]180
[1293]181    CCOUT(3) << "Set up done." << std::endl;
[612]182    return true;
183  }
184
[1293]185  void GraphicsEngine::declareRessourceLocations()
[612]186  {
[1293]187    CCOUT(4) << "Declaring Resources" << std::endl;
[612]188    //TODO: Specify layout of data file and maybe use xml-loader
189    //TODO: Work with ressource groups (should be generated by a special loader)
190    // Load resource paths from data file using configfile ressource type
[1052]191    Ogre::ConfigFile cf;
[1293]192    cf.load(dataPath_ + "resources.cfg");
[612]193
194    // Go through all sections & settings in the file
[1052]195    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
[612]196
[715]197    std::string secName, typeName, archName;
[612]198    while (seci.hasMoreElements())
199    {
200      secName = seci.peekNextKey();
[1052]201      Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
202      Ogre::ConfigFile::SettingsMultiMap::iterator i;
[612]203      for (i = settings->begin(); i != settings->end(); ++i)
204      {
205        typeName = i->first; // for instance "FileSystem" or "Zip"
206        archName = i->second; // name (and location) of archive
207
[1052]208        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
[1293]209                                           std::string(dataPath_ + archName),
[612]210                                           typeName, secName);
211      }
212    }
213  }
214
[1293]215  bool GraphicsEngine::loadRenderer()
216  {
217    CCOUT(4) << "Configuring Renderer" << std::endl;
218    if (!root_->restoreConfig() && !root_->showConfigDialog())
219      return false;
220
221    CCOUT(4) << "Creating render window" << std::endl;
222    this->renderWindow_ = root_->initialise(true, "OrxonoxV2");
223    if (!root_->isInitialised())
224    {
225      CCOUT(2) << "Error: Creating Ogre root object failed" << std::endl;
226      return false;
227    }
228    Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, this);
229    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
230    return true;
231  }
232
233  bool GraphicsEngine::initialiseResources()
234  {
235    CCOUT(4) << "Initialising resources" << std::endl;
236    //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
237    try
238    {
239      Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
240      /*Ogre::StringVector str = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
241      for (unsigned int i = 0; i < str.size(); i++)
242      {
243        Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(str[i]);
244      }*/
245    }
246    catch (Ogre::Exception e)
247    {
248      CCOUT(2) << "Error: There was an Error when initialising the resources." << std::endl;
249      CCOUT(2) << "ErrorMessage: " << e.getFullDescription() << std::endl;
250      return false;
251    }
252    return true;
253  }
254
[1021]255  /**
[1293]256   * @brief Creates the SceneManager
257   */
258  bool GraphicsEngine::createNewScene()
259  {
[1493]260    CCOUT(4) << "Creating new SceneManager..." << std::endl;
[1293]261    if (scene_)
262    {
263      CCOUT(2) << "SceneManager already exists! Skipping." << std::endl;
264      return false;
265    }
266    scene_ = root_->createSceneManager(Ogre::ST_GENERIC, "Default SceneManager");
267    CCOUT(3) << "Created SceneManager: " << scene_ << std::endl;
268    return true;
269  }
270
271  /**
[1021]272    Returns the window handle of the render window.
273    At least the InputHandler uses this to create the OIS::InputManager
274    @return The window handle of the render window
275  */
276  size_t GraphicsEngine::getWindowHandle()
277  {
278    if (this->renderWindow_)
279    {
[1024]280      size_t windowHnd = 0;
[1032]281      this->renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
[1024]282      return windowHnd;
283    }
[1021]284    else
285      return 0;
286  }
[612]287
[1021]288  /**
289    Get the width of the current render window
290    @return The width of the current render window
291  */
292  int GraphicsEngine::getWindowWidth() const
293  {
294    if (this->renderWindow_)
295      return this->renderWindow_->getWidth();
296    else
297      return 0;
298  }
299
300  /**
301    Get the height of the current render window
302    @return The height of the current render window
303  */
304  int GraphicsEngine::getWindowHeight() const
305  {
306    if (this->renderWindow_)
307      return this->renderWindow_->getHeight();
308    else
309      return 0;
310  }
[1494]311  /**    @brief Returns the window aspect ratio height/width.    @return The ratio  */  float GraphicsEngine::getWindowAspectRatio() const  {    if (this->renderWindow_)        return (float)this->renderWindow_->getHeight() / (float)this->renderWindow_->getWidth();    else        return 1.0f;  }
[1024]312  /**
313    @brief Method called by the LogListener interface from Ogre.
314    We use it to capture Ogre log messages and handle it ourselves.
315    @param message The message to be logged
316    @param lml The message level the log is using
317    @param maskDebug If we are printing to the console or not
318    @param logName the name of this log (so you can have several listeners
319                   for different logs, and identify them)
320  */
321  void GraphicsEngine::messageLogged(const std::string& message,
[1052]322    Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName)
[1024]323  {
324    int orxonoxLevel;
325    switch (lml)
326    {
[1052]327      case Ogre::LML_TRIVIAL:
[1024]328        orxonoxLevel = this->ogreLogLevelTrivial_;
329        break;
[1052]330      case Ogre::LML_NORMAL:
[1024]331        orxonoxLevel = this->ogreLogLevelNormal_;
332        break;
[1052]333      case Ogre::LML_CRITICAL:
[1024]334        orxonoxLevel = this->ogreLogLevelCritical_;
335        break;
336      default:
337        orxonoxLevel = 0;
338    }
339    OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
[1293]340        << "Ogre: " << message << std::endl;
[1024]341  }
[1214]342
[1293]343  /**
344  * Window has resized.
345  * @param rw The render window it occured in
346  */
347  void GraphicsEngine::windowMoved(Ogre::RenderWindow *rw)
348  {
349    // note: this doesn't change the window extents
350  }
[1214]351
[1293]352  /**
353  * Window has resized.
354  * @param rw The render window it occured in
355  * @note GraphicsEngine has a render window stored itself. This is the same
356  *       as rw. But we have to be careful when using multiple render windows!
357  */
[1494]358  void GraphicsEngine::windowResized(Ogre::RenderWindow *rw)  {    // change the mouse clipping size for absolute mouse movements
[1293]359    int w = rw->getWidth();
360    int h = rw->getHeight();
361    InputManager::setWindowExtents(w, h);
[1446]362    InGameConsole::getInstance().resize();
[1293]363  }
[1214]364
[1293]365  /**
366  * Window has resized.
367  * @param rw The render window it occured in
368  */
369  void GraphicsEngine::windowFocusChanged(Ogre::RenderWindow *rw)
370  {
371    // note: this doesn't change the window extents
372  }
373
374  /**
375  * Window has resized.
376  * @param rw The render window it occured in
377  */
378  void GraphicsEngine::windowClosed(Ogre::RenderWindow *rw)
379  {
380    // using CommandExecutor in order to avoid depending on Orxonox class.
381    CommandExecutor::execute("exit", false);
382  }
[1466]383
384  //HACK!!
[1487]385  /*SetConsoleCommandShortcut(GraphicsEngine, CompositorBloomOn).setAccessLevel(AccessLevel::User);
386  SetConsoleCommandShortcut(GraphicsEngine, CompositorMotionBlurOn).setAccessLevel(AccessLevel::User);
387  SetConsoleCommandShortcut(GraphicsEngine, CompositorBloomOff).setAccessLevel(AccessLevel::User);
388  SetConsoleCommandShortcut(GraphicsEngine, CompositorMotionBlurOff).setAccessLevel(AccessLevel::User);
[1466]389  void GraphicsEngine::CompositorBloomOn()
390  {
391    Ogre::SceneManager* mSceneMgr = GraphicsEngine::getSingleton().getSceneManager();
392    Ogre::Viewport* mViewport = mSceneMgr->getCurrentViewport();
393    Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "Bloom");
394    Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Bloom", true);
395  }
396  void GraphicsEngine::CompositorBloomOff()
397  {
398    Ogre::SceneManager* mSceneMgr = GraphicsEngine::getSingleton().getSceneManager();
399    Ogre::Viewport* mViewport = mSceneMgr->getCurrentViewport();
400    Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Bloom", false);
401  }
402
403  void GraphicsEngine::CompositorMotionBlurOn()
404  {
405    Ogre::SceneManager* mSceneMgr = GraphicsEngine::getSingleton().getSceneManager();
406    Ogre::Viewport* mViewport = mSceneMgr->getCurrentViewport();
407    Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "MotionBlur");
408    Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "MotionBlur", true);
409  }
410  void GraphicsEngine::CompositorMotionBlurOff()
411  {
412    Ogre::SceneManager* mSceneMgr = GraphicsEngine::getSingleton().getSceneManager();
413    Ogre::Viewport* mViewport = mSceneMgr->getCurrentViewport();
414    Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "MotionBlur", false);
[1487]415  }*/
[612]416}
Note: See TracBrowser for help on using the repository browser.