Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2710 was 2710, checked in by rgrieder, 15 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

  • Property svn:eol-style set to native
File size: 11.9 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.file_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::loadScenes()
195    {
196        // first of all, we need to have our own SceneManager for the GUI. The reason
197        // is that we might have multiple viewports when in play mode (e.g. the view of
198        // a camera fixed at the back of the ship). That forces us to create our own
199        // full screen viewport that is on top of all the others, but doesn't clear the
200        // port before rendering, so everything from the GUI gets on top eventually.
201        // But in order to realise that, we also need a SceneManager with an empty scene,
202        // because the SceneManager is responsible for the render queue.
203        //this->emptySceneManager_ = Ogre::Root::getSingleton()
204        //    .createSceneManager(Ogre::ST_GENERIC, "GUI/EmptySceneManager");
205
206        // we also need a camera or we won't see anything at all.
207        // The camera settings don't matter at all for an empty scene since the GUI
208        // gets rendered on top of the screen rather than into the scene.
209        //this->emptyCamera_ = this->emptySceneManager_->createCamera("GUI/EmptyCamera");
210
211        // Create another SceneManager that enables to display some 3D
212        // scene in the background of the main menu.
213        this->backgroundSceneManager_ = Ogre::Root::getSingleton()
214            .createSceneManager(Ogre::ST_GENERIC, "GUI/BackgroundSceneManager");
215        this->backgroundCamera_ = backgroundSceneManager_->createCamera("GUI/BackgroundCamera");
216
217        // TODO: create something 3D
218        try
219        {
220            this->scriptModule_->executeScriptFile("loadGUI.lua", "GUI");
221        }
222        catch (CEGUI::Exception& ex)
223        {
224#if CEGUI_VERSION_MINOR < 6
225            throw GeneralException(ex.getMessage().c_str());
226#else
227            throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
228                ex.getFileName().c_str(), ex.getName().c_str());
229#endif
230        }
231    }
232
233    void GUIManager::showGUI(const std::string& name, Ogre::SceneManager* sceneManager)// bool showBackground)
234    {
235        if (state_ != Uninitialised)
236        {
237            if (state_ == OnDisplay)
238                hideGUI();
239
240            COUT(3) << "Loading GUI " << name << std::endl;
241            try
242            {
243                if (!sceneManager)
244                {
245                    // currently, only an image is loaded. We could do 3D, see loadBackground.
246                    //this->viewport_->setClearEveryFrame(true);
247                    this->guiRenderer_->setTargetSceneManager(this->backgroundSceneManager_);
248                    //this->viewport_->setCamera(this->backgroundCamera_);
249
250                    lua_pushboolean(this->scriptModule_->getLuaState(), true);
251                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
252                }
253                else
254                {
255                    //this->viewport_->setClearEveryFrame(false);
256                    this->guiRenderer_->setTargetSceneManager(sceneManager);
257                    //this->viewport_->setCamera(this->emptyCamera_);
258
259                    lua_pushboolean(this->scriptModule_->getLuaState(), false);
260                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
261                }
262
263                this->scriptModule_->executeScriptGlobal("showMainMenu");
264
265                InputManager::getInstance().requestEnterState("gui");
266
267                this->state_ = OnDisplay;
268            }
269            catch (CEGUI::Exception& ex)
270            {
271                COUT(2) << "Error while executing lua script. Message:\n" << ex.getMessage() << std::endl;
272            }
273            catch (...)
274            {
275                COUT(2) << "Could show a menu due to unknown reasons." << std::endl;
276            }
277        }
278        else
279        {
280            COUT(2) << "Warning: GUI Manager not yet initialised, cannot load a GUI" << std::endl;
281        }
282    }
283
284    void GUIManager::hideGUI()
285    {
286        if (this->state_ != OnDisplay)
287            return;
288        //this->viewport_->setCamera(0);
289        this->guiRenderer_->setTargetSceneManager(0);
290        this->state_ = Ready;
291        InputManager::getInstance().requestLeaveState("gui");
292    }
293
294    void GUIManager::mouseButtonPressed(MouseButtonCode::ByEnum id)
295    {
296        try
297        {
298            guiSystem_->injectMouseButtonDown(convertButton(id));
299        }
300        catch (CEGUI::ScriptException& ex)
301        {
302            // We simply ignore the exception and proceed
303            COUT(1) << ex.getMessage() << std::endl;
304        }
305    }
306
307    void GUIManager::mouseButtonReleased(MouseButtonCode::ByEnum id)
308    {
309        try
310        {
311            guiSystem_->injectMouseButtonUp(convertButton(id));
312        }
313        catch (CEGUI::ScriptException& ex)
314        {
315            // We simply ignore the exception and proceed
316            COUT(1) << ex.getMessage() << std::endl;
317        }
318    }
319
320
321    inline CEGUI::MouseButton GUIManager::convertButton(MouseButtonCode::ByEnum button)
322    {
323        switch (button)
324        {
325        case MouseButtonCode::Left:
326            return CEGUI::LeftButton;
327
328        case MouseButtonCode::Right:
329            return CEGUI::RightButton;
330
331        case MouseButtonCode::Middle:
332            return CEGUI::MiddleButton;
333
334        case MouseButtonCode::Button3:
335            return CEGUI::X1Button;
336
337        case MouseButtonCode::Button4:
338            return CEGUI::X2Button;
339
340        default:
341            return CEGUI::NoButton;
342        }
343    }
344}
Note: See TracBrowser for help on using the repository browser.