D:/Papagan/490.2006/490.2006/korsan/Papagan/490.2006/korsan/Papagan/ExampleFrameListener.h

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright (c) 2000-2005 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 You may use this sample code for anything you like, it is not covered by the
00011 LGPL like the rest of the engine.
00012 -----------------------------------------------------------------------------
00013 */
00014 /*
00015 -----------------------------------------------------------------------------
00016 Filename:    ExampleFrameListener.h
00017 Description: Defines an example frame listener which responds to frame events.
00018 This frame listener just moves a specified camera around based on
00019 keyboard and mouse movements.
00020 Mouse:    Freelook
00021 W or Up:  Forward
00022 S or Down:Backward
00023 A:        Step left
00024 D:        Step right
00025              PgUp:     Move upwards
00026              PgDown:   Move downwards
00027              F:        Toggle frame rate stats on/off
00028                          R:        Render mode
00029              T:        Cycle texture filtering
00030                        Bilinear, Trilinear, Anisotropic(8)
00031              P:        Toggle on/off display of camera position / orientation
00032 -----------------------------------------------------------------------------
00033 */
00034 
00035 #ifndef __ExampleFrameListener_H__
00036 #define __ExampleFrameListener_H__
00037 
00038 #include "Ogre.h"
00039 #include "OgreKeyEvent.h"
00040 #include "OgreEventListeners.h"
00041 #include "OgreStringConverter.h"
00042 #include "OgreException.h"
00043 
00044 using namespace Ogre;
00061 class ExampleFrameListener: public FrameListener, public KeyListener
00062 {
00063 protected:
00064         int mSceneDetailIndex ;
00065     Real mMoveSpeed;
00066     Degree mRotateSpeed;
00067     //Overlay* mDebugOverlay;
00068 
00069     /*void updateStats(void)
00070     {
00071         static String currFps = "Current FPS: ";
00072         static String avgFps = "Average FPS: ";
00073         static String bestFps = "Best FPS: ";
00074         static String worstFps = "Worst FPS: ";
00075         static String tris = "Triangle Count: ";
00076 
00077         // update stats when necessary
00078         try {
00079             OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
00080             OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
00081             OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
00082             OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
00083 
00084             const RenderTarget::FrameStats& stats = mWindow->getStatistics();
00085 
00086             guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
00087             guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
00088             guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
00089                 +" "+StringConverter::toString(stats.bestFrameTime)+" ms");
00090             guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
00091                 +" "+StringConverter::toString(stats.worstFrameTime)+" ms");
00092 
00093             OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
00094             guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));
00095 
00096             OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
00097             guiDbg->setCaption(mWindow->getDebugText());
00098         }
00099         catch(...)
00100         {
00101             // ignore
00102         }
00103     }*/
00104 
00105 public:
00106     // Constructor takes a RenderWindow because it uses that to determine input context
00107     ExampleFrameListener(RenderWindow* win, Camera* cam, bool useBufferedInputKeys = false, bool useBufferedInputMouse = false)
00108     {
00109         //mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
00110         mUseBufferedInputKeys = useBufferedInputKeys;
00111                 mUseBufferedInputMouse = useBufferedInputMouse;
00112                 mInputTypeSwitchingOn = mUseBufferedInputKeys || mUseBufferedInputMouse;
00113         mRotateSpeed = 36;
00114         mMoveSpeed = 100;
00115 
00116                 if (mInputTypeSwitchingOn)
00117                 {
00118             mEventProcessor = new EventProcessor();
00119                         mEventProcessor->initialise(win);
00120                         mEventProcessor->startProcessingEvents();
00121                         mEventProcessor->addKeyListener(this);
00122                         mInputDevice = mEventProcessor->getInputReader();
00123 
00124                 }
00125         else
00126         {
00127             mInputDevice = PlatformManager::getSingleton().createInputReader();
00128             mInputDevice->initialise(win,true, true);
00129         }
00130 
00131         mCamera = cam;
00132         mWindow = win;
00133         mStatsOn = true;
00134                 mNumScreenShots = 0;
00135                 mTimeUntilNextToggle = 0;
00136         mSceneDetailIndex = 0;
00137         mMoveScale = 0.0f;
00138         mRotScale = 0.0f;
00139             mTranslateVector = Vector3::ZERO;
00140         mAniso = 1;
00141         mFiltering = TFO_BILINEAR;
00142 
00143         //showDebugOverlay(true);
00144     }
00145     virtual ~ExampleFrameListener()
00146     {
00147                 if (mInputTypeSwitchingOn)
00148                 {
00149             delete mEventProcessor;
00150                 }
00151         else
00152         {
00153             PlatformManager::getSingleton().destroyInputReader( mInputDevice );
00154         }
00155     }
00156 
00157     virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
00158     {
00159         if (mInputDevice->isKeyDown(KC_A))
00160         {
00161             // Move camera left
00162             mTranslateVector.x = -mMoveScale;
00163         }
00164 
00165         if (mInputDevice->isKeyDown(KC_D))
00166         {
00167             // Move camera RIGHT
00168             mTranslateVector.x = mMoveScale;
00169         }
00170 
00171         /* Move camera forward by keypress. */
00172         if (mInputDevice->isKeyDown(KC_UP) || mInputDevice->isKeyDown(KC_W) )
00173         {
00174             mTranslateVector.z = -mMoveScale;
00175         }
00176 
00177         /* Move camera backward by keypress. */
00178         if (mInputDevice->isKeyDown(KC_DOWN) || mInputDevice->isKeyDown(KC_S) )
00179         {
00180             mTranslateVector.z = mMoveScale;
00181         }
00182 
00183         if (mInputDevice->isKeyDown(KC_PGUP))
00184         {
00185             // Move camera up
00186             mTranslateVector.y = mMoveScale;
00187         }
00188 
00189         if (mInputDevice->isKeyDown(KC_PGDOWN))
00190         {
00191             // Move camera down
00192             mTranslateVector.y = -mMoveScale;
00193         }
00194 
00195         if (mInputDevice->isKeyDown(KC_RIGHT))
00196         {
00197             mCamera->yaw(-mRotScale);
00198         }
00199                 
00200         if (mInputDevice->isKeyDown(KC_LEFT))
00201         {
00202             mCamera->yaw(mRotScale);
00203         }
00204 
00205         if( mInputDevice->isKeyDown( KC_ESCAPE) )
00206         {            
00207             return false;
00208         }
00209 
00210                 // see if switching is on, and you want to toggle 
00211         if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_M) && mTimeUntilNextToggle <= 0)
00212         {
00213                         switchMouseMode();
00214             mTimeUntilNextToggle = 1;
00215         }
00216 
00217         if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_K) && mTimeUntilNextToggle <= 0)
00218         {
00219                         // must be going from immediate keyboard to buffered keyboard
00220                         switchKeyMode();
00221             mTimeUntilNextToggle = 1;
00222         }
00223         if (mInputDevice->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0)
00224         {
00225             mStatsOn = !mStatsOn;
00226             //showDebugOverlay(mStatsOn);
00227 
00228             mTimeUntilNextToggle = 1;
00229         }
00230         if (mInputDevice->isKeyDown(KC_T) && mTimeUntilNextToggle <= 0)
00231         {
00232             switch(mFiltering)
00233             {
00234             case TFO_BILINEAR:
00235                 mFiltering = TFO_TRILINEAR;
00236                 mAniso = 1;
00237                 break;
00238             case TFO_TRILINEAR:
00239                 mFiltering = TFO_ANISOTROPIC;
00240                 mAniso = 8;
00241                 break;
00242             case TFO_ANISOTROPIC:
00243                 mFiltering = TFO_BILINEAR;
00244                 mAniso = 1;
00245                 break;
00246             default:
00247                 break;
00248             }
00249             MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
00250             MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
00251 
00252 
00253             //showDebugOverlay(mStatsOn);
00254 
00255             mTimeUntilNextToggle = 1;
00256         }
00257 
00258         if (mInputDevice->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
00259         {
00260                         char tmp[20];
00261                         sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
00262             mWindow->writeContentsToFile(tmp);
00263             mTimeUntilNextToggle = 0.5;
00264                         mWindow->setDebugText(String("Wrote ") + tmp);
00265         }
00266                 
00267                 if (mInputDevice->isKeyDown(KC_R) && mTimeUntilNextToggle <=0)
00268                 {
00269                         mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
00270                         switch(mSceneDetailIndex) {
00271                                 case 0 : mCamera->setDetailLevel(SDL_SOLID) ; break ;
00272                                 case 1 : mCamera->setDetailLevel(SDL_WIREFRAME) ; break ;
00273                                 case 2 : mCamera->setDetailLevel(SDL_POINTS) ; break ;
00274                         }
00275                         mTimeUntilNextToggle = 0.5;
00276                 }
00277 
00278         static bool displayCameraDetails = false;
00279         if (mInputDevice->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
00280         {
00281             displayCameraDetails = !displayCameraDetails;
00282             mTimeUntilNextToggle = 0.5;
00283             if (!displayCameraDetails)
00284                 mWindow->setDebugText("");
00285         }
00286         if (displayCameraDetails)
00287         {
00288             // Print camera details
00289             mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) + " " + 
00290                 "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
00291         }
00292 
00293         // Return true to continue rendering
00294         return true;
00295     }
00296 
00297     bool processUnbufferedMouseInput(const FrameEvent& evt)
00298     {
00299         /* Rotation factors, may not be used if the second mouse button is pressed. */
00300 
00301         /* If the second mouse button is pressed, then the mouse movement results in 
00302            sliding the camera, otherwise we rotate. */
00303         if( mInputDevice->getMouseButton( 1 ) )
00304         {
00305             mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
00306             mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
00307         }
00308         else
00309         {
00310             mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
00311             mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
00312         }
00313 
00314 
00315                 return true;
00316         }
00317 
00318         void moveCamera()
00319         {
00320 
00321         // Make all the changes to the camera
00322         // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW (e.g. airplane)
00323         mCamera->yaw(mRotX);
00324         mCamera->pitch(mRotY);
00325         mCamera->moveRelative(mTranslateVector);
00326 
00327 
00328         }
00329 
00330     /*void showDebugOverlay(bool show)
00331     {
00332         if (mDebugOverlay)
00333         {
00334             if (show)
00335             {
00336                 mDebugOverlay->show();
00337             }
00338             else
00339             {
00340                 mDebugOverlay->hide();
00341             }
00342         }
00343     }*/
00344 
00346     bool frameStarted(const FrameEvent& evt)
00347     {
00348         if(mWindow->isClosed())
00349             return false;
00350 
00351         if (!mInputTypeSwitchingOn)
00352         {
00353             mInputDevice->capture();
00354         }
00355 
00356 
00357                 if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
00358                 {
00359                         // one of the input modes is immediate, so setup what is needed for immediate mouse/key movement
00360                         if (mTimeUntilNextToggle >= 0) 
00361                                 mTimeUntilNextToggle -= evt.timeSinceLastFrame;
00362 
00363                         // If this is the first frame, pick a speed
00364                         if (evt.timeSinceLastFrame == 0)
00365                         {
00366                                 mMoveScale = 1;
00367                                 mRotScale = 0.1;
00368                         }
00369                         // Otherwise scale movement units by time passed since last frame
00370                         else
00371                         {
00372                                 // Move about 100 units per second,
00373                                 mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
00374                                 // Take about 10 seconds for full rotation
00375                                 mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
00376                         }
00377                         mRotX = 0;
00378             mRotY = 0;
00379                 mTranslateVector = Vector3::ZERO;
00380                 }
00381 
00382         if (mUseBufferedInputKeys)
00383         {
00384             // no need to do any processing here, it is handled by event processor and 
00385                         // you get the results as KeyEvents
00386         }
00387         else
00388         {
00389             if (processUnbufferedKeyInput(evt) == false)
00390                         {
00391                                 return false;
00392                         }
00393         }
00394         if (mUseBufferedInputMouse)
00395         {
00396             // no need to do any processing here, it is handled by event processor and 
00397                         // you get the results as MouseEvents
00398         }
00399         else
00400         {
00401             if (processUnbufferedMouseInput(evt) == false)
00402                         {
00403                                 return false;
00404                         }
00405         }
00406 
00407                 if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
00408                 {
00409                         // one of the input modes is immediate, so update the movement vector
00410 
00411                         moveCamera();
00412 
00413                 }
00414 
00415                 return true;
00416     }
00417 
00418     bool frameEnded(const FrameEvent& evt)
00419     {
00420         //updateStats();
00421         return true;
00422     }
00423 
00424         void switchMouseMode() 
00425         {
00426         mUseBufferedInputMouse = !mUseBufferedInputMouse;
00427                 mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
00428         }
00429         void switchKeyMode() 
00430         {
00431         mUseBufferedInputKeys = !mUseBufferedInputKeys;
00432                 mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
00433         }
00434 
00435         void keyClicked(KeyEvent* e) 
00436         {
00437                 if (e->getKeyChar() == 'm')
00438                 {
00439                         switchMouseMode();
00440                 }
00441                 else if (e->getKeyChar() == 'k')
00442                 {
00443 
00444                         switchKeyMode();
00445                 }
00446 
00447         }
00448         void keyPressed(KeyEvent* e) {}
00449         void keyReleased(KeyEvent* e) {}
00450 
00451 protected:
00452     EventProcessor* mEventProcessor;
00453     InputReader* mInputDevice;
00454     Camera* mCamera;
00455 
00456     Vector3 mTranslateVector;
00457     RenderWindow* mWindow;
00458     bool mStatsOn;
00459     bool mUseBufferedInputKeys, mUseBufferedInputMouse, mInputTypeSwitchingOn;
00460         unsigned int mNumScreenShots;
00461     float mMoveScale;
00462     Degree mRotScale;
00463     // just to stop toggles flipping too fast
00464     Real mTimeUntilNextToggle ;
00465     Radian mRotX, mRotY;
00466     TextureFilterOptions mFiltering;
00467     int mAniso;
00468 
00469 };
00470 
00471 #endif

Generated on Mon May 29 01:10:33 2006 for Papagan by  doxygen 1.4.6-NO