Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ReferenceApplication/Common/include/ExampleRefAppFrameListener.h @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 9.2 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10You may use this sample code for anything you like, it is not covered by the
11LGPL like the rest of the engine.
12-----------------------------------------------------------------------------
13*/
14
15/*
16-----------------------------------------------------------------------------
17Filename:    ExampleFrameListener.h
18Description: Defines an example frame listener which responds to frame events.
19             This frame listener just moves a specified camera around based on
20             keyboard and mouse movements.
21             Mouse:    Freelook
22             W or Up:  Forward
23             S or Down:Backward
24             A:           Step left
25             D:        Step right
26             PgUp:     Move upwards
27             PgDown:   Move downwards
28             O/P:       Yaw the root scene node (and it's children)
29             I/K:       Pitch the root scene node (and it's children)
30             F:           Toggle frame rate stats on/off
31-----------------------------------------------------------------------------
32*/
33
34#ifndef __ExampleRefAppFrameListener_H__
35#define __ExampleRefAppFrameListener_H__
36
37#include "OgreReferenceAppLayer.h"
38#include "OgreException.h"
39#include <OIS/OIS.h>
40
41using namespace Ogre;
42using namespace OgreRefApp;
43
44class ExampleRefAppFrameListener: public FrameListener
45{
46private:
47    void updateStats(void)
48    {
49        static String currFps = "Current FPS: ";
50        static String avgFps = "Average FPS: ";
51        static String bestFps = "Best FPS: ";
52        static String worstFps = "Worst FPS: ";
53        static String tris = "Triangle Count: ";
54
55        // update stats when necessary
56        OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
57        OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
58        OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
59        OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
60       
61        guiAvg->setCaption(avgFps + StringConverter::toString(mWindow->getAverageFPS()));
62        guiCurr->setCaption(currFps + StringConverter::toString(mWindow->getLastFPS()));
63        guiBest->setCaption(bestFps + StringConverter::toString(mWindow->getBestFPS())
64            +" "+StringConverter::toString(mWindow->getBestFrameTime())+" ms");
65        guiWorst->setCaption(worstFps + StringConverter::toString(mWindow->getWorstFPS())
66            +" "+StringConverter::toString(mWindow->getWorstFrameTime())+" ms");
67           
68        OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
69        guiTris->setCaption(tris + StringConverter::toString(mWindow->getTriangleCount()));
70
71        OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
72        guiDbg->setCaption(mDebugText);
73    }
74   
75public:
76    // Constructor takes a RenderWindow because it uses that to determine input context
77    ExampleRefAppFrameListener(RenderWindow* win, CollideCamera* cam, bool bufferedKeys = false, bool bufferedMouse = false)
78    {
79                using namespace OIS;
80                ParamList pl;   
81                size_t windowHnd = 0;
82                std::ostringstream windowHndStr;
83
84                win->getCustomAttribute("WINDOW", &windowHnd);
85                windowHndStr << windowHnd;
86                pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
87
88                mInputManager = InputManager::createInputSystem( pl );
89
90                //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
91                mKeyboard = static_cast<Keyboard*>(mInputManager->createInputObject( OISKeyboard, bufferedKeys ));
92                mMouse = static_cast<Mouse*>(mInputManager->createInputObject( OISMouse, bufferedMouse ));
93
94                unsigned int width, height, depth;
95                int left, top;
96                win->getMetrics(width, height, depth, left, top);
97
98                //Set Mouse Region.. if window resizes, we should alter this to reflect as well
99                const MouseState &ms = mMouse->getMouseState();
100                ms.width = width;
101                ms.height = height;
102
103                mCamera = cam;
104        mWindow = win;
105        mStatsOn = true;
106                mNumScreenShots = 0;
107                mTimeUntilNextToggle = 0;
108
109        showDebugOverlay(true);
110
111                mDebugText = "Press SPACE to throw the ball";
112    }
113    virtual ~ExampleRefAppFrameListener()
114    {
115                if(mInputManager)
116                {
117                        mInputManager->destroyInputObject(mMouse);
118                        mInputManager->destroyInputObject(mKeyboard);
119                        OIS::InputManager::destroyInputSystem(mInputManager);
120                        mInputManager = 0;
121                }
122    }
123
124    bool processUnbufferedKeyInput(const FrameEvent& evt)
125    {
126                using namespace OIS;
127
128                if(mKeyboard->isKeyDown(KC_A))
129                        mTranslateVector.x = -mMoveScale;       // Move camera left
130
131                if(mKeyboard->isKeyDown(KC_D))
132                        mTranslateVector.x = mMoveScale;        // Move camera RIGHT
133
134                if(mKeyboard->isKeyDown(KC_UP) || mKeyboard->isKeyDown(KC_W) )
135                        mTranslateVector.z = -mMoveScale;       // Move camera forward
136
137                if(mKeyboard->isKeyDown(KC_DOWN) || mKeyboard->isKeyDown(KC_S) )
138                        mTranslateVector.z = mMoveScale;        // Move camera backward
139
140                if(mKeyboard->isKeyDown(KC_PGUP))
141                        mTranslateVector.y = mMoveScale;        // Move camera up
142
143                if(mKeyboard->isKeyDown(KC_PGDOWN))
144                        mTranslateVector.y = -mMoveScale;       // Move camera down
145
146                if(mKeyboard->isKeyDown(KC_RIGHT))
147                        mCamera->yaw(-mRotScale);
148               
149                if(mKeyboard->isKeyDown(KC_LEFT))
150                        mCamera->yaw(mRotScale);
151
152                if( mKeyboard->isKeyDown(KC_ESCAPE) || mKeyboard->isKeyDown(KC_Q) )
153                        return false;
154
155        if( mKeyboard->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0 ) 
156                {
157                        mStatsOn = !mStatsOn;
158                        showDebugOverlay(mStatsOn);
159                        mTimeUntilNextToggle = 1;
160                }
161
162                if(mKeyboard->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
163                {
164                        std::ostringstream ss;
165                        ss << "screenshot_" << ++mNumScreenShots << ".png";
166                        mWindow->writeContentsToFile(ss.str());
167                        mTimeUntilNextToggle = 0.5;
168                        mDebugText = "Saved: " + ss.str();
169                }
170
171
172                // Return true to continue rendering
173                return true;
174    }
175
176    bool processUnbufferedMouseInput(const FrameEvent& evt)
177    {
178                using namespace OIS;
179
180                // Rotation factors, may not be used if the second mouse button is pressed
181                // 2nd mouse button - slide, otherwise rotate
182                const MouseState &ms = mMouse->getMouseState();
183                if( ms.buttonDown( MB_Right ) )
184                {
185                        mTranslateVector.x += ms.X.rel * 0.13;
186                        mTranslateVector.y -= ms.Y.rel * 0.13;
187                }
188                else
189                {
190                        mRotX = Degree(-ms.X.rel * 0.13);
191                        mRotY = Degree(-ms.Y.rel * 0.13);
192                }
193
194                return true;
195        }
196
197        void moveCamera()
198        {
199
200        // Make all the changes to the camera
201        // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW (e.g. airplane)
202        mCamera->yaw(mRotX);
203        mCamera->pitch(mRotY);
204        mCamera->translate(mTranslateVector);
205        }
206
207    void showDebugOverlay(bool show)
208    {   
209        Overlay* o = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
210        if (!o)
211            OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find overlay Core/DebugOverlay",
212                "showDebugOverlay" );
213        if (show)
214            o->show();
215        else
216            o->hide();
217    }
218
219    // Override frameEnded event
220    bool frameEnded(const FrameEvent& evt)
221    {
222                mMouse->capture();
223                mKeyboard->capture();
224
225                if( !mMouse->buffered() || !mKeyboard->buffered() )
226                {
227                        // one of the input modes is immediate, so setup what is needed for immediate mouse/key movement
228                        if (mTimeUntilNextToggle >= 0) 
229                                mTimeUntilNextToggle -= evt.timeSinceLastFrame;
230
231                        // If this is the first frame, pick a speed
232                        if (evt.timeSinceLastFrame == 0)
233                        {
234                                mMoveScale = 0.5;
235                                mRotScale = 0.1;
236                        }
237                        // Otherwise scale movement units by time passed since last frame
238                        else
239                        {
240                                // Move about 50 units per second,
241                                mMoveScale = 50.0 * evt.timeSinceLastFrame;
242                                // Take about 10 seconds for full rotation
243                                mRotScale = Degree(36 * evt.timeSinceLastFrame);
244                        }
245                        mRotX = 0;
246            mRotY = 0;
247                mTranslateVector = Vector3::ZERO;
248                }
249
250                //Check to see which device is not buffered, and handle it
251                if( !mKeyboard->buffered() )
252                        if( processUnbufferedKeyInput(evt) == false )
253                                return false;
254                if( !mMouse->buffered() )
255                        if( processUnbufferedMouseInput(evt) == false )
256                                return false;
257               
258                if( !mMouse->buffered() || !mKeyboard->buffered() )
259                        moveCamera();
260
261        // Perform simulation step
262        World::getSingleton().simulationStep(evt.timeSinceLastFrame);
263
264        updateStats();
265                return true;
266    }
267
268protected:
269        OIS::Mouse *mMouse;
270        OIS::Keyboard *mKeyboard;
271    OIS::InputManager *mInputManager;
272   
273    CollideCamera* mCamera;
274    Vector3 mTranslateVector;
275    RenderWindow* mWindow;
276    bool mStatsOn;
277        unsigned int mNumScreenShots;
278    float mMoveScale;
279    Radian mRotScale;
280    // just to stop toggles flipping too fast
281    Real mTimeUntilNextToggle ;
282    Radian mRotX, mRotY;
283
284        std::string mDebugText;
285};
286#endif
Note: See TracBrowser for help on using the repository browser.