MFC(VSB 2010)+ORE環境構築

16914 ワード

記事は『Ogre組み込みMFCバカ完全教程』(http://blog.csdn.net/guoyk1990/article/details/25915065)およびOgre公式サイトの例(http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Setting+Up+An+Apple+i+Visual+Studio&structure=Development)。実際の操作の過程でいくつかの問題が発生しました。だから、すべての仕事を完全に記録して、不時の必要に備えて、友達にも参考にしてください。覚えてください。「バカ完全教程」といっても、完全には当てはまらないです。
一、準備工作
        本人の配置Windows 7 64ビットシステム、VSS 2010(32ビット)、OgreSDK_vc 10_v 1-8-1      
       ダウンロードOG RESDK:http://www.ogre3d.org/download/sdk  ,Dディスクのルートディレクトリにインストールします。
二、環境変数の配置
        公式の例ではcmd命令で構成されていますが、本人はこのような方式が苦手で、操作に安全感がありません。したがって、より直感的な方法を採用します。
        ユーザー変数とシステム変数の両方にOGARE_を新規作成します。HOME値は:D:\OgreSDK_vc 10_v 1-8-1
        pathに一つを追加します。%OGARE_HOME
       
        本人は最初はシステム変数の中でこの項目を新築しただけですが、運動プログラムの時、配置が成功していないことを発見しました。いっそ二つの変数を加えて、問題は解決しました。
        環境変数を設定したらパソコンを再起動します。
三、MFC単一ドキュメントアプリケーションの確立
       1.工程名:OgreTest 2、構成は以下の通りである。
MFC(VS2010) + OGRE 环境搭建_第1张图片
2.プロジェクト属性の設定
属性ページに入り、「すべての設定」を選択します。
プロファイル->全般
出力ディレクトリ:bin\$
中間ディレクトリ:obj\$
mfcの使用:標準Windowsライブラリを使用する
文字セット:多バイトの文字セットを使う
       
設定プロパティ->デバッグ
コマンド:  $(ORE HOME)\Bin\$
作業ディレクトリ: $(ORE HOME)\Bin\$(Configration)
プロファイル->C/C++->全般
ディレクトリを追加
$(OGRE_HOME)\include$(OGRE HOME)\include\OIS$
プロファイル->C/C++->プリプロセッサ
プリプロセッサ定義
一つを追加しますAXDLL
MFC(VS2010) + OGRE 环境搭建_第2张图片
属性の設定->リンク器->全般
追加ディレクトリライブラリ:
$(OGRE HOME)\lib\$
MFC(VS2010) + OGRE 环境搭建_第3张图片
設定を「Debug」に切り替えます。
MFC(VS2010) + OGRE 环境搭建_第4张图片
属性の設定->リンク—入力
追加の依存項:
OgreMain_d.lib OIS_d.lib
設定を「Release」に切り替えます。
属性の設定->リンク—入力
追加の依存項:
OgreMain.lib OIS.lib
これで、設定作業を完了し、それぞれDEBUGとRELEASEモードで、生成コマンドをクリックして、成功します。
四、レンダリングシーンはMFCウィンドウに
1.プロジェクト->>クラスを追加->C++クラス
MFC(VS2010) + OGRE 环境搭建_第5张图片
      追加したクラス名は「CMyOgreApp」で、ソースコードは以下の通りです。
ヘッダファイル
#pragma once
#include "ogre.h"
#include "OgreConfigFile.h"
#include "OgreFrameListener.h"
#include "OgreStringConverter.h"
#include "OIS.h"

#include 
#include 
#include "MyFrameListener.h"
using namespace Ogre;
class CMyOgreApp
{
public:
	CMyOgreApp(void);
	~CMyOgreApp(void);

	Ogre::Root* getRoot(void) const {return mRoot;}
	Ogre::Camera* getCamera(void) const {return mCamera;}
	Ogre::SceneNode* getCamNode(void) const {return mCamNode;}
	Ogre::SceneManager* getSceneManager(void) const {return mSceneMgr;}
	Ogre::RenderWindow* getRenderWindow(void) const {return mWindow;}

	bool go(CRect rt, HWND hWnd);
	void createRoot(void);
	void setupResources(void);
	void setupRenderSystem(void);
	void createRenderWindow(HWND m_hWnd, int width, int height);
	int initializeResourceGroups(void);
	void chooseSceneManager(void);
	void createCamera(void);
	void createViewport(void);
	void createScene(void);
	void createFrameListener(void);
	class CMyFrameListener* mListener;

private:
	Ogre::Root* mRoot;
	Ogre::RenderWindow* mWindow;            
	Ogre::SceneManager* mSceneMgr;
	Ogre::Camera* mCamera;
	Ogre::SceneNode* mCamNode;
	OgreBites::SdkCameraMan* mCameraMan;     // basic camera controller
	Ogre::Light* light;
};
ソースファイル
#include "StdAfx.h"
#include "MyOgreApp.h"


CMyOgreApp::CMyOgreApp(void)
{
}


CMyOgreApp::~CMyOgreApp(void)
{
}


bool CMyOgreApp::go(CRect rt, HWND hWnd)
{
	createRoot();
	setupResources();
	setupRenderSystem();
	createRenderWindow(hWnd, rt.Width(), rt.Height());
	chooseSceneManager();
	createCamera();
	createViewport();
	initializeResourceGroups();
	createScene();
	createFrameListener();	//    
	return true;
}


void CMyOgreApp::createRoot(void)
{
//	mRoot = new Ogre::Root("plugins_d.cfg");		//debug   
	//  plugins_d.cfg      plugins.cfg,    ,   DEBUG  RELEASE  ,       
	mRoot = new Ogre::Root("plugins.cfg");			//release   
}


void CMyOgreApp::setupResources(void)
{
	// Load resource paths from config file
	Ogre::ConfigFile cf;
//	cf.load("resources_d.cfg");		//debug   
	//  plugins_d.cfg      plugins.cfg,    ,   DEBUG  RELEASE  ,       
	cf.load("resources.cfg");		//release   

	// Go through all sections & settings in the file
	Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();

	Ogre::String secName, typeName, archName;
	while (seci.hasMoreElements())
	{
		secName = seci.peekNextKey();
		Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
		Ogre::ConfigFile::SettingsMultiMap::iterator i;
		for (i = settings->begin(); i != settings->end(); ++i)
		{
			typeName = i->first;
			archName = i->second;
			Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
				archName, typeName, secName);
		}
	}
}

void CMyOgreApp::setupRenderSystem(void)
{
//	mRoot->showConfigDialog();
//	mRoot->restoreConfig();
	//if (!mRoot->restoreConfig() && !mRoot->showConfigDialog())
	//	throw Ogre::Exception(1, "       ","setupRenderSystem()");

	RenderSystemList* rl = &const_cast(mRoot->getAvailableRenderers());
	RenderSystem* rSys = NULL;
	RenderSystemList::iterator it = rl->begin();
	while (it!=rl->end())
	{
		if (-1 != (*it)->getName().find("OpenGL Rendering Subsystem"))
	//	if (-1 != (*it)->getName().find("Direct3D9 Rendering Subsystem"))
		{
			rSys = (RenderSystem*)(*it);
			break;
		}
		++it;
	}
	rSys->setConfigOption("Full Screen","Yes");
	rSys->setConfigOption("VSync","No");
	mRoot->setRenderSystem(rSys);
}


void CMyOgreApp::createRenderWindow(HWND m_hWnd, int width, int height)
{
	mRoot->initialise(false);//  ogre        ,   MFC   
	NameValuePairList misc;
	misc["externalWindowHandle"] = StringConverter::toString((int)m_hWnd); 
	mWindow = mRoot->createRenderWindow("OgreRenderWindow", width, height, false, &misc);
}


int CMyOgreApp::initializeResourceGroups(void)
{
	TextureManager::getSingleton().setDefaultNumMipmaps(5);
	ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
	return 0;
}


void CMyOgreApp::chooseSceneManager(void)
{
	mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE);
}


void CMyOgreApp::createCamera(void)
{
	// Create the camera
	mCamera = mSceneMgr->createCamera("PlayerCam");

	// Position it at 500 in Z direction
	mCamera->setPosition(Ogre::Vector3(0,0,80));
	// Look back along -Z
	mCamera->lookAt(Ogre::Vector3(0,0,-300));
	mCamera->setNearClipDistance(5);
	mCameraMan = new OgreBites::SdkCameraMan(mCamera);   // create a default camera controller
}


void CMyOgreApp::createViewport(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 CMyOgreApp::createScene(void)
{

	//    
	mSceneMgr->setSkyDome(true, "Examples/CloudySky",6, 8);

	Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");

	Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	headNode->attachObject(ogreHead);

	// Set ambient light
	mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

	// Create a light
	Ogre::Light* l = mSceneMgr->createLight("MainLight");
	l->setPosition(20,80,50);
}

//     
void CMyOgreApp::createFrameListener(void)
{
	mListener= new CMyFrameListener(mWindow, mCamera, mSceneMgr, light);
	mRoot->addFrameListener(mListener);
}
2.View類のヘッダファイルにCMyOgreAppのヘッダファイルが含まれています。
#include "MyOgreApp.h"
二つの変数を宣言します。
public:
	// ogre  
	CMyOgreApp m_ogreApp;
	//     
	bool m_firstDraw;
3.View類のコンストラクターでm_first Drawは初期化されました。  true
4.View類のOnDraw関数に下記のコードを追加します。
void COgreTest2View::OnDraw(CDC* /*pDC*/)
{
	COgreTest2Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO:               
	//Ogre  
	try {
		if(m_firstDraw)
		{
			m_firstDraw = false;
			CRect   rect;
			GetClientRect(&rect);
			m_ogreApp.go(rect,m_hWnd);//  MFC     
			SetTimer(1,20,0);
		}

		m_ogreApp.getRoot()->renderOneFrame();
	} catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		MessageBox(  e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
		std::cerr << "An exception has occured: " <<
			e.getFullDescription().c_str() << std::endl;
#endif
	}
}
5.WM_を追加するTIMERとWM_ERASEBKGNDメッセージ処理関数、コードはそれぞれ以下の通りです。
void COgreTest2View::OnTimer(UINT_PTR nIDEvent)
{
	// TODO:              /      
	if (1 == nIDEvent)
	{
		m_ogreApp.getRoot()->renderOneFrame();
	}
	CView::OnTimer(nIDEvent);
}
BOOL COgreTest2View::OnEraseBkgnd(CDC* pDC)
{
	// TODO:              /      
	return TRUE;
}
五、イベント処理方法を追加し、人と機の相互作用を実現する。
1.フレームの傍受クラスを追加します。CMyFraameListener、コードは以下の通りです。
ヘッダファイル
#pragma once
#include "ogre.h"
#include "OgreConfigFile.h"
#include "OgreFrameListener.h"
#include "OgreStringConverter.h"
#include "OIS.h"

#include "MyOgreApp.h"
#include 
#include 
#include 
#include 

#include 
#include 
using namespace Ogre;
class CMyFrameListener: public FrameListener, public OIS::MouseListener,public Ogre::WindowEventListener, public OIS::KeyListener
{
public:
	CMyFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr, Light* light);
	~CMyFrameListener(void);
	bool frameRenderingQueued(const Ogre::FrameEvent& evt);
	bool mouseMoved(const OIS::MouseEvent &e);
	bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id); 
	bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id);
	bool keyPressed(const OIS::KeyEvent &e);
	bool keyReleased(const OIS::KeyEvent &e);

protected:

	Ogre::SceneManager *mSceneMgr;//     
	Ogre::SceneNode* mCamNode;//     
	Ogre::Camera* mCamera;//   
	Ogre::RenderWindow* mWindow;//    
	Ogre::Light* light;//  

	OIS::Keyboard* mKeyboard;//           
	OIS::Mouse* mMouse;      //      
	OIS::InputManager* mInputManager;//      

//	OgreBites::SdkTrayManager* mTrayMgr;
	OgreBites::SdkCameraMan* mCameraMan;     // basic camera controller
	bool mRBtdown;
};
ソースファイル
#include "StdAfx.h"
#include "MyFrameListener.h"

CMyFrameListener::CMyFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr, Light *l): mMouse(0), 
	mKeyboard(0), mInputManager(0), mWindow(win), mCamera(cam), light(l)
{
	mRBtdown = false;
	mCamNode=cam->getParentSceneNode();
	mSceneMgr = sceneMgr;


	size_t windowHnd = 0;
	std::ostringstream windowHndStr;
	OIS::ParamList pl;


	mCameraMan = new OgreBites::SdkCameraMan(mCamera);  


	windowHnd = (size_t )AfxGetMainWnd()->GetSafeHwnd(); //              MFC   
	windowHndStr << windowHnd;
	// OIS          ,     MFC      , view   
	pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));


	//             ,                     
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
	//        
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
	mInputManager = OIS::InputManager::createInputSystem(pl);


	mKeyboard = static_cast<:keyboard>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
	mMouse = static_cast<:mouse>(mInputManager->createInputObject( OIS::OISMouse, true ));


	mMouse->setEventCallback(this);
	mKeyboard->setEventCallback(this);
}




CMyFrameListener::~CMyFrameListener(void)
{
	mInputManager->destroyInputObject(mMouse);
	mInputManager->destroyInputObject(mKeyboard);
	OIS::InputManager::destroyInputSystem(mInputManager);
	mInputManager = 0;
}




bool CMyFrameListener::frameRenderingQueued(const Ogre::FrameEvent& e){


	mMouse->capture();
	mKeyboard->capture();
	mCameraMan->frameRenderingQueued(e); 
	return true;
}


bool CMyFrameListener::mouseMoved(const OIS::MouseEvent &e)
{
	if (mRBtdown)
	{
		mCameraMan->injectMouseMove(e);
	}
	
	return true;
}


bool CMyFrameListener::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
//	mCameraMan->injectMouseDown(e, id);
	if (id == OIS::MB_Right)
	{
		mRBtdown = true;
	}
	
	return true;
}


bool CMyFrameListener::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{


//	mCameraMan->injectMouseUp(e, id);
	if (id == OIS::MB_Right)
	{
		mRBtdown = false;
	}
	return true;
}
//    
bool CMyFrameListener::keyPressed(const OIS::KeyEvent &e)
{
	
	mCameraMan->injectKeyDown(e);


	return true;
}


bool CMyFrameListener::keyReleased(const OIS::KeyEvent &e)
{
	 mCameraMan->injectKeyUp(e);
	return true;
}
2.モニターと応答を実現するために、CMyOgreAppクラスを修正する必要があります。これらの仕事は上に貼ったコードの中ですでに完成しました。ここで簡単に説明します。
CMyOgreAppクラスのヘッダファイルに傍受クラスが含まれています。
#include "MyFrameListener.h"
CMyFraameListenerクラスの変数を宣言します。
class CMyFrameListener* mListener; 
関数を宣言します。関数の実装は上のコードに貼り付けられました。
void createFrameListener(void); 
go()関数でクリエテFraame Listenerを呼び出します。
3.特に指摘したいのは、setupRenderSystem()関数の変更であり、本プロジェクトはデフォルトでOpenGLでレンダリングされていますので、レンダリング選択ダイアログは省略されています。
コードは以下の通りです
void CMyOgreApp::setupRenderSystem(void)
{
	RenderSystemList* rl = &const_cast(mRoot->getAvailableRenderers());
	RenderSystem* rSys = NULL;
	RenderSystemList::iterator it = rl->begin();
	while (it!=rl->end())
	{
		if (-1 != (*it)->getName().find("OpenGL Rendering Subsystem"))
	//	if (-1 != (*it)->getName().find("Direct3D9 Rendering Subsystem"))
		{
			rSys = (RenderSystem*)(*it);
			break;
		}
		++it;
	}
	rSys->setConfigOption("Full Screen","Yes");
	rSys->setConfigOption("VSync","No");
	mRoot->setRenderSystem(rSys);
}
レンダリング選択ダイアログをイジェクトすると、コードは以下のように変更できます。
void CMyOgreApp::setupRenderSystem(void)
{
	mRoot->showConfigDialog();
}
4.DEBUGとRELEASEモードでは、プログラムが正しく動作することを保証するため、本人はD:\OgreSDK_vc 10_v 1-8-1\bin\debugフォルダの二つのファイルの名前が変更されました。
プラグィング.d.cfgをplugins.cfgに変更しました。
reourcesd.cfgをresorcess.cfgに変更しました。
これですべての作業が完了し、生成して実行されます。
MFC(VS2010) + OGRE 环境搭建_第6张图片