|
下面的代码运行没有所要的结果 都来看看怎么回事
#ifndef __MyExampleFrameListener_H__
#define __MyExampleFrameListener_H__
#include "Ogre.h"
#include "OgreStringConverter.h"
#include "OgreException.h"
//Use this define to signify OIS will be used as a DLL
//(so that dll import/export macros are in effect)
#define OIS_DYNAMIC_LIB
#include <OIS/OIS.h> //使用OIS
using namespace Ogre;
using namespace std;
using Ogre::uint;
class MyExampleFrameListener: public FrameListener, public WindowEventListener
{
protected:
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: ";
static String batches = "Batch 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* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");
guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));
OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
guiDbg->setCaption(mDebugText);
guiDbg->setColour(ColourValue(1,1,1));
}
catch(...) { /* ignore */ }
}
public:
// Constructor takes a RenderWindow because it uses that to determine input context
MyExampleFrameListener(RenderWindow* win, Camera* cam, HWND h,bool bufferedKeys = false, bool bufferedMouse = false,
bool bufferedJoy = false ) :
mCamera(cam), m_hwnd(h),mTranslateVector(Vector3::ZERO), mWindow(win), mStatsOn(true), mNumScreenShots(0),
mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR),
mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0),
mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0)
{
using namespace OIS;
mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
ParamList pl;
//下面这段是重点, 使用Win32的窗口
unsigned long h1 = (unsigned long)m_hwnd;
pl.insert(std::make_pair(std::string("WINDOW"), StringConverter::toString(h1)));
pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
mInputManager = InputManager::createInputSystem( pl );
//Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
mKeyboard = static_cast<Keyboard*>(mInputManager->createInputObject( OISKeyboard, bufferedKeys ));
mMouse = static_cast<Mouse*>(mInputManager->createInputObject( OISMouse, bufferedMouse ));
try {
mJoy = static_cast<JoyStick*>(mInputManager->createInputObject( OISJoyStick, bufferedJoy ));
}
catch(...) {
mJoy = 0;
}
//Set initial mouse clipping size
windowResized(mWindow);
showDebugOverlay(true);
//Register as a Window listener
WindowEventUtilities::addWindowEventListener(mWindow, this);
}
//Adjust mouse clipping area
virtual void 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)
virtual void 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 );
mInputManager->destroyInputObject( mJoy );
OIS::InputManager::destroyInputSystem(mInputManager);
mInputManager = 0;
}
}
}
virtual ~MyExampleFrameListener()
{
//Remove ourself as a Window listener
WindowEventUtilities::removeWindowEventListener(mWindow, this);
windowClosed(mWindow);
}
virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
{
using namespace OIS;
int vel=1;//速度增加1倍
if(mKeyboard->isKeyDown(KC_A))
mTranslateVector.x = -mMoveScale*vel; // Move camera left
if(mKeyboard->isKeyDown(KC_D))
mTranslateVector.x = mMoveScale*vel; // Move camera RIGHT
if(mKeyboard->isKeyDown(KC_UP) || mKeyboard->isKeyDown(KC_W) )
mTranslateVector.z = -mMoveScale*vel; // Move camera forward
if(mKeyboard->isKeyDown(KC_DOWN) || mKeyboard->isKeyDown(KC_S) )
mTranslateVector.z = mMoveScale*vel; // Move camera backward
if(mKeyboard->isKeyDown(KC_PGUP))
mTranslateVector.y = mMoveScale; // Move camera up
if(mKeyboard->isKeyDown(KC_PGDOWN))
mTranslateVector.y = -mMoveScale; // Move camera down
if(mKeyboard->isKeyDown(KC_RIGHT))
mCamera->yaw(-mRotScale);
if(mKeyboard->isKeyDown(KC_LEFT))
mCamera->yaw(mRotScale);
if( mKeyboard->isKeyDown(KC_ESCAPE) || mKeyboard->isKeyDown(KC_Q) )
return false;
if( mKeyboard->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0 )
{
mStatsOn = !mStatsOn;
showDebugOverlay(mStatsOn);
mTimeUntilNextToggle = 1;
}
if( mKeyboard->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(mKeyboard->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
{
std: stringstream ss;
ss << "screenshot_" << ++mNumScreenShots << ".png";
mWindow->writeContentsToFile(ss.str());
mTimeUntilNextToggle = 0.5;
mDebugText = "Saved: " + ss.str();
}
if(mKeyboard->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(mKeyboard->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
{
displayCameraDetails = !displayCameraDetails;
mTimeUntilNextToggle = 0.5;
if (!displayCameraDetails)
mDebugText = "";
}
// Print camera details
if(displayCameraDetails)
mDebugText = " : " + StringConverter::toString(mCamera->getDerivedPosition()) +
" " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation());
// Return true to continue rendering
return true;
}
bool 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_Middle ) )
{
mTranslateVector.x -= ms.X.rel * 0.13;
mTranslateVector.y += ms.Y.rel * 0.13;
}
if(ms.buttonDown(MB_Left))//此处改为左键按下旋转镜头
{
mRotX = Degree(-ms.X.rel * 0.13);
mRotY = Degree(-ms.Y.rel * 0.13);
}
if(ms.Z.rel)
mTranslateVector.z = -ms.Z.rel;//使用滚轮来ZoomIn/ZoomOut
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)
{
using namespace OIS;
if(mWindow->isClosed()) return false;
//Need to capture/update each device
mKeyboard->capture();
mMouse->capture();
if( mJoy ) mJoy->capture();
bool buffJ = (mJoy) ? mJoy->buffered() : true;
//Check if one of the devices is not buffered
if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
{
// one of the input modes is immediate, so setup what is needed for immediate 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 = Ogre::Vector3::ZERO;
}
//Check to see which device is not buffered, and handle it
if( !mKeyboard->buffered() )
if( processUnbufferedKeyInput(evt) == false )
return false;
if( !mMouse->buffered() )
if( processUnbufferedMouseInput(evt) == false )
return false;
if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
moveCamera();
return true;
}
bool frameEnded(const FrameEvent& evt)
{
updateStats();
return true;
}
protected:
Camera* mCamera;
HWND m_hwnd;
Vector3 mTranslateVector;
RenderWindow* mWindow;
bool mStatsOn;
std::string mDebugText;
unsigned int mNumScreenShots;
float mMoveScale;
Degree mRotScale;
// just to stop toggles flipping too fast
Real mTimeUntilNextToggle ;
Radian mRotX, mRotY;
TextureFilterOptions mFiltering;
int mAniso;
int mSceneDetailIndex ;
Real mMoveSpeed;
Degree mRotateSpeed;
Overlay* mDebugOverlay;
//OIS Input devices
OIS::InputManager* mInputManager;
OIS::Mouse* mMouse;
OIS::Keyboard* mKeyboard;
OIS::JoyStick* mJoy;
};
#endif
// Win32Ogre.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "Win32Ogre.h"
#include "ogre.h"
#include "MyExampleFrameListener.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
HWND hWnd;
//OGRE -------------------//
Root* mRoot;
RenderWindow* mWindow;
SceneManager* mSceneMgr;
Camera* mCamera;
Viewport* vp ;
void setupResources();
void SetRoot()
{
//----创建根实例
mRoot = new Root();//无参数即默认参数Root("plugin.cfg","ogre.cfg","ogre.log")
//----设置资源目录(声明资源:此时资源未初始化,不可使用)
setupResources();//目录设置根据"resource.cfg"
if(!mRoot->showConfigDialog())//你不想弹出那个配置对话框就注释掉此句, 下面的程序是手动来配置,手动配置自动使用D3D
{
//-----初始化渲染器
RenderSystemList* rl = Root::getSingleton().getAvailableRenderers();//获得所有可用渲染器
RenderSystem* rsys = NULL;
RenderSystemList::iterator it = rl->begin();//循环列表,得到GL渲染器
while( it != rl->end() )
{
if( -1 != ( *it )->getName().find( "3D9" ) )
{
rsys = (RenderSystem*)( *it );
break;
}
it++;
}
//设置渲染器属性
rsys->setConfigOption( "Full Screen", "No" );
rsys->setConfigOption( "VSync", "No" );
rsys->setConfigOption( "Video Mode", "800 x 600" );
mRoot->setRenderSystem( rsys ); // 起用该渲染器
}
mRoot->initialise(0);
//-------初始化渲染窗口(自建)
NameValuePairList parms;
parms["externalWindowHandle"] = StringConverter::toString((long)hWnd);
RECT rect;
::GetWindowRect(hWnd,&rect);
mWindow = mRoot->createRenderWindow("MFC Window", rect.right-rect.left, rect.bottom-rect.top, false, &parms);
//渲染窗口事实上是由渲染器所创建RenderSystem::CreateRenderWindow
}
void CreateCamVP()
{
mCamera = mSceneMgr->createCamera("PlayerCam");
mCamera->setPosition(Vector3(0,0,500));
mCamera->lookAt(Vector3(0,0,-300));
mCamera->setNearClipDistance(1);
mCamera->setFarClipDistance(100000);
mCamera->setQueryFlags(8);//临时定一个掩码值,暂时与现在的所有掩码不冲突,保证检测不到相机
// -------创建视口
vp = mWindow->addViewport(mCamera);
// 视口创建好后调整相机的比例
mCamera->setAspectRatio(
Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
}
//设置阴影
void AddShadowEffect()
{
mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
LiSPSMShadowCameraSetup* lispsm = new LiSPSMShadowCameraSetup();
lispsm->setOptimalAdjustFactor(0.5);
mSceneMgr->setShadowFarDistance(1000);
mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(lispsm));
mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
}
//设置场景相关的效果,如灯光,雾,天空,视口背景色等
void SetAmbientRef()
{
//--------创建灯光
Light* l = mSceneMgr->createLight("MainLight");
l->setPosition(20,2000,50);
//mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 800, 2000);
mSceneMgr->setAmbientLight(ColourValue(0.5,0.5,0.5));
ColourValue fadeColour(0.93, 0.86, 0.76);
mWindow->getViewport(0)->setBackgroundColour(fadeColour);
mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
}
void setupResources()
{
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 CreateScene()
{
//----------初始化OGRE(自动加载插件)----------------//
SetRoot();
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
//-------创建场景管理器-------------------------------//
mSceneMgr = mRoot->createSceneManager(ST_GENERIC);//在新版本中,getSceneManager全部更新为createSceneManager
//-----------打开阴影-------------------------------//
AddShadowEffect();
//=======================================================//
//--------创建相机并设置,创建视口----//
CreateCamVP();
//===================================//
//-------设置环境相关,如灯光,雾,天空等------------//
SetAmbientRef();
//===================================================//
//-------设置FramListener---------------------------//
MyExampleFrameListener *m_FramListenler=new MyExampleFrameListener(mWindow,mCamera,hWnd);
mRoot->addFrameListener(m_FramListenler);
//==================================================//.
mWindow->update();
}
//========================//
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32OGRE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32OGRE));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32OGRE));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32OGRE);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
SetTimer(hWnd,1,1,0);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_TIMER: //这里的处理,如果在MFC中,即是响应OnTimer
{
static int once=1;
if(once==1)
{
once=2;
CreateScene(); //这里即全部的初始化操作, 放在这里是为了不影响窗口初始化,能够先弹出来
}
if(once==2)
mRoot->renderOneFrame(); //每帧渲染, 当然前提是先初始化好OGRE
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
} |
|