Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2588 was 2570, checked in by rgrieder, 16 years ago

Removed ogreceguirenderer from the include directories because the files can get included with OgreMain, which will result in errors. The other paths (cpptcl, ois, tinyxml, tolua) are not affected by this behaviour.

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