Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1447 was 1446, checked in by landauf, 17 years ago

merged console branch into network branch

after several heavy troubles it compiles, but there is still a bug I couldn't fix: orxonox crashes as soon as one presses a key after opening the console… maybe someone else sees the problem?

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#include "console/InGameConsole.h"
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    // note: If there's already a logManager, Ogre will complain by a failed assertation.
141    // but that shouldn't happen, since this is the first time to create a logManager..
142    Ogre::LogManager* logger = new Ogre::LogManager();
143    CCOUT(4) << "Ogre LogManager created" << std::endl;
144
145    // create our own log that we can listen to
146    Ogre::Log *myLog;
147    if (this->ogreLogfile_ == "")
148      myLog = logger->createLog("ogre.log", true, false, true);
149    else
150          myLog = logger->createLog(this->ogreLogfile_, true, false, false);
151    CCOUT(4) << "Ogre Log created" << std::endl;
152
153    myLog->setLogDetail(Ogre::LL_BOREME);
154    myLog->addListener(this);*/
155
156    // Root will detect that we've already created a Log
157    CCOUT(4) << "Creating Ogre Root..." << std::endl;
158    root_ = new Ogre::Root(plugin_filename);
159    CCOUT(4) << "Creating Ogre Root done" << std::endl;
160
161    // specify where Ogre has to look for resources. This call doesn't parse anything yet!
162    declareRessourceLocations();
163
164    CCOUT(3) << "Set up done." << std::endl;
165    return true;
166  }
167
168  void GraphicsEngine::declareRessourceLocations()
169  {
170    CCOUT(4) << "Declaring Resources" << std::endl;
171    //TODO: Specify layout of data file and maybe use xml-loader
172    //TODO: Work with ressource groups (should be generated by a special loader)
173    // Load resource paths from data file using configfile ressource type
174    Ogre::ConfigFile cf;
175    cf.load(dataPath_ + "resources.cfg");
176
177    // Go through all sections & settings in the file
178    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
179
180    std::string secName, typeName, archName;
181    while (seci.hasMoreElements())
182    {
183      secName = seci.peekNextKey();
184      Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
185      Ogre::ConfigFile::SettingsMultiMap::iterator i;
186      for (i = settings->begin(); i != settings->end(); ++i)
187      {
188        typeName = i->first; // for instance "FileSystem" or "Zip"
189        archName = i->second; // name (and location) of archive
190
191        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
192                                           std::string(dataPath_ + archName),
193                                           typeName, secName);
194      }
195    }
196  }
197
198  bool GraphicsEngine::loadRenderer()
199  {
200    CCOUT(4) << "Configuring Renderer" << std::endl;
201    if (!root_->restoreConfig() && !root_->showConfigDialog())
202      return false;
203
204    CCOUT(4) << "Creating render window" << std::endl;
205    this->renderWindow_ = root_->initialise(true, "OrxonoxV2");
206    if (!root_->isInitialised())
207    {
208      CCOUT(2) << "Error: Creating Ogre root object failed" << std::endl;
209      return false;
210    }
211    Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, this);
212    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
213    return true;
214  }
215
216  bool GraphicsEngine::initialiseResources()
217  {
218    CCOUT(4) << "Initialising resources" << std::endl;
219    //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
220    try
221    {
222      Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
223      /*Ogre::StringVector str = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
224      for (unsigned int i = 0; i < str.size(); i++)
225      {
226        Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(str[i]);
227      }*/
228    }
229    catch (Ogre::Exception e)
230    {
231      CCOUT(2) << "Error: There was an Error when initialising the resources." << std::endl;
232      CCOUT(2) << "ErrorMessage: " << e.getFullDescription() << std::endl;
233      return false;
234    }
235    return true;
236  }
237
238  /**
239   * @brief Creates the SceneManager
240   */
241  bool GraphicsEngine::createNewScene()
242  {
243    CCOUT(4) << "Creating new SceneManager" << std::endl;
244    if (scene_)
245    {
246      CCOUT(2) << "SceneManager already exists! Skipping." << std::endl;
247      return false;
248    }
249    scene_ = root_->createSceneManager(Ogre::ST_GENERIC, "Default SceneManager");
250    CCOUT(3) << "Created SceneManager: " << scene_ << std::endl;
251    return true;
252  }
253
254  /**
255    Returns the window handle of the render window.
256    At least the InputHandler uses this to create the OIS::InputManager
257    @return The window handle of the render window
258  */
259  size_t GraphicsEngine::getWindowHandle()
260  {
261    if (this->renderWindow_)
262    {
263      size_t windowHnd = 0;
264      this->renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
265      return windowHnd;
266    }
267    else
268      return 0;
269  }
270
271  /**
272    Get the width of the current render window
273    @return The width of the current render window
274  */
275  int GraphicsEngine::getWindowWidth() const
276  {
277    if (this->renderWindow_)
278      return this->renderWindow_->getWidth();
279    else
280      return 0;
281  }
282
283  /**
284    Get the height of the current render window
285    @return The height of the current render window
286  */
287  int GraphicsEngine::getWindowHeight() const
288  {
289    if (this->renderWindow_)
290      return this->renderWindow_->getHeight();
291    else
292      return 0;
293  }
294
295  /**
296    @brief Method called by the LogListener interface from Ogre.
297    We use it to capture Ogre log messages and handle it ourselves.
298    @param message The message to be logged
299    @param lml The message level the log is using
300    @param maskDebug If we are printing to the console or not
301    @param logName the name of this log (so you can have several listeners
302                   for different logs, and identify them)
303  */
304  void GraphicsEngine::messageLogged(const std::string& message,
305    Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName)
306  {
307    int orxonoxLevel;
308    switch (lml)
309    {
310      case Ogre::LML_TRIVIAL:
311        orxonoxLevel = this->ogreLogLevelTrivial_;
312        break;
313      case Ogre::LML_NORMAL:
314        orxonoxLevel = this->ogreLogLevelNormal_;
315        break;
316      case Ogre::LML_CRITICAL:
317        orxonoxLevel = this->ogreLogLevelCritical_;
318        break;
319      default:
320        orxonoxLevel = 0;
321    }
322    OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
323        << "Ogre: " << message << std::endl;
324  }
325
326  /**
327  * Window has resized.
328  * @param rw The render window it occured in
329  */
330  void GraphicsEngine::windowMoved(Ogre::RenderWindow *rw)
331  {
332    // note: this doesn't change the window extents
333  }
334
335  /**
336  * Window has resized.
337  * @param rw The render window it occured in
338  * @note GraphicsEngine has a render window stored itself. This is the same
339  *       as rw. But we have to be careful when using multiple render windows!
340  */
341  void GraphicsEngine::windowResized(Ogre::RenderWindow *rw)
342  {
343    // change the mouse clipping size for absolute mouse movements
344    int w = rw->getWidth();
345    int h = rw->getHeight();
346    InputManager::setWindowExtents(w, h);
347    InGameConsole::getInstance().resize();
348  }
349
350  /**
351  * Window has resized.
352  * @param rw The render window it occured in
353  */
354  void GraphicsEngine::windowFocusChanged(Ogre::RenderWindow *rw)
355  {
356    // note: this doesn't change the window extents
357  }
358
359  /**
360  * Window has resized.
361  * @param rw The render window it occured in
362  */
363  void GraphicsEngine::windowClosed(Ogre::RenderWindow *rw)
364  {
365    // using CommandExecutor in order to avoid depending on Orxonox class.
366    CommandExecutor::execute("exit", false);
367  }
368}
Note: See TracBrowser for help on using the repository browser.