Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/gui/GUIManager.cc @ 1766

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

Moved Exception to util now that debug has been moved.

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