Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

You can now toggle visibility ingame. Strangely the SceneManager changes after the initial enter()-function of GSStandalone. That's why - for the moment - the SceneManager is set every tick to be able to keep track of the current SceneManager.

Also there are some strange functions defined not having a real purpose aside from debug (the implementation is not clean at all, but rather full of shortcuts and functional). At least it compiles and runs ;-)

  • Property svn:eol-style set to native
File size: 13.6 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, toggleGUI).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_OVERLAY, 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("loadGUI.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::toggleGUI()
264    {
265        //COUT(0) << "********* TOGGLE TOGGLE **********" << std::endl;
266        getInstance().scriptModule_->executeScriptGlobal("toggleGUI");
267    }
268
269    void GUIManager::showGUI(const std::string& name, Ogre::SceneManager* sceneManager)// bool showBackground)
270    {
271        if (state_ != Uninitialised)
272        {
273            if (state_ == OnDisplay)
274                hideGUI();
275
276            COUT(3) << "Loading GUI " << name << std::endl;
277            try
278            {
279                // COUT (0) << "************* sceneManager: " << sceneManager << std::endl;
280                if (!sceneManager)
281                {
282                    // currently, only an image is loaded. We could do 3D, see loadBackground.
283                    //this->viewport_->setClearEveryFrame(true);
284                    this->guiRenderer_->setTargetSceneManager(this->backgroundSceneManager_);
285                    //this->viewport_->setCamera(this->backgroundCamera_);
286
287                    lua_pushboolean(this->scriptModule_->getLuaState(), true);
288                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
289                }
290                else
291                {
292                    //this->viewport_->setClearEveryFrame(false);
293                    this->guiRenderer_->setTargetSceneManager(sceneManager);
294                    currentSceneManager_ = sceneManager;
295                    //this->viewport_->setCamera(this->emptyCamera_);
296
297                    lua_pushboolean(this->scriptModule_->getLuaState(), false);
298                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
299                }
300
301                this->scriptModule_->executeScriptGlobal("showMainMenu");
302
303                InputManager::getInstance().requestEnterState("gui");
304
305                this->state_ = OnDisplay;
306            }
307            catch (CEGUI::Exception& ex)
308            {
309                COUT(2) << "Error while executing lua script. Message:\n" << ex.getMessage() << std::endl;
310            }
311            catch (...)
312            {
313                COUT(2) << "Could show a menu due to unknown reasons." << std::endl;
314            }
315        }
316        else
317        {
318            COUT(2) << "Warning: GUI Manager not yet initialised, cannot load a GUI" << std::endl;
319        }
320    }
321
322    void GUIManager::testFct()
323    {
324        //COUT(0) << "**** " << currentSceneManager_ << std::endl;
325        this->showGUI("IngameMenu", currentSceneManager_);
326    }
327
328    void GUIManager::testOutput(const std::string& str)
329    {
330        COUT(0) << "***" << str << "***" << std::endl;
331    }
332
333    void GUIManager::hideGUI()
334    {
335        if (this->state_ != OnDisplay)
336            return;
337        //this->viewport_->setCamera(0);
338        // has no effect since you cannot assign 0 as SceneManager
339        //this->guiRenderer_->setTargetSceneManager(0);
340        this->state_ = Ready;
341        InputManager::getInstance().requestLeaveState("gui");
342    }
343
344    void GUIManager::mouseButtonPressed(MouseButtonCode::ByEnum id)
345    {
346        try
347        {
348            guiSystem_->injectMouseButtonDown(convertButton(id));
349        }
350        catch (CEGUI::ScriptException& ex)
351        {
352            // We simply ignore the exception and proceed
353            COUT(1) << ex.getMessage() << std::endl;
354        }
355    }
356
357    void GUIManager::mouseButtonReleased(MouseButtonCode::ByEnum id)
358    {
359        try
360        {
361            guiSystem_->injectMouseButtonUp(convertButton(id));
362        }
363        catch (CEGUI::ScriptException& ex)
364        {
365            // We simply ignore the exception and proceed
366            COUT(1) << ex.getMessage() << std::endl;
367        }
368    }
369
370
371    inline CEGUI::MouseButton GUIManager::convertButton(MouseButtonCode::ByEnum button)
372    {
373        switch (button)
374        {
375        case MouseButtonCode::Left:
376            return CEGUI::LeftButton;
377
378        case MouseButtonCode::Right:
379            return CEGUI::RightButton;
380
381        case MouseButtonCode::Middle:
382            return CEGUI::MiddleButton;
383
384        case MouseButtonCode::Button3:
385            return CEGUI::X1Button;
386
387        case MouseButtonCode::Button4:
388            return CEGUI::X2Button;
389
390        default:
391            return CEGUI::NoButton;
392        }
393    }
394}
Note: See TracBrowser for help on using the repository browser.