Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Installation paths should be relative when using in C++ code if they're actually relative.
This ensures copy & paste installations under windows. For Unix it is only useful when installation to an arbitrary folder instead of /usr
(also resolves a problem the with tcl lib path; Apparently Tcl cannot cope with spaces in the path (and neither "\") so C:/Program Files/ was not working at all)

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