Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation3/src/libraries/tools/bsp/ExampleFrameListener.h @ 7073

Last change on this file since 7073 was 7073, checked in by landauf, 14 years ago

merged fps branch to presentation3

  • Property svn:eol-style set to native
File size: 12.1 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-----------------------------------------------------------------------------
16Filename:    ExampleFrameListener.h
17Description: Defines an example frame listener which responds to frame events.
18This frame listener just moves a specified camera around based on
19keyboard and mouse movements.
20Mouse:    Freelook
21W or Up:  Forward
22S or Down:Backward
23A:        Step left
24D:        Step right
25             PgUp:     Move upwards
26             PgDown:   Move downwards
27             F:        Toggle frame rate stats on/off
28                         R:        Render mode
29             T:        Cycle texture filtering
30                       Bilinear, Trilinear, Anisotropic(8)
31             P:        Toggle on/off display of camera position / orientation
32-----------------------------------------------------------------------------
33*/
34
35#ifndef __ExampleFrameListener_H__
36#define __ExampleFrameListener_H__
37
38#include "Ogre.h"
39#include "OgreStringConverter.h"
40#include "OgreException.h"
41
42//Use this define to signify OIS will be used as a DLL
43//(so that dll import/export macros are in effect)
44#ifndef OIS_DYNAMIC_LIB
45#  define OIS_DYNAMIC_LIB
46#endif
47#include <OIS/OIS.h>
48
49using namespace Ogre;
50
51class ExampleFrameListener: public FrameListener, public WindowEventListener
52{
53protected:
54        virtual void updateStats(void)
55        {
56                static String currFps = "Current FPS: ";
57                static String avgFps = "Average FPS: ";
58                static String bestFps = "Best FPS: ";
59                static String worstFps = "Worst FPS: ";
60                static String tris = "Triangle Count: ";
61                static String batches = "Batch Count: ";
62
63                // update stats when necessary
64                try {
65                        OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
66                        OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
67                        OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
68                        OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
69
70                        const RenderTarget::FrameStats& stats = mWindow->getStatistics();
71                        guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
72                        guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
73                        guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
74                                +" "+StringConverter::toString(stats.bestFrameTime)+" ms");
75                        guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
76                                +" "+StringConverter::toString(stats.worstFrameTime)+" ms");
77
78                        OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
79                        guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));
80
81                        OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");
82                        guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));
83
84                        OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
85                        guiDbg->setCaption(mDebugText);
86                }
87                catch(...) { /* ignore */ }
88        }
89
90public:
91        // Constructor takes a RenderWindow because it uses that to determine input context
92        ExampleFrameListener(RenderWindow* win, Camera* cam, bool bufferedKeys = false, bool bufferedMouse = false,
93                             bool bufferedJoy = false ) :
94                mCamera(cam), mTranslateVector(Vector3::ZERO), mCurrentSpeed(0), mWindow(win), mStatsOn(true), mNumScreenShots(0),
95                mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR),
96                mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0),
97                mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0)
98        {
99
100                mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
101
102                LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
103                OIS::ParamList pl;
104                size_t windowHnd = 0;
105                std::ostringstream windowHndStr;
106
107                win->getCustomAttribute("WINDOW", &windowHnd);
108                windowHndStr << windowHnd;
109                pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
110
111                mInputManager = OIS::InputManager::createInputSystem( pl );
112
113                //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
114                mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys ));
115                mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, bufferedMouse ));
116                try {
117                        mJoy = static_cast<OIS::JoyStick*>(mInputManager->createInputObject( OIS::OISJoyStick, bufferedJoy ));
118                }
119                catch(...) {
120                        mJoy = 0;
121                }
122
123                //Set initial mouse clipping size
124                windowResized(mWindow);
125
126                showDebugOverlay(true);
127
128                //Register as a Window listener
129                WindowEventUtilities::addWindowEventListener(mWindow, this);
130        }
131
132        //Adjust mouse clipping area
133        virtual void windowResized(RenderWindow* rw)
134        {
135                unsigned int width, height, depth;
136                int left, top;
137                rw->getMetrics(width, height, depth, left, top);
138
139                const OIS::MouseState &ms = mMouse->getMouseState();
140                ms.width = width;
141                ms.height = height;
142        }
143
144        //Unattach OIS before window shutdown (very important under Linux)
145        virtual void windowClosed(RenderWindow* rw)
146        {
147                //Only close for window that created OIS (the main window in these demos)
148                if( rw == mWindow )
149                {
150                        if( mInputManager )
151                        {
152                                mInputManager->destroyInputObject( mMouse );
153                                mInputManager->destroyInputObject( mKeyboard );
154                                mInputManager->destroyInputObject( mJoy );
155
156                                OIS::InputManager::destroyInputSystem(mInputManager);
157                                mInputManager = 0;
158                        }
159                }
160        }
161
162        virtual ~ExampleFrameListener()
163        {
164                //Remove ourself as a Window listener
165                WindowEventUtilities::removeWindowEventListener(mWindow, this);
166                windowClosed(mWindow);
167        }
168
169        virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
170        {
171
172                if(mKeyboard->isKeyDown(OIS::KC_A))
173                        mTranslateVector.x = -mMoveScale;       // Move camera left
174
175                if(mKeyboard->isKeyDown(OIS::KC_D))
176                        mTranslateVector.x = mMoveScale;        // Move camera RIGHT
177
178                if(mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W) )
179                        mTranslateVector.z = -mMoveScale;       // Move camera forward
180
181                if(mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S) )
182                        mTranslateVector.z = mMoveScale;        // Move camera backward
183
184                if(mKeyboard->isKeyDown(OIS::KC_PGUP))
185                        mTranslateVector.y = mMoveScale;        // Move camera up
186
187                if(mKeyboard->isKeyDown(OIS::KC_PGDOWN))
188                        mTranslateVector.y = -mMoveScale;       // Move camera down
189
190                if(mKeyboard->isKeyDown(OIS::KC_RIGHT))
191                        mCamera->yaw(-mRotScale);
192
193                if(mKeyboard->isKeyDown(OIS::KC_LEFT))
194                        mCamera->yaw(mRotScale);
195
196                if( mKeyboard->isKeyDown(OIS::KC_ESCAPE) || mKeyboard->isKeyDown(OIS::KC_Q) )
197                        return false;
198
199        if( mKeyboard->isKeyDown(OIS::KC_F) && mTimeUntilNextToggle <= 0 )
200                {
201                        mStatsOn = !mStatsOn;
202                        showDebugOverlay(mStatsOn);
203                        mTimeUntilNextToggle = 1;
204                }
205
206                if( mKeyboard->isKeyDown(OIS::KC_T) && mTimeUntilNextToggle <= 0 )
207                {
208                        switch(mFiltering)
209                        {
210                        case TFO_BILINEAR:
211                                mFiltering = TFO_TRILINEAR;
212                                mAniso = 1;
213                                break;
214                        case TFO_TRILINEAR:
215                                mFiltering = TFO_ANISOTROPIC;
216                                mAniso = 8;
217                                break;
218                        case TFO_ANISOTROPIC:
219                                mFiltering = TFO_BILINEAR;
220                                mAniso = 1;
221                                break;
222                        default: break;
223                        }
224                        MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
225                        MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
226
227                        showDebugOverlay(mStatsOn);
228                        mTimeUntilNextToggle = 1;
229                }
230
231                if(mKeyboard->isKeyDown(OIS::KC_SYSRQ) && mTimeUntilNextToggle <= 0)
232                {
233                        std::ostringstream ss;
234                        ss << "screenshot_" << ++mNumScreenShots << ".png";
235                        mWindow->writeContentsToFile(ss.str());
236                        mTimeUntilNextToggle = 0.5;
237                        mDebugText = "Saved: " + ss.str();
238                }
239
240                if(mKeyboard->isKeyDown(OIS::KC_R) && mTimeUntilNextToggle <=0)
241                {
242                        mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
243                        switch(mSceneDetailIndex) {
244                                case 0 : mCamera->setPolygonMode(PM_SOLID); break;
245                                case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break;
246                                case 2 : mCamera->setPolygonMode(PM_POINTS); break;
247                        }
248                        mTimeUntilNextToggle = 0.5;
249                }
250
251                static bool displayCameraDetails = false;
252                if(mKeyboard->isKeyDown(OIS::KC_P) && mTimeUntilNextToggle <= 0)
253                {
254                        displayCameraDetails = !displayCameraDetails;
255                        mTimeUntilNextToggle = 0.5;
256                        if (!displayCameraDetails)
257                                mDebugText = "";
258                }
259
260                // Print camera details
261                if(displayCameraDetails)
262                        mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
263                                                 " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation());
264
265                // Return true to continue rendering
266                return true;
267        }
268
269        virtual bool processUnbufferedMouseInput(const FrameEvent& evt)
270        {
271
272                // Rotation factors, may not be used if the second mouse button is pressed
273                // 2nd mouse button - slide, otherwise rotate
274                const OIS::MouseState &ms = mMouse->getMouseState();
275                if( ms.buttonDown( OIS::MB_Right ) )
276                {
277                        mTranslateVector.x += ms.X.rel * 0.13;
278                        mTranslateVector.y -= ms.Y.rel * 0.13;
279                }
280                else
281                {
282                        mRotX = Degree(-ms.X.rel * 0.13);
283                        mRotY = Degree(-ms.Y.rel * 0.13);
284                }
285
286                return true;
287        }
288
289        virtual void moveCamera()
290        {
291                // Make all the changes to the camera
292                // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW
293                //(e.g. airplane)
294                mCamera->yaw(mRotX);
295                mCamera->pitch(mRotY);
296                mCamera->moveRelative(mTranslateVector);
297        }
298
299        virtual void showDebugOverlay(bool show)
300        {
301                if (mDebugOverlay)
302                {
303                        if (show)
304                                mDebugOverlay->show();
305                        else
306                                mDebugOverlay->hide();
307                }
308        }
309
310        // Override frameRenderingQueued event to process that (don't care about frameEnded)
311        bool frameRenderingQueued(const FrameEvent& evt)
312        {
313
314                if(mWindow->isClosed()) return false;
315
316                mSpeedLimit = mMoveScale * evt.timeSinceLastFrame;
317
318                //Need to capture/update each device
319                mKeyboard->capture();
320                mMouse->capture();
321                if( mJoy ) mJoy->capture();
322
323                bool buffJ = (mJoy) ? mJoy->buffered() : true;
324
325        Ogre::Vector3 lastMotion = mTranslateVector;
326
327                //Check if one of the devices is not buffered
328                if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
329                {
330                        // one of the input modes is immediate, so setup what is needed for immediate movement
331                        if (mTimeUntilNextToggle >= 0)
332                                mTimeUntilNextToggle -= evt.timeSinceLastFrame;
333
334                        // Move about 100 units per second
335                        mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
336                        // Take about 10 seconds for full rotation
337                        mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
338
339                        mRotX = 0;
340                        mRotY = 0;
341                        mTranslateVector = Ogre::Vector3::ZERO;
342
343                }
344
345                //Check to see which device is not buffered, and handle it
346                if( !mKeyboard->buffered() )
347                        if( processUnbufferedKeyInput(evt) == false )
348                                return false;
349                if( !mMouse->buffered() )
350                        if( processUnbufferedMouseInput(evt) == false )
351                                return false;
352
353                // ramp up / ramp down speed
354        if (mTranslateVector == Ogre::Vector3::ZERO)
355                {
356                        // decay (one third speed)
357                        mCurrentSpeed -= evt.timeSinceLastFrame * 0.3;
358                        mTranslateVector = lastMotion;
359                }
360                else
361                {
362                        // ramp up
363                        mCurrentSpeed += evt.timeSinceLastFrame;
364
365                }
366                // Limit motion speed
367                if (mCurrentSpeed > 1.0)
368                        mCurrentSpeed = 1.0;
369                if (mCurrentSpeed < 0.0)
370                        mCurrentSpeed = 0.0;
371
372                mTranslateVector *= mCurrentSpeed;
373
374
375                if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
376                        moveCamera();
377
378                return true;
379        }
380
381        bool frameEnded(const FrameEvent& evt)
382        {
383                updateStats();
384                return true;
385        }
386
387protected:
388        Camera* mCamera;
389
390        Vector3 mTranslateVector;
391        Real mCurrentSpeed;
392        RenderWindow* mWindow;
393        bool mStatsOn;
394
395        std::string mDebugText;
396
397        unsigned int mNumScreenShots;
398        float mMoveScale;
399        float mSpeedLimit;
400        Degree mRotScale;
401        // just to stop toggles flipping too fast
402        Real mTimeUntilNextToggle ;
403        Radian mRotX, mRotY;
404        TextureFilterOptions mFiltering;
405        int mAniso;
406
407        int mSceneDetailIndex ;
408        Real mMoveSpeed;
409        Degree mRotateSpeed;
410        Overlay* mDebugOverlay;
411
412        //OIS Input devices
413        OIS::InputManager* mInputManager;
414        OIS::Mouse*    mMouse;
415        OIS::Keyboard* mKeyboard;
416        OIS::JoyStick* mJoy;
417};
418
419#endif
Note: See TracBrowser for help on using the repository browser.