Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2512 was 2509, checked in by rgrieder, 16 years ago

Merged revisions 1875-2278 of the buildsystem branch to buildsystem2.

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