Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/merge/src/orxonox/GraphicsEngine.cc @ 1268

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