Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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