source: trunk/VUT/work/ogre_changes/Samples/Common/include/ExampleFrameListener.h @ 100

Revision 100, 13.8 KB checked in by mattausch, 19 years ago (diff)

added visualization for octree culling
camera in terrainexample is now attached to camera node => can see correct camera
in visualization

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(KC_R) && mTimeUntilNextToggle <=0)
253                {
254                        mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
255                        switch(mSceneDetailIndex) {
256                                case 0 : mCamera->setDetailLevel(SDL_SOLID) ; break ;
257                                case 1 : mCamera->setDetailLevel(SDL_WIREFRAME) ; break ;
258                                case 2 : mCamera->setDetailLevel(SDL_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#ifdef GTP_VISIBILITY_MODIFIED_OGRE
303        virtual void moveCamera() // made virtual by matt (16.05.05)
304#else
305        void moveCamera()
306#endif // GTP_VISIBILTIY_MODIFIED_OGRE
307        {
308
309        // Make all the changes to the camera
310        // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW (e.g. airplane)
311        mCamera->yaw(mRotX);
312        mCamera->pitch(mRotY);
313        mCamera->moveRelative(mTranslateVector);
314
315
316        }
317
318    void showDebugOverlay(bool show)
319    {
320        if (mDebugOverlay)
321        {
322            if (show)
323            {
324                mDebugOverlay->show();
325            }
326            else
327            {
328                mDebugOverlay->hide();
329            }
330        }
331    }
332
333    // Override frameStarted event to process that (don't care about frameEnded)
334    bool frameStarted(const FrameEvent& evt)
335    {
336        if(mWindow->isClosed())
337            return false;
338
339        if (!mInputTypeSwitchingOn)
340        {
341            mInputDevice->capture();
342        }
343
344
345                if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
346                {
347                        // one of the input modes is immediate, so setup what is needed for immediate mouse/key movement
348                        if (mTimeUntilNextToggle >= 0)
349                                mTimeUntilNextToggle -= evt.timeSinceLastFrame;
350
351                        // If this is the first frame, pick a speed
352                        if (evt.timeSinceLastFrame == 0)
353                        {
354                                mMoveScale = 1;
355                                mRotScale = 0.1;
356                        }
357                        // Otherwise scale movement units by time passed since last frame
358                        else
359                        {
360                                // Move about 100 units per second,
361                                mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
362                                // Take about 10 seconds for full rotation
363                                mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
364                        }
365                        mRotX = 0;
366            mRotY = 0;
367                mTranslateVector = Vector3::ZERO;
368                }
369
370        if (mUseBufferedInputKeys)
371        {
372            // no need to do any processing here, it is handled by event processor and
373                        // you get the results as KeyEvents
374        }
375        else
376        {
377            if (processUnbufferedKeyInput(evt) == false)
378                        {
379                                return false;
380                        }
381        }
382        if (mUseBufferedInputMouse)
383        {
384            // no need to do any processing here, it is handled by event processor and
385                        // you get the results as MouseEvents
386        }
387        else
388        {
389            if (processUnbufferedMouseInput(evt) == false)
390                        {
391                                return false;
392                        }
393        }
394
395                if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
396                {
397                        // one of the input modes is immediate, so update the movement vector
398
399                        moveCamera();
400
401                }
402
403                return true;
404    }
405
406    bool frameEnded(const FrameEvent& evt)
407    {
408        updateStats();
409        return true;
410    }
411
412        void switchMouseMode()
413        {
414        mUseBufferedInputMouse = !mUseBufferedInputMouse;
415                mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
416        }
417        void switchKeyMode()
418        {
419        mUseBufferedInputKeys = !mUseBufferedInputKeys;
420                mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
421        }
422
423        void keyClicked(KeyEvent* e)
424        {
425                if (e->getKeyChar() == 'm')
426                {
427                        switchMouseMode();
428                }
429                else if (e->getKeyChar() == 'k')
430                {
431
432                        switchKeyMode();
433                }
434
435        }
436        void keyPressed(KeyEvent* e) {}
437        void keyReleased(KeyEvent* e) {}
438
439protected:
440    EventProcessor* mEventProcessor;
441    InputReader* mInputDevice;
442    Camera* mCamera;
443
444    Vector3 mTranslateVector;
445    RenderWindow* mWindow;
446    bool mStatsOn;
447    bool mUseBufferedInputKeys, mUseBufferedInputMouse, mInputTypeSwitchingOn;
448        unsigned int mNumScreenShots;
449    float mMoveScale;
450    Degree mRotScale;
451    // just to stop toggles flipping too fast
452    Real mTimeUntilNextToggle ;
453    Radian mRotX, mRotY;
454    TextureFilterOptions mFiltering;
455    int mAniso;
456
457};
458
459#endif
Note: See TracBrowser for help on using the repository browser.