Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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