www.pudn.com > TestForNetwonOgre.rar > BaseApplication.cpp


/* 
----------------------------------------------------------------------------- 
Filename:    BaseApplication.cpp 
----------------------------------------------------------------------------- 
 
This source file is generated by the Ogre AppWizard. 
 
Check out: http://conglomerate.berlios.de/wiki/doku.php?id=ogrewizards 
 
Based on the Example Framework for OGRE 
(Object-oriented Graphics Rendering Engine) 
 
Copyright (c) 2000-2007 The OGRE Team 
For the latest info, see http://www.ogre3d.org/ 
 
You may use this sample code for anything you like, it is not covered by the 
LGPL like the rest of the OGRE engine. 
----------------------------------------------------------------------------- 
*/ 
#include "BaseApplication.h" 
 
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 
#include "../scripts/res/resource.h" 
#endif 
 
template<> BaseApplication* Ogre::Singleton::ms_Singleton = 0; 
 
 
//------------------------------------------------------------------------------------- 
BaseApplication::BaseApplication(void) 
	: mRoot(0), 
	mCamera(0), 
	mSceneMgr(0), 
	mWindow(0), 
	mSceneDetailIndex(0), 
	mMoveSpeed(100), 
	mRotateSpeed(36), 
	mDebugOverlay(0), 
	mDebugText(""), 
	mInputManager(0), 
	mMouse(0), 
	mKeyboard(0), 
	mTranslateVector(Vector3::ZERO), 
	mStatsOn(true), 
	mUseBufferedInputKeys(true), 
	mUseBufferedInputMouse(true), 
	mInputTypeSwitchingOn(true), 
	mNumScreenShots(0), 
	mMoveScale(0.0f), 
	mRotScale(0.0f), 
	mTimeUntilNextToggle(0), 
	mRotX(0), 
	mRotY(0), 
	mFiltering(TFO_BILINEAR), 
	mAniso(1) 
{ 
} 
 
//------------------------------------------------------------------------------------- 
BaseApplication::~BaseApplication(void) 
{ 
	//Remove ourself as a Window listener 
	WindowEventUtilities::removeWindowEventListener(mWindow, this); 
	windowClosed(mWindow); 
	delete mRoot; 
} 
 
//------------------------------------------------------------------------------------- 
bool BaseApplication::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' 
		mRoot->restoreConfig(); 
		mWindow = mRoot->initialise(true); 
 
		// Let's add a nice window icon 
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 
		HWND hwnd; 
		mWindow->getCustomAttribute("WINDOW", (void*)&hwnd); 
		LONG iconID   = (LONG)LoadIcon( GetModuleHandle(0), MAKEINTRESOURCE(IDI_APPICON) ); 
		SetClassLong( hwnd, GCL_HICON, iconID ); 
#endif 
		return true; 
//	} 
//	else 
//	{ 
//		return false; 
//	} 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::chooseSceneManager(void) 
{ 
	// Get the SceneManager, in this case a generic one 
	mSceneMgr = mRoot->createSceneManager(ST_GENERIC); 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::createCamera(void) 
{ 
	// Create the camera 
	mCamera = mSceneMgr->createCamera("PlayerCam"); 
 
	// Position it at 500 in Z direction 
	mCamera->setPosition(Vector3(0,0,80)); 
	// Look back along -Z 
	mCamera->lookAt(Vector3(0,0,-300)); 
	mCamera->setNearClipDistance(5); 
 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::createFrameListener(void) 
{ 
	mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); 
	mUseBufferedInputKeys = false; 
	mUseBufferedInputMouse = false; 
//	mInputTypeSwitchingOn = mUseBufferedInputKeys || mUseBufferedInputMouse; 
	mRotateSpeed = 36; 
	mMoveSpeed = 100; 
 
	using namespace OIS; 
 
	LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***"); 
	ParamList pl; 
	size_t windowHnd = 0; 
	std::ostringstream windowHndStr; 
 
	mWindow->getCustomAttribute("WINDOW", &windowHnd); 
	windowHndStr << windowHnd; 
	pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 
 
	mInputManager = InputManager::createInputSystem( pl ); 
 
	mKeyboard = static_cast(mInputManager->createInputObject( OISKeyboard, mUseBufferedInputKeys )); 
	mMouse = static_cast(mInputManager->createInputObject( OISMouse, mUseBufferedInputMouse )); 
 
	mMouse->setEventCallback(this); 
	mKeyboard->setEventCallback(this); 
 
	//Set initial mouse clipping size 
	windowResized(mWindow); 
 
	//Register as a Window listener 
	WindowEventUtilities::addWindowEventListener(mWindow, this); 
 
	mStatsOn = true; 
	mNumScreenShots = 0; 
	mTimeUntilNextToggle = 0; 
	mSceneDetailIndex = 0; 
	mMoveScale = 0.0f; 
	mRotScale = 0.0f; 
	mTranslateVector = Vector3::ZERO; 
	mAniso = 1; 
	mFiltering = TFO_BILINEAR; 
 
	showDebugOverlay(true); 
	mRoot->addFrameListener(this); 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::destroyScene(void) 
{ 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::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())); 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::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); 
		} 
	} 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::createResourceListener(void) 
{ 
 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::loadResources(void) 
{ 
	ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::go(void) 
{ 
	if (!setup()) 
		return; 
 
	showDebugOverlay(true); 
 
	mRoot->startRendering(); 
 
	// clean up 
	destroyScene(); 
} 
//------------------------------------------------------------------------------------- 
bool BaseApplication::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; 
}; 
//------------------------------------------------------------------------------------- 
void BaseApplication::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(stats.triangleCount)); 
 
		OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); 
		guiDbg->setCaption(mDebugText); 
	} 
	catch(...) 
	{ 
		// ignore 
	} 
} 
//------------------------------------------------------------------------------------- 
bool BaseApplication::processUnbufferedKeyInput(const FrameEvent& evt) 
{ 
	using namespace OIS; 
	OIS::Keyboard* mInputDevice = mKeyboard; // Nice hack, eh? :) 
 
	if (mInputDevice->isKeyDown(KC_SPACE)) 
	{ 
		mKeyPressed[KC_SPACE]=TRUE; 
	} 
	else 
	{ 
		mKeyPressed[KC_SPACE]=FALSE; 
	} 
 
	if (mInputDevice->isKeyDown(KC_A)) 
	{ 
		mKeyPressed[KC_A]=TRUE; 
	} 
	else 
	{ 
		mKeyPressed[KC_A]=FALSE; 
	} 
 
 
	if (mInputDevice->isKeyDown(KC_D)) 
	{ 
		mKeyPressed[KC_D]=TRUE; 
	} 
	else 
	{ 
		mKeyPressed[KC_D]=FALSE; 
	} 
 
	if (mInputDevice->isKeyDown(KC_W) ) 
	{ 
		mKeyPressed[KC_W]=TRUE; 
	} 
	else 
	{ 
		mKeyPressed[KC_W]=FALSE; 
	} 
 
	/* Move camera backward by keypress. */ 
	if (mInputDevice->isKeyDown(KC_S) ) 
	{ 
		mKeyPressed[KC_S]=TRUE; 
	} 
	else 
	{ 
		mKeyPressed[KC_S]=FALSE; 
	} 
 
	if (mInputDevice->isKeyDown(KC_PGUP)) 
	{ 
		// Move camera up 
		mTranslateVector.y = mMoveScale; 
	} 
 
	if (mInputDevice->isKeyDown(KC_PGDOWN)) 
	{ 
		// Move camera down 
		mTranslateVector.y = -mMoveScale; 
	} 
	/* Move camera forward by keypress. */ 
	if (mInputDevice->isKeyDown(KC_UP)) 
	{ 
		mTranslateVector.z = -mMoveScale; 
	} 
 
	if (mInputDevice->isKeyDown(KC_DOWN)) 
	{ 
		mTranslateVector.z = mMoveScale; 
	}	 
	 
	if (mInputDevice->isKeyDown(KC_RIGHT)) 
	{ 
		mTranslateVector.x = mMoveScale; 
	} 
 
	if (mInputDevice->isKeyDown(KC_LEFT)) 
	{ 
		mTranslateVector.x = -mMoveScale; 
	} 
 
	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) 
	{ 
		std::ostringstream ss; 
		ss << "screenshot_" << ++mNumScreenShots << ".png"; 
		mWindow->writeContentsToFile(ss.str()); 
		mTimeUntilNextToggle = 0.5; 
		mDebugText = "Saved: " + ss.str(); 
	} 
 
	if (mInputDevice->isKeyDown(KC_R) && mTimeUntilNextToggle <=0) 
	{ 
		mSceneDetailIndex = (mSceneDetailIndex+1)%3 ; 
		switch(mSceneDetailIndex) { 
				case 0 : mCamera->setPolygonMode(PM_SOLID) ; break ; 
				case 1 : mCamera->setPolygonMode(PM_WIREFRAME) ; break ; 
				case 2 : mCamera->setPolygonMode(PM_POINTS) ; break ; 
		} 
		mTimeUntilNextToggle = 0.5; 
	} 
 
	static bool displayCameraDetails = false; 
	if (mInputDevice->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0) 
	{ 
		displayCameraDetails = !displayCameraDetails; 
		mTimeUntilNextToggle = 0.5; 
		if (!displayCameraDetails) 
			mDebugText = ""; 
	} 
	if (displayCameraDetails) 
	{ 
		// Print camera details 
		mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) + 
			" " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()); 
	} 
 
	// Return true to continue rendering 
	return true; 
} 
//------------------------------------------------------------------------------------- 
//------------------------------------------------------------------------------------- 
bool BaseApplication::processUnbufferedMouseInput(const FrameEvent& evt) 
{ 
	using namespace OIS; 
 
	// Rotation factors, may not be used if the second mouse button is pressed 
	// 2nd mouse button - slide, otherwise rotate 
	const MouseState &ms = mMouse->getMouseState(); 
	if( ms.buttonDown( MB_Right ) ) 
	{ 
		mTranslateVector.x += ms.X.rel * 0.13; 
		mTranslateVector.y -= ms.Y.rel * 0.13; 
	} 
	else 
	{ 
		mRotX = Degree(-ms.X.rel * 0.13); 
		mRotY = Degree(-ms.Y.rel * 0.13); 
	} 
 
	return true; 
} 
//------------------------------------------------------------------------------------- 
//------------------------------------------------------------------------------------- 
void BaseApplication::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 BaseApplication::showDebugOverlay(bool show) 
{ 
	if (mDebugOverlay) 
	{ 
		if (show) 
		{ 
			mDebugOverlay->show(); 
		} 
		else 
		{ 
			mDebugOverlay->hide(); 
		} 
	} 
} 
//------------------------------------------------------------------------------------- 
//------------------------------------------------------------------------------------- 
bool BaseApplication::frameStarted(const FrameEvent& evt) 
{ 
	if(mWindow->isClosed()) 
		return false; 
 
	//Need to capture/update each device 
	mKeyboard->capture(); 
	mMouse->capture(); 
 
	mUseBufferedInputMouse = mMouse->buffered(); 
	mUseBufferedInputKeys = mKeyboard->buffered(); 
 
 
 
	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(); 
 
	} 
	else 
	{ 
 
	} 
 
	return true; 
} 
//------------------------------------------------------------------------------------- 
//------------------------------------------------------------------------------------- 
bool BaseApplication::frameEnded(const FrameEvent& evt) 
{ 
	updateStats(); 
	return true; 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::switchMouseMode() 
{ 
	mUseBufferedInputMouse = !mUseBufferedInputMouse; 
	mMouse->setBuffered(mUseBufferedInputMouse); 
} 
//------------------------------------------------------------------------------------- 
void BaseApplication::switchKeyMode() 
{ 
	mUseBufferedInputKeys = !mUseBufferedInputKeys; 
	mKeyboard->setBuffered(mUseBufferedInputKeys); 
} 
//------------------------------------------------------------------------------------- 
//------------------------------------------------------------------------------------- 
bool BaseApplication::keyPressed( const OIS::KeyEvent &arg ) 
{ 
	CEGUI::System *sys = CEGUI::System::getSingletonPtr(); 
	sys->injectKeyDown(arg.key); 
	sys->injectChar(arg.text); 
	return true; 
} 
 
bool BaseApplication::keyReleased( const OIS::KeyEvent &arg ) 
{ 
	CEGUI::System::getSingleton().injectKeyUp(arg.key); 
	if( arg.key == OIS::KC_M ) 
		mMouse->setBuffered( !mMouse->buffered() ); 
	else if( arg.key == OIS::KC_K ) 
		mKeyboard->setBuffered( !mKeyboard->buffered() ); 
	return true; 
} 
 
bool BaseApplication::mouseMoved( const OIS::MouseEvent &arg ) 
{ 
//	CEGUI::System::getSingleton().injectMouseMove(arg.state.X.rel, arg.state.Y.rel); 
	mSystem->injectMouseMove(arg.state.X.rel, arg.state.Y.rel); 
	return true; 
} 
 
bool BaseApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) 
{ 
	CEGUI::System::getSingleton().injectMouseButtonDown(convertButton(id)); 
	return true; 
} 
 
bool BaseApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) 
{ 
	CEGUI::System::getSingleton().injectMouseButtonUp(convertButton(id)); 
	return true; 
} 
 
//Adjust mouse clipping area 
void BaseApplication::windowResized(RenderWindow* rw) 
{ 
	unsigned int width, height, depth; 
	int left, top; 
	rw->getMetrics(width, height, depth, left, top); 
 
	const OIS::MouseState &ms = mMouse->getMouseState(); 
	ms.width = width; 
	ms.height = height; 
} 
 
//Unattach OIS before window shutdown (very important under Linux) 
void BaseApplication::windowClosed(RenderWindow* rw) 
{ 
	//Only close for window that created OIS (the main window in these demos) 
	if( rw == mWindow ) 
	{ 
		if( mInputManager ) 
		{ 
			mInputManager->destroyInputObject( mMouse ); 
			mInputManager->destroyInputObject( mKeyboard ); 
 
			OIS::InputManager::destroyInputSystem(mInputManager); 
			mInputManager = 0; 
		} 
	} 
} 
CEGUI::MouseButton BaseApplication::convertButton(OIS::MouseButtonID buttonID) 
{ 
	switch (buttonID) 
	{ 
	case OIS::MB_Left: 
		return CEGUI::LeftButton; 
 
	case OIS::MB_Right: 
		return CEGUI::RightButton; 
 
	case OIS::MB_Middle: 
		return CEGUI::MiddleButton; 
 
	default: 
		return CEGUI::LeftButton; 
	} 
}