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、構成は以下の通りである。
2.プロジェクト属性の設定
属性ページに入り、「すべての設定」を選択します。
プロファイル->全般
出力ディレクトリ:bin\$
中間ディレクトリ:obj\$
mfcの使用:標準Windowsライブラリを使用する
文字セット:多バイトの文字セットを使う
設定プロパティ->デバッグ
コマンド: $(ORE HOME)\Bin\$
作業ディレクトリ: $(ORE HOME)\Bin\$(Configration)
プロファイル->C/C++->全般
ディレクトリを追加
$(OGRE_HOME)\include$(OGRE HOME)\include\OIS$
プロファイル->C/C++->プリプロセッサ
プリプロセッサ定義
一つを追加しますAXDLL
属性の設定->リンク器->全般
追加ディレクトリライブラリ:
$(OGRE HOME)\lib\$
設定を「Debug」に切り替えます。
属性の設定->リンク—入力
追加の依存項:
OgreMain_d.lib OIS_d.lib
設定を「Release」に切り替えます。
属性の設定->リンク—入力
追加の依存項:
OgreMain.lib OIS.lib
これで、設定作業を完了し、それぞれDEBUGとRELEASEモードで、生成コマンドをクリックして、成功します。
四、レンダリングシーンはMFCウィンドウに
1.プロジェクト->>クラスを追加->C++クラス
追加したクラス名は「CMyOgreApp」で、ソースコードは以下の通りです。
ヘッダファイル
4.View類のOnDraw関数に下記のコードを追加します。
1.フレームの傍受クラスを追加します。CMyFraameListener、コードは以下の通りです。
ヘッダファイル
CMyOgreAppクラスのヘッダファイルに傍受クラスが含まれています。
3.特に指摘したいのは、setupRenderSystem()関数の変更であり、本プロジェクトはデフォルトでOpenGLでレンダリングされていますので、レンダリング選択ダイアログは省略されています。
コードは以下の通りです
プラグィング.d.cfgをplugins.cfgに変更しました。
reourcesd.cfgをresorcess.cfgに変更しました。
これですべての作業が完了し、生成して実行されます。
一、準備工作
本人の配置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、構成は以下の通りである。
2.プロジェクト属性の設定
属性ページに入り、「すべての設定」を選択します。
プロファイル->全般
出力ディレクトリ:bin\$
中間ディレクトリ:obj\$
mfcの使用:標準Windowsライブラリを使用する
文字セット:多バイトの文字セットを使う
設定プロパティ->デバッグ
コマンド: $(ORE HOME)\Bin\$
作業ディレクトリ: $(ORE HOME)\Bin\$(Configration)
プロファイル->C/C++->全般
ディレクトリを追加
$(OGRE_HOME)\include$(OGRE HOME)\include\OIS$
プロファイル->C/C++->プリプロセッサ
プリプロセッサ定義
一つを追加しますAXDLL
属性の設定->リンク器->全般
追加ディレクトリライブラリ:
$(OGRE HOME)\lib\$
設定を「Debug」に切り替えます。
属性の設定->リンク—入力
追加の依存項:
OgreMain_d.lib OIS_d.lib
設定を「Release」に切り替えます。
属性の設定->リンク—入力
追加の依存項:
OgreMain.lib OIS.lib
これで、設定作業を完了し、それぞれDEBUGとRELEASEモードで、生成コマンドをクリックして、成功します。
四、レンダリングシーンはMFCウィンドウに
1.プロジェクト->>クラスを追加->C++クラス
追加したクラス名は「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は初期化されました。 true4.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に変更しました。
これですべての作業が完了し、生成して実行されます。