Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ogre/src/orxonox/GraphicsEngine.cc @ 1252

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