Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1776 was 1776, checked in by landauf, 16 years ago

Many changes in almost all FindXYZ.cmake files. They now throw errors if something wasn't found.

  • 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) << "Initialising 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.