Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2790 was 2790, checked in by bknecht, 15 years ago

Ugly hack to use GUI ingame. Hack itself needs improvement AND of course it should be hackfree!

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