[Opal-commits] opal/samples/src BaseOpalApp.h,NONE,1.1 ExampleApplication.h,NONE,1.1 ExampleFrameLis
Status: Inactive
Brought to you by:
tylerstreeter
|
From: tylerstreeter <tyl...@us...> - 2005-03-30 23:26:36
|
Update of /cvsroot/opal/opal/samples/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4745/samples/src Added Files: BaseOpalApp.h ExampleApplication.h ExampleFrameListener.h TemplateApp.cpp Log Message: implemented InclineSensor; added code for Ogre sample apps --- NEW FILE: TemplateApp.cpp --- #include <time.h> #include "../src/BaseOpalApp.h" namespace myAppNamespace { class MyApp : public BaseOpalApp { public: MyApp() : BaseOpalApp() { mUseShadows = true; } ~MyApp() {} protected: virtual void createScene() { // Setup shadows. if (mUseShadows) { mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE); } else { mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); } // Set the ambient light level. mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); // Create a light source. Ogre::Light* light = mSceneMgr->createLight("light0"); light->setType(Ogre::Light::LT_POINT); light->setPosition(-80.0, 30.0, -10.0); // Load models, create physical objects, etc. here. } virtual bool appFrameStarted(opal::real dt) { // Do per-frame application specific things here. // Return true to continue looping. return true; } virtual bool processUnbufferedKeyInput(Ogre::Real dt) { // Check if we should quit looping. if(mInputDevice->isKeyDown(KC_ESCAPE) || mInputDevice->isKeyDown(KC_Q)) { return false; } // The following code can be used to update a camera's position. if (mInputDevice->isKeyDown(KC_LEFT)) { // Move camera left. } else if (mInputDevice->isKeyDown(KC_RIGHT)) { // Move camera right. } else if (mInputDevice->isKeyDown(KC_UP)) { // Move camera forward. } else if (mInputDevice->isKeyDown(KC_DOWN)) { // Move camera backward. } else { // Stop camera motion if necessary. } // Toggle shadows. if( mInputDevice->isKeyDown(KC_S)) { mUseShadows = !mUseShadows; if (mUseShadows) { mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE); } else { mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); } // Set this to keep from handling the key press // continually while it is down. mTimeUntilNextToggle = 0.5; } // Toggle HUD. if (mInputDevice->isKeyDown(KC_H) && mTimeUntilNextToggle <= 0) { mStatsOn = !mStatsOn; showDebugOverlay(mStatsOn); mTimeUntilNextToggle = 1; } // Handy screenshot saving procedure. if (mInputDevice->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0) { char tmp[20]; sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots); ExampleApplication::mWindow->writeContentsToFile(tmp); ExampleApplication::mWindow->setDebugText(String("Wrote ") + tmp); // Set this to keep from handling the key press // continually while it is down. mTimeUntilNextToggle = 0.5; } // Return true to continue looping. return true; } virtual bool processUnbufferedMouseInput(Ogre::Real dt) { // The following code checks the mouse button state. if (true == mInputDevice->getMouseButton(0)) { // The left mouse button is down. } else { // The left mouse button is up. } // The following code checks how far the mouse has move since // the last poll. This data can be used to rotate the camera // around its X and Y axes (yaw and pitch, respectively). Ogre::Real rotX = -mInputDevice->getMouseRelativeX(); Ogre::Real rotY = -mInputDevice->getMouseRelativeY(); // Return true to continue looping. return true; } private: /// Used to toggle shadows on and off. bool mUseShadows; }; } int main(int argc, char **argv) { srand(time(NULL)); SET_TERM_HANDLER; myAppNamespace::MyApp app; try { app.go(); } catch(Ogre::Exception& e) { std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl; } return 0; } --- NEW FILE: ExampleApplication.h --- /* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2005 The OGRE Team Also see acknowledgements in Readme.html You may use this sample code for anything you like, it is not covered by the LGPL like the rest of the engine. ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Filename: ExampleApplication.h Description: Base class for all the OGRE examples ----------------------------------------------------------------------------- */ #ifndef __ExampleApplication_H__ #define __ExampleApplication_H__ #include <ogre/Ogre.h> #include <ogre/OgreConfigFile.h> #include "ExampleFrameListener.h" using namespace Ogre; /** Base class which manages the standard startup of an Ogre application. Designed to be subclassed for specific examples if required. */ class ExampleApplication { public: /// Standard constructor ExampleApplication() { mFrameListener = 0; mRoot = 0; } /// Standard destructor virtual ~ExampleApplication() { if (mFrameListener) delete mFrameListener; if (mRoot) delete mRoot; } /// Start the example virtual void go(void) { if (!setup()) return; mRoot->startRendering(); // clean up destroyScene(); } protected: Root *mRoot; Camera* mCamera; SceneManager* mSceneMgr; ExampleFrameListener* mFrameListener; RenderWindow* mWindow; // These internal methods package up the stages in the startup process /** Sets up the application - returns false if the user chooses to abandon configuration. */ virtual bool setup(void) { mRoot = new Root(); setupResources(); bool carryOn = configure(); if (!carryOn) return false; chooseSceneManager(); createCamera(); createViewports(); // Set default mipmap level (NB some APIs ignore this) TextureManager::getSingleton().setDefaultNumMipmaps(5); // Create any resource listeners (for loading screens) createResourceListener(); // Load resources loadResources(); // Create the scene createScene(); createFrameListener(); return true; } /** Configures the application - returns false if the user chooses to abandon configuration. */ virtual bool configure(void) { // Show the configuration dialog and initialise the system // You can skip this and use root.restoreConfig() to load configuration // settings if you were sure there are valid ones saved in ogre.cfg if(mRoot->showConfigDialog()) { // If returned true, user clicked OK so initialise // Here we choose to let the system create a default rendering window by passing 'true' mWindow = mRoot->initialise(true); return true; } else { return false; } } virtual void chooseSceneManager(void) { // Get the SceneManager, in this case a generic one mSceneMgr = mRoot->getSceneManager(ST_GENERIC); } virtual void createCamera(void) { // Create the camera mCamera = mSceneMgr->createCamera("PlayerCam"); // Position it at 500 in Z direction mCamera->setPosition(Vector3(0,0,500)); // Look back along -Z mCamera->lookAt(Vector3(0,0,-300)); mCamera->setNearClipDistance(5); } // This function was modifed for the Opal sample apps. virtual void createFrameListener() { //mFrameListener= new ExampleFrameListener(mWindow, mCamera); //mFrameListener->showDebugOverlay(true); //mRoot->addFrameListener(mFrameListener); } virtual void createScene(void) = 0; // pure virtual - this has to be overridden virtual void destroyScene(void){} // Optional to override this virtual void createViewports(void) { // Create one viewport, entire window Viewport* vp = mWindow->addViewport(mCamera); vp->setBackgroundColour(ColourValue(0,0,0)); // Alter the camera aspect ratio to match the viewport mCamera->setAspectRatio( Real(vp->getActualWidth()) / Real(vp->getActualHeight())); } /// Method which will define the source of resources (other than current folder) virtual void setupResources(void) { // Load resource paths from config file ConfigFile cf; cf.load("resources.cfg"); // Go through all sections & settings in the file ConfigFile::SectionIterator seci = cf.getSectionIterator(); String secName, typeName, archName; while (seci.hasMoreElements()) { secName = seci.peekNextKey(); ConfigFile::SettingsMultiMap *settings = seci.getNext(); ConfigFile::SettingsMultiMap::iterator i; for (i = settings->begin(); i != settings->end(); ++i) { typeName = i->first; archName = i->second; ResourceGroupManager::getSingleton().addResourceLocation( archName, typeName, secName); } } } /// Optional override method where you can create resource listeners (e.g. for loading screens) virtual void createResourceListener(void) { } /// Optional override method where you can perform resource group loading /// Must at least do ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); virtual void loadResources(void) { // Initialise, parse scripts etc ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); } }; #endif --- NEW FILE: ExampleFrameListener.h --- /* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2005 The OGRE Team Also see acknowledgements in Readme.html You may use this sample code for anything you like, it is not covered by the LGPL like the rest of the engine. ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Filename: ExampleFrameListener.h Description: Defines an example frame listener which responds to frame events. This frame listener just moves a specified camera around based on keyboard and mouse movements. Mouse: Freelook W or Up: Forward S or Down:Backward A: Step left D: Step right PgUp: Move upwards PgDown: Move downwards F: Toggle frame rate stats on/off R: Render mode T: Cycle texture filtering Bilinear, Trilinear, Anisotropic(8) P: Toggle on/off display of camera position / orientation ----------------------------------------------------------------------------- */ #ifndef __ExampleFrameListener_H__ #define __ExampleFrameListener_H__ #include <ogre/Ogre.h> #include <ogre/OgreKeyEvent.h> #include <ogre/OgreEventListeners.h> #include <ogre/OgreStringConverter.h> #include <ogre/OgreException.h> using namespace Ogre; class ExampleFrameListener: public FrameListener, public KeyListener { protected: int mSceneDetailIndex ; Real mMoveSpeed; Degree mRotateSpeed; Overlay* mDebugOverlay; void updateStats(void) { static String currFps = "Current FPS: "; static String avgFps = "Average FPS: "; static String bestFps = "Best FPS: "; static String worstFps = "Worst FPS: "; static String tris = "Triangle Count: "; // update stats when necessary try { OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps"); OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps"); OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps"); OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps"); const RenderTarget::FrameStats& stats = mWindow->getStatistics(); guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS)); guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS)); guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS) +" "+StringConverter::toString(stats.bestFrameTime)+" ms"); guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS) +" "+StringConverter::toString(stats.worstFrameTime)+" ms"); OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris"); guiTris->setCaption(tris + StringConverter::toString((unsigned int)stats.triangleCount)); OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); guiDbg->setCaption(mWindow->getDebugText()); } catch(...) { // ignore } } public: // This constructor was changed from its normal behavior for Opal // sample apps. Warning: be sure to call init on instances of // this class after the Ogre root has been created! If you're deriving // your app from BaseOpalApp, you should be fine. ExampleFrameListener() {} // Takes a RenderWindow because it uses that to determine input context. // This function was added for Opal sample apps. void init(RenderWindow* win, Camera* cam, bool useBufferedInputKeys = false, bool useBufferedInputMouse = false) { mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); mUseBufferedInputKeys = useBufferedInputKeys; mUseBufferedInputMouse = useBufferedInputMouse; mInputTypeSwitchingOn = mUseBufferedInputKeys || mUseBufferedInputMouse; mRotateSpeed = 36; mMoveSpeed = 100; if (mInputTypeSwitchingOn) { mEventProcessor = new EventProcessor(); mEventProcessor->initialise(win); mEventProcessor->startProcessingEvents(); mEventProcessor->addKeyListener(this); mInputDevice = mEventProcessor->getInputReader(); } else { mInputDevice = PlatformManager::getSingleton().createInputReader(); mInputDevice->initialise(win,true, true); } mCamera = cam; mWindow = win; mStatsOn = true; mNumScreenShots = 0; mTimeUntilNextToggle = 0; mSceneDetailIndex = 0; mMoveScale = 0.0f; mRotScale = 0.0f; mTranslateVector = Vector3::ZERO; mAniso = 1; mFiltering = TFO_BILINEAR; showDebugOverlay(true); } virtual ~ExampleFrameListener() { if (mInputTypeSwitchingOn) { delete mEventProcessor; } else { PlatformManager::getSingleton().destroyInputReader( mInputDevice ); } } virtual bool processUnbufferedKeyInput(const FrameEvent& evt) { if (mInputDevice->isKeyDown(KC_A)) { // Move camera left mTranslateVector.x = -mMoveScale; } if (mInputDevice->isKeyDown(KC_D)) { // Move camera RIGHT mTranslateVector.x = mMoveScale; } /* Move camera forward by keypress. */ if (mInputDevice->isKeyDown(KC_UP) || mInputDevice->isKeyDown(KC_W) ) { mTranslateVector.z = -mMoveScale; } /* Move camera backward by keypress. */ if (mInputDevice->isKeyDown(KC_DOWN) || mInputDevice->isKeyDown(KC_S) ) { mTranslateVector.z = mMoveScale; } if (mInputDevice->isKeyDown(KC_PGUP)) { // Move camera up mTranslateVector.y = mMoveScale; } if (mInputDevice->isKeyDown(KC_PGDOWN)) { // Move camera down mTranslateVector.y = -mMoveScale; } if (mInputDevice->isKeyDown(KC_RIGHT)) { mCamera->yaw(-mRotScale); } if (mInputDevice->isKeyDown(KC_LEFT)) { mCamera->yaw(mRotScale); } if( mInputDevice->isKeyDown( KC_ESCAPE) ) { return false; } // see if switching is on, and you want to toggle if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_M) && mTimeUntilNextToggle <= 0) { switchMouseMode(); mTimeUntilNextToggle = 1; } if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_K) && mTimeUntilNextToggle <= 0) { // must be going from immediate keyboard to buffered keyboard switchKeyMode(); mTimeUntilNextToggle = 1; } if (mInputDevice->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0) { mStatsOn = !mStatsOn; showDebugOverlay(mStatsOn); mTimeUntilNextToggle = 1; } if (mInputDevice->isKeyDown(KC_T) && mTimeUntilNextToggle <= 0) { switch(mFiltering) { case TFO_BILINEAR: mFiltering = TFO_TRILINEAR; mAniso = 1; break; case TFO_TRILINEAR: mFiltering = TFO_ANISOTROPIC; mAniso = 8; break; case TFO_ANISOTROPIC: mFiltering = TFO_BILINEAR; mAniso = 1; break; default: break; } MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering); MaterialManager::getSingleton().setDefaultAnisotropy(mAniso); showDebugOverlay(mStatsOn); mTimeUntilNextToggle = 1; } if (mInputDevice->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0) { char tmp[20]; sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots); mWindow->writeContentsToFile(tmp); mTimeUntilNextToggle = 0.5; mWindow->setDebugText(String("Wrote ") + tmp); } if (mInputDevice->isKeyDown(KC_R) && mTimeUntilNextToggle <=0) { mSceneDetailIndex = (mSceneDetailIndex+1)%3 ; switch(mSceneDetailIndex) { case 0 : mCamera->setDetailLevel(SDL_SOLID) ; break ; case 1 : mCamera->setDetailLevel(SDL_WIREFRAME) ; break ; case 2 : mCamera->setDetailLevel(SDL_POINTS) ; break ; } mTimeUntilNextToggle = 0.5; } static bool displayCameraDetails = false; if (mInputDevice->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0) { displayCameraDetails = !displayCameraDetails; mTimeUntilNextToggle = 0.5; if (!displayCameraDetails) mWindow->setDebugText(""); } if (displayCameraDetails) { // Print camera details mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) + " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation())); } // Return true to continue rendering return true; } bool processUnbufferedMouseInput(const FrameEvent& evt) { /* Rotation factors, may not be used if the second mouse button is pressed. */ /* If the second mouse button is pressed, then the mouse movement results in sliding the camera, otherwise we rotate. */ if( mInputDevice->getMouseButton( 1 ) ) { mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13; mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13; } else { mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13); mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13); } return true; } void moveCamera() { // Make all the changes to the camera // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW (e.g. airplane) mCamera->yaw(mRotX); mCamera->pitch(mRotY); mCamera->moveRelative(mTranslateVector); } void showDebugOverlay(bool show) { if (mDebugOverlay) { if (show) { mDebugOverlay->show(); } else { mDebugOverlay->hide(); } } } // Override frameStarted event to process that (don't care about frameEnded) bool frameStarted(const FrameEvent& evt) { if(mWindow->isClosed()) return false; if (!mInputTypeSwitchingOn) { mInputDevice->capture(); } if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys) { // one of the input modes is immediate, so setup what is needed for immediate mouse/key movement if (mTimeUntilNextToggle >= 0) mTimeUntilNextToggle -= evt.timeSinceLastFrame; // If this is the first frame, pick a speed if (evt.timeSinceLastFrame == 0) { mMoveScale = 1; mRotScale = 0.1; } // Otherwise scale movement units by time passed since last frame else { // Move about 100 units per second, mMoveScale = mMoveSpeed * evt.timeSinceLastFrame; // Take about 10 seconds for full rotation mRotScale = mRotateSpeed * evt.timeSinceLastFrame; } mRotX = 0; mRotY = 0; mTranslateVector = Vector3::ZERO; } if (mUseBufferedInputKeys) { // no need to do any processing here, it is handled by event processor and // you get the results as KeyEvents } else { if (processUnbufferedKeyInput(evt) == false) { return false; } } if (mUseBufferedInputMouse) { // no need to do any processing here, it is handled by event processor and // you get the results as MouseEvents } else { if (processUnbufferedMouseInput(evt) == false) { return false; } } if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys) { // one of the input modes is immediate, so update the movement vector moveCamera(); } return true; } bool frameEnded(const FrameEvent& evt) { updateStats(); return true; } void switchMouseMode() { mUseBufferedInputMouse = !mUseBufferedInputMouse; mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse); } void switchKeyMode() { mUseBufferedInputKeys = !mUseBufferedInputKeys; mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse); } void keyClicked(KeyEvent* e) { if (e->getKeyChar() == 'm') { switchMouseMode(); } else if (e->getKeyChar() == 'k') { switchKeyMode(); } } void keyPressed(KeyEvent* e) {} void keyReleased(KeyEvent* e) {} protected: EventProcessor* mEventProcessor; InputReader* mInputDevice; Camera* mCamera; Vector3 mTranslateVector; RenderWindow* mWindow; bool mStatsOn; bool mUseBufferedInputKeys, mUseBufferedInputMouse, mInputTypeSwitchingOn; unsigned int mNumScreenShots; float mMoveScale; Degree mRotScale; // just to stop toggles flipping too fast Real mTimeUntilNextToggle ; Radian mRotX, mRotY; TextureFilterOptions mFiltering; int mAniso; }; #endif --- NEW FILE: BaseOpalApp.h --- #ifndef BASE_OPAL_APP_H #define BASE_OPAL_APP_H #include "ExampleApplication.h" #include "ExampleFrameListener.h" #include <opal/opal.h> class BaseOpalApp : public ExampleApplication, public ExampleFrameListener { public: BaseOpalApp() : ExampleApplication(), ExampleFrameListener() { mSimulator = opal::createSimulator(); } ~BaseOpalApp() { mSimulator->destroy(); } protected: /// Register the frame listener with the Ogre root so it will /// call the listener at the appropriate time. virtual void createFrameListener() { ExampleFrameListener::init(ExampleApplication::mWindow, ExampleApplication::mCamera); mRoot->addFrameListener(this); } /// Initial scene setup function. Create and position lights, load /// models, create a camera, etc. virtual void createScene() = 0; /// Called once per frame after input and physics have been updated. /// This is a place for applications to do application-specific updates /// per frame. It takes the dt since the last frame as a parameter. /// This should return false if we should break out of the main loop. virtual bool appFrameStarted(opal::real dt) = 0; /// Called at the start of each frame. Calculate dt since the last /// frame, update input, update physics, etc. Returns false if we /// should break out of the main loop. Applications should not override /// this; instead, they should override 'appFrameStarted'. virtual bool frameStarted(const FrameEvent& evt) { if(ExampleApplication::mWindow->isClosed()) { return false; } Ogre::Real dt = evt.timeSinceLastFrame; if (false == handleInput(dt)) { return false; } // Simulate physics. mSimulator->simulate(dt); // Notify the application about the new frame. appFrameStarted((opal::real)dt); return true; } /// Returns false if we should break out of the main loop. bool handleInput(Ogre::Real dt) { // This variable can be used to keep keys from repeating too fast. if (mTimeUntilNextToggle >= 0) { mTimeUntilNextToggle -= dt; } // Acquire data from input devices. mInputDevice->capture(); // Handle keyboard input. if (processUnbufferedKeyInput(dt) == false) { return false; } // Handle mouse input. if (processUnbufferedMouseInput(dt) == false) { return false; } return true; } /// Process keyboard input here. Returns false if we should break out /// of the main loop. virtual bool processUnbufferedKeyInput(Ogre::Real dt) = 0; /// Process mouse input here. Returns false if we should break out of /// the main loop. virtual bool processUnbufferedMouseInput(Ogre::Real dt) = 0; /// Pointer to the OPAL Simulator. opal::Simulator* mSimulator; private: }; #endif |