Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2138 was 1804, checked in by rgrieder, 16 years ago

Implemented lua and ceguilua as far as it works now with visual studio. Next (not so big) step is to integrate it in CMake (already did the most part).

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