source: GTP/trunk/App/Demos/Illum/IBRBillboardCloudTrees/OGRE/IBRTreesOGRE/include/ExampleFrameListener.h @ 1493

Revision 1493, 13.6 KB checked in by igarcia, 18 years ago (diff)
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-2005 The OGRE Team
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 "OgreKeyEvent.h"
40#include "OgreEventListeners.h"
41#include "OgreStringConverter.h"
42#include "OgreException.h"
43
44using namespace Ogre;
45
46class ExampleFrameListener: public FrameListener, public KeyListener
47{
48protected:
49        int mSceneDetailIndex ;
50    Real mMoveSpeed;
51    Degree mRotateSpeed;
52    Overlay* mDebugOverlay;
53
54    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
62        // update stats when necessary
63        try {
64            OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
65            OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
66            OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
67            OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
68
69            const RenderTarget::FrameStats& stats = mWindow->getStatistics();
70
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* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
82            guiDbg->setCaption(mWindow->getDebugText());
83        }
84        catch(...)
85        {
86            // ignore
87        }
88    }
89
90public:
91    // Constructor takes a RenderWindow because it uses that to determine input context
92    ExampleFrameListener(RenderWindow* win, Camera* cam, bool useBufferedInputKeys = false, bool useBufferedInputMouse = false)
93    {
94        mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
95        mUseBufferedInputKeys = useBufferedInputKeys;
96                mUseBufferedInputMouse = useBufferedInputMouse;
97                mInputTypeSwitchingOn = mUseBufferedInputKeys || mUseBufferedInputMouse;
98        mRotateSpeed = 36;
99        mMoveSpeed = 100;
100
101                if (mInputTypeSwitchingOn)
102                {
103            mEventProcessor = new EventProcessor();
104                        mEventProcessor->initialise(win);
105                        mEventProcessor->startProcessingEvents();
106                        mEventProcessor->addKeyListener(this);
107                        mInputDevice = mEventProcessor->getInputReader();
108
109                }
110        else
111        {
112            mInputDevice = PlatformManager::getSingleton().createInputReader();
113            mInputDevice->initialise(win,true, true);
114        }
115
116        mCamera = cam;
117        mWindow = win;
118        mStatsOn = true;
119                mNumScreenShots = 0;
120                mTimeUntilNextToggle = 0;
121        mSceneDetailIndex = 0;
122        mMoveScale = 0.0f;
123        mRotScale = 0.0f;
124            mTranslateVector = Vector3::ZERO;
125        mAniso = 1;
126        mFiltering = TFO_BILINEAR;
127
128        showDebugOverlay(true);
129    }
130    virtual ~ExampleFrameListener()
131    {
132                if (mInputTypeSwitchingOn)
133                {
134            delete mEventProcessor;
135                }
136        else
137        {
138            PlatformManager::getSingleton().destroyInputReader( mInputDevice );
139        }
140    }
141
142    virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
143    {
144        if (mInputDevice->isKeyDown(KC_A))
145        {
146            // Move camera left
147            mTranslateVector.x = -mMoveScale;
148        }
149
150        if (mInputDevice->isKeyDown(KC_D))
151        {
152            // Move camera RIGHT
153            mTranslateVector.x = mMoveScale;
154        }
155
156        /* Move camera forward by keypress. */
157        if (mInputDevice->isKeyDown(KC_UP) || mInputDevice->isKeyDown(KC_W) )
158        {
159            mTranslateVector.z = -mMoveScale;
160        }
161
162        /* Move camera backward by keypress. */
163        if (mInputDevice->isKeyDown(KC_DOWN) || mInputDevice->isKeyDown(KC_S) )
164        {
165            mTranslateVector.z = mMoveScale;
166        }
167
168        if (mInputDevice->isKeyDown(KC_PGUP))
169        {
170            // Move camera up
171            mTranslateVector.y = mMoveScale;
172        }
173
174        if (mInputDevice->isKeyDown(KC_PGDOWN))
175        {
176            // Move camera down
177            mTranslateVector.y = -mMoveScale;
178        }
179
180        if (mInputDevice->isKeyDown(KC_RIGHT))
181        {
182            mCamera->yaw(-mRotScale);
183        }
184               
185        if (mInputDevice->isKeyDown(KC_LEFT))
186        {
187            mCamera->yaw(mRotScale);
188        }
189
190        if( mInputDevice->isKeyDown( KC_ESCAPE) )
191        {           
192            return false;
193        }
194
195                // see if switching is on, and you want to toggle
196        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_M) && mTimeUntilNextToggle <= 0)
197        {
198                        switchMouseMode();
199            mTimeUntilNextToggle = 1;
200        }
201
202        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_K) && mTimeUntilNextToggle <= 0)
203        {
204                        // must be going from immediate keyboard to buffered keyboard
205                        switchKeyMode();
206            mTimeUntilNextToggle = 1;
207        }
208        if (mInputDevice->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0)
209        {
210            mStatsOn = !mStatsOn;
211            showDebugOverlay(mStatsOn);
212
213            mTimeUntilNextToggle = 1;
214        }
215        if (mInputDevice->isKeyDown(KC_T) && mTimeUntilNextToggle <= 0)
216        {
217            switch(mFiltering)
218            {
219            case TFO_BILINEAR:
220                mFiltering = TFO_TRILINEAR;
221                mAniso = 1;
222                break;
223            case TFO_TRILINEAR:
224                mFiltering = TFO_ANISOTROPIC;
225                mAniso = 8;
226                break;
227            case TFO_ANISOTROPIC:
228                mFiltering = TFO_BILINEAR;
229                mAniso = 1;
230                break;
231            default:
232                break;
233            }
234            MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
235            MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
236
237
238            showDebugOverlay(mStatsOn);
239
240            mTimeUntilNextToggle = 1;
241        }
242
243        if (mInputDevice->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
244        {
245                        char tmp[20];
246                        sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
247            mWindow->writeContentsToFile(tmp);
248            mTimeUntilNextToggle = 0.5;
249                        mWindow->setDebugText(String("Wrote ") + tmp);
250        }
251               
252                if (mInputDevice->isKeyDown(Ogre::KC_R) && mTimeUntilNextToggle <=0)
253                {
254                        mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
255                        switch(mSceneDetailIndex) {
256                                case 0 : mCamera->setPolygonMode(Ogre::PM_SOLID) ; break ;
257                                case 1 : mCamera->setPolygonMode(Ogre::PM_WIREFRAME) ; break ;
258                                case 2 : mCamera->setPolygonMode(Ogre::PM_POINTS) ; break ;
259                        }
260                        mTimeUntilNextToggle = 0.5;
261                }
262
263        static bool displayCameraDetails = false;
264        if (mInputDevice->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
265        {
266            displayCameraDetails = !displayCameraDetails;
267            mTimeUntilNextToggle = 0.5;
268            if (!displayCameraDetails)
269                mWindow->setDebugText("");
270        }
271        if (displayCameraDetails)
272        {
273            // Print camera details
274            mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) + " " +
275                "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
276        }
277
278        // Return true to continue rendering
279        return true;
280    }
281
282    bool processUnbufferedMouseInput(const FrameEvent& evt)
283    {
284        /* Rotation factors, may not be used if the second mouse button is pressed. */
285
286        /* If the second mouse button is pressed, then the mouse movement results in
287           sliding the camera, otherwise we rotate. */
288        if( mInputDevice->getMouseButton( 1 ) )
289        {
290            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
291            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
292        }
293        else
294        {
295            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
296            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
297        }
298
299
300                return true;
301        }
302
303        void moveCamera()
304        {
305
306        // Make all the changes to the camera
307        // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW (e.g. airplane)
308        mCamera->yaw(mRotX);
309        mCamera->pitch(mRotY);
310        mCamera->moveRelative(mTranslateVector);
311
312
313        }
314
315    void showDebugOverlay(bool show)
316    {
317        if (mDebugOverlay)
318        {
319            if (show)
320            {
321                mDebugOverlay->show();
322            }
323            else
324            {
325                mDebugOverlay->hide();
326            }
327        }
328    }
329
330    // Override frameStarted event to process that (don't care about frameEnded)
331    bool frameStarted(const FrameEvent& evt)
332    {
333        if(mWindow->isClosed())
334            return false;
335
336        if (!mInputTypeSwitchingOn)
337        {
338            mInputDevice->capture();
339        }
340
341
342                if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
343                {
344                        // one of the input modes is immediate, so setup what is needed for immediate mouse/key movement
345                        if (mTimeUntilNextToggle >= 0)
346                                mTimeUntilNextToggle -= evt.timeSinceLastFrame;
347
348                        // If this is the first frame, pick a speed
349                        if (evt.timeSinceLastFrame == 0)
350                        {
351                                mMoveScale = 1;
352                                mRotScale = 0.1;
353                        }
354                        // Otherwise scale movement units by time passed since last frame
355                        else
356                        {
357                                // Move about 100 units per second,
358                                mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
359                                // Take about 10 seconds for full rotation
360                                mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
361                        }
362                        mRotX = 0;
363            mRotY = 0;
364                mTranslateVector = Vector3::ZERO;
365                }
366
367        if (mUseBufferedInputKeys)
368        {
369            // no need to do any processing here, it is handled by event processor and
370                        // you get the results as KeyEvents
371        }
372        else
373        {
374            if (processUnbufferedKeyInput(evt) == false)
375                        {
376                                return false;
377                        }
378        }
379        if (mUseBufferedInputMouse)
380        {
381            // no need to do any processing here, it is handled by event processor and
382                        // you get the results as MouseEvents
383        }
384        else
385        {
386            if (processUnbufferedMouseInput(evt) == false)
387                        {
388                                return false;
389                        }
390        }
391
392                if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
393                {
394                        // one of the input modes is immediate, so update the movement vector
395
396                        moveCamera();
397
398                }
399
400                return true;
401    }
402
403    bool frameEnded(const FrameEvent& evt)
404    {
405        updateStats();
406        return true;
407    }
408
409        void switchMouseMode()
410        {
411        mUseBufferedInputMouse = !mUseBufferedInputMouse;
412                mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
413        }
414        void switchKeyMode()
415        {
416        mUseBufferedInputKeys = !mUseBufferedInputKeys;
417                mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
418        }
419
420        void keyClicked(KeyEvent* e)
421        {
422                if (e->getKeyChar() == 'm')
423                {
424                        switchMouseMode();
425                }
426                else if (e->getKeyChar() == 'k')
427                {
428
429                        switchKeyMode();
430                }
431
432        }
433        void keyPressed(KeyEvent* e) {}
434        void keyReleased(KeyEvent* e) {}
435
436protected:
437    EventProcessor* mEventProcessor;
438    InputReader* mInputDevice;
439    Camera* mCamera;
440
441    Vector3 mTranslateVector;
442    RenderWindow* mWindow;
443    bool mStatsOn;
444    bool mUseBufferedInputKeys, mUseBufferedInputMouse, mInputTypeSwitchingOn;
445        unsigned int mNumScreenShots;
446    float mMoveScale;
447    Degree mRotScale;
448    // just to stop toggles flipping too fast
449    Real mTimeUntilNextToggle ;
450    Radian mRotX, mRotY;
451    TextureFilterOptions mFiltering;
452    int mAniso;
453
454};
455
456#endif
Note: See TracBrowser for help on using the repository browser.