Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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