Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/orxonox/gui/GUIManager.cc @ 1646

Last change on this file since 1646 was 1646, checked in by rgrieder, 16 years ago
  • privatised InputState c'tors
  • added destruction code for GUIManager
  • fixed some issues and bugs
  • found 2400 memory leaks ;)
  • haven't done anything about it
  • converted GUIManager to Ogre Singleton
  • added NULL checkers in Loader
  • Property svn:eol-style set to native
File size: 11.0 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 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file
31    @brief Implementation of the GUIManager class.
32*/
33
34#include "OrxonoxStableHeaders.h"
35#include "GUIManager.h"
36
37#include <OgreRenderWindow.h>
38#include <OgreCEGUIRenderer.h>
39#include <OgreRoot.h>
40#include <CEGUI.h>
41#include <CEGUILua.h>
42#include "core/input/InputManager.h"
43#include "core/input/SimpleInputState.h"
44#include "core/tolua/tolua_bind.h"
45#include "core/ConsoleCommand.h"
46#include "core/Exception.h"
47#include "core/Core.h"
48#include "tolua/tolua_bind.h"
49#include "GraphicsEngine.h"
50
51extern "C" {
52#include <lualib.h>
53#include <lauxlib.h>
54}
55
56namespace orxonox
57{
58    SetConsoleCommandShortcut(GUIManager, showGUI_s).setKeybindMode(KeybindMode::OnPress);
59
60    GUIManager* GUIManager::singletonRef_s = 0;
61
62    GUIManager::GUIManager()
63        //: emptySceneManager_(0)
64        : backgroundSceneManager_(0)
65        //, emptyCamera_(0)
66        , backgroundCamera_(0)
67        //, viewport_(0)
68        , renderWindow_(0)
69        , guiRenderer_(0)
70        , resourceProvider_(0)
71        , scriptModule_(0)
72        , guiSystem_(0)
73        , state_(Uninitialised)
74    {
75        assert(singletonRef_s == 0);
76        singletonRef_s = this;
77    }
78
79    GUIManager::~GUIManager()
80    {
81        if (backgroundCamera_)
82            backgroundSceneManager_->destroyCamera(backgroundCamera_);
83
84        if (backgroundSceneManager_)
85            Ogre::Root::getSingleton().destroySceneManager(backgroundSceneManager_);
86
87        InputManager::getInstance().destroyState("gui");
88
89        if (guiSystem_)
90            delete guiSystem_;
91
92        if (scriptModule_)
93        {
94            // destroy our own tolua interfaces
95                //lua_pushnil(luaState_);
96                //lua_setglobal(luaState_, "Orxonox");
97                //lua_pushnil(luaState_);
98                //lua_setglobal(luaState_, "Core");
99            // TODO: deleting the script module fails an assertation.
100            // However there is not much we can do about it since it occurs too when
101            // we don't open Core or Orxonox. Might be a CEGUI issue.
102            // The memory leak is not a problem anyway..
103            //delete scriptModule_;
104        }
105
106        if (guiRenderer_)
107            delete guiRenderer_;
108
109        singletonRef_s = 0;
110    }
111
112    bool GUIManager::initialise()
113    {
114        using namespace CEGUI;
115        if (state_ == Uninitialised)
116        {
117            COUT(3) << "Intialising CEGUI." << std::endl;
118
119            try
120            {
121                // get the render window
122                renderWindow_ = GraphicsEngine::getSingleton().getRenderWindow();
123
124                // Full screen viewport with Z order = 0 (top most). Don't yet feed a camera (so nothing gets rendered)
125                //this->viewport_ = renderWindow_->addViewport(0, 3);
126                //this->viewport_->setOverlaysEnabled(false);
127                //this->viewport_->setShadowsEnabled(false);
128                //this->viewport_->setSkiesEnabled(false);
129                //this->viewport_->setClearEveryFrame(false);
130
131                // Note: No SceneManager specified yet
132                this->guiRenderer_ = new OgreCEGUIRenderer(renderWindow_, Ogre::RENDER_QUEUE_MAIN, true, 3000);
133                this->resourceProvider_ = guiRenderer_->createResourceProvider();
134                this->resourceProvider_->setDefaultResourceGroup("GUI");
135               
136                // setup scripting
137                this->scriptModule_ = new LuaScriptModule();
138                this->luaState_ = this->scriptModule_->getLuaState();
139
140                // create the CEGUI system singleton
141                this->guiSystem_ = new System(this->guiRenderer_, this->resourceProvider_, 0, this->scriptModule_);
142               
143                // set the log level according to ours (translate by subtracting 1)
144                Logger::getSingleton().setLoggingLevel(
145                    (LoggingLevel)(Core::getSoftDebugLevel(OutputHandler::LD_Logfile) - 1));
146               
147                // do this after 'new CEGUI::Sytem' because that creates the lua state in the first place
148                tolua_Core_open(this->scriptModule_->getLuaState());
149                tolua_Orxonox_open(this->scriptModule_->getLuaState());
150
151                // register us as input handler
152                SimpleInputState* state = InputManager::getInstance().createSimpleInputState("gui", 30);
153                state->setHandler(this);
154                state->setJoyStickHandler(new EmptyHandler());
155
156                // load the background scene
157                loadScenes();
158            }
159            catch (CEGUI::Exception& ex)
160            {
161#if CEGUI_VERSION_MINOR < 6
162                throw GeneralException(ex.getMessage().c_str());
163#else
164                throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
165                    ex.getFileName().c_str(), ex.getName().c_str());
166#endif
167            }
168
169            state_ = Ready;
170        }
171       
172        return true;
173    }
174
175    void GUIManager::loadScenes()
176    {
177        // first of all, we need to have our own SceneManager for the GUI. The reason
178        // is that we might have multiple viewports when in play mode (e.g. the view of
179        // a camera fixed at the back of the ship). That forces us to create our own
180        // full screen viewport that is on top of all the others, but doesn't clear the
181        // port before rendering, so everything from the GUI gets on top eventually.
182        // But in order to realise that, we also need a SceneManager with an empty scene,
183        // because the SceneManager is responsible for the render queue.
184        //this->emptySceneManager_ = Ogre::Root::getSingleton()
185        //    .createSceneManager(Ogre::ST_GENERIC, "GUI/EmptySceneManager");
186
187        // we also need a camera or we won't see anything at all.
188        // The camera settings don't matter at all for an empty scene since the GUI
189        // gets rendered on top of the screen rather than into the scene.
190        //this->emptyCamera_ = this->emptySceneManager_->createCamera("GUI/EmptyCamera");
191
192        // Create another SceneManager that enables to display some 3D
193        // scene in the background of the main menu.
194        this->backgroundSceneManager_ = Ogre::Root::getSingleton()
195            .createSceneManager(Ogre::ST_GENERIC, "GUI/BackgroundSceneManager");
196        this->backgroundCamera_ = backgroundSceneManager_->createCamera("GUI/BackgroundCamera");
197
198        // TODO: create something 3D
199        try
200        {
201            this->scriptModule_->executeScriptFile("loadGUI.lua", "GUI");
202        }
203        catch (CEGUI::Exception& ex)
204        {
205#if CEGUI_VERSION_MINOR < 6
206            throw GeneralException(ex.getMessage().c_str());
207#else
208            throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
209                ex.getFileName().c_str(), ex.getName().c_str());
210#endif
211        }
212    }
213
214    void GUIManager::showGUI(const std::string& name, Ogre::SceneManager* sceneManager)// bool showBackground)
215    {
216        if (state_ != Uninitialised)
217        {
218            if (state_ == OnDisplay)
219                _hideGUI();
220
221            COUT(3) << "Loading GUI " << name << std::endl;
222            try
223            {
224                if (!sceneManager)
225                {
226                    // currently, only an image is loaded. We could do 3D, see loadBackground.
227                    //this->viewport_->setClearEveryFrame(true);
228                    this->guiRenderer_->setTargetSceneManager(this->backgroundSceneManager_);
229                    //this->viewport_->setCamera(this->backgroundCamera_);
230
231                    lua_pushboolean(this->scriptModule_->getLuaState(), true);
232                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
233                }
234                else
235                {
236                    //this->viewport_->setClearEveryFrame(false);
237                    this->guiRenderer_->setTargetSceneManager(sceneManager);
238                    //this->viewport_->setCamera(this->emptyCamera_);
239
240                    lua_pushboolean(this->scriptModule_->getLuaState(), false);
241                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
242                }
243
244                this->scriptModule_->executeScriptGlobal("showMainMenu");
245
246                InputManager::getInstance().requestEnterState("gui");
247
248                this->state_ = OnDisplay;
249            }
250            catch (CEGUI::Exception& ex)
251            {
252                COUT(2) << "Error while executing lua script. Message:\n" << ex.getMessage() << std::endl;
253            }
254            catch (...)
255            {
256                COUT(2) << "Could show a menu due to unknown reasons." << std::endl;
257            }
258        }
259        else
260        {
261            COUT(2) << "Warning: GUI Manager not yet initialised, cannot load a GUI" << std::endl;
262        }
263    }
264
265    void GUIManager::_hideGUI()
266    {
267        if (this->state_ != OnDisplay)
268            return;
269        //this->viewport_->setCamera(0);
270        this->guiRenderer_->setTargetSceneManager(0);
271        this->state_ = Ready;
272        InputManager::getInstance().requestLeaveState("gui");
273    }
274
275    void GUIManager::mouseButtonPressed(MouseButton::Enum id)
276    {
277        try
278        {
279            guiSystem_->injectMouseButtonDown(convertButton(id));
280        }
281        catch (CEGUI::ScriptException& ex)
282        {
283            // We simply ignore the exception and proceed
284            COUT(1) << ex.getMessage() << std::endl;
285        }
286    }
287
288    void GUIManager::mouseButtonReleased(MouseButton::Enum id)
289    {
290        try
291        {
292            guiSystem_->injectMouseButtonUp(convertButton(id));
293        }
294        catch (CEGUI::ScriptException& ex)
295        {
296            // We simply ignore the exception and proceed
297            COUT(1) << ex.getMessage() << std::endl;
298        }
299    }
300
301
302    inline CEGUI::MouseButton GUIManager::convertButton(MouseButton::Enum button)
303    {
304        switch (button)
305        {
306        case MouseButton::Left:
307            return CEGUI::LeftButton;
308
309        case MouseButton::Right:
310            return CEGUI::RightButton;
311
312        case MouseButton::Middle:
313            return CEGUI::MiddleButton;
314
315        case MouseButton::Button3:
316            return CEGUI::X1Button;
317
318        case MouseButton::Button4:
319            return CEGUI::X2Button;
320
321        default:
322            return CEGUI::NoButton;
323        }
324    }
325}
Note: See TracBrowser for help on using the repository browser.