Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1487 was 1487, checked in by rgrieder, 16 years ago

commented hack section in GraphicsEngine.cc in regards to shader functions

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