ogre嵌入MFC教程

来源:互联网 发布:java环境变量设置作用 编辑:程序博客网 时间:2024/06/01 08:08

由于实验室项目的需要,要学习ogre嵌入MFC,在这里把我从小白到实现的过程写下来给大家分享。

首先声明一下,在这里我建的是基于单文档的ogre嵌入MFC,多文档的并没有研究,后面有时间实现了再拿来分享。

配置环境:VS2008+ogre1.6.5

第一步:

创建一个MFC SDI程序(之前并没有学过MFC,最近才开始看,这一部分也是参考网上的教程,具体哪位大侠的博客忘记了,抱歉~)

1.新建项目,MFC应用程序。
2.MFC应用程序向导设置如下图:


3.生成的类设置如下:


4.至此,一个MFC SDI程序创建完成,编译运行,可以得到一个空窗口视图。


    如果上一步选择基类为CFormView,那么可以进一步创建一个继承    
       CFormView的类,可以命名为OgreControl,用来放置一些控件来
       和Ogre的渲染窗口进行交互。
     
        在工程名上右键->添加->类->MFC类->添加,类名OgreControl,基  
        类为 CFormView,完成。如下图:

5.


6.至此第一步完成。

第二步 分割窗口(暂时跳过)

这一步可以暂时不用,可以在掌握Ogre和MFC之后进行进一步的学习和练习使用。
本例子创建单视图文档。

第三步 Ogre嵌入MFC

这一步主要修改对应View的.h和.cpp文件。
1.OgreMFCView.h的代码如下:

// OgreMFCView.h : COgreMFCView 类的接口  //    #pragma once    //添加的代码  #include "ogre.h"  #include "OgreConfigFile.h"  using namespace Ogre;      class COgreMFCView : public CView  {  protected: // 仅从序列化创建      COgreMFCView();      DECLARE_DYNCREATE(COgreMFCView)    // 属性  public:      COgreMFCDoc* GetDocument() const;    // 操作  public:    // 重写  public:      virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);  protected:      virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);      virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);      virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);        void setupResources();//添加的代码  // 实现  public:      virtual ~COgreMFCView();  #ifdef _DEBUG      virtual void AssertValid() const;      virtual void Dump(CDumpContext& dc) const;  #endif    protected:    // 生成的消息映射函数  protected:      DECLARE_MESSAGE_MAP()  public:      afx_msg BOOL OnEraseBkgnd(CDC* pDC);      afx_msg void OnLButtonDown(UINT nFlags, CPoint point);    private:      CPoint              m_mouseLast;      Root* mRoot;      RenderWindow* mWindow;      SceneManager* mSceneMgr;      Camera* mCamera;//添加的代码  public:      afx_msg void OnMouseMove(UINT nFlags, CPoint point);      afx_msg void OnTimer(UINT_PTR nIDEvent);      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);      afx_msg void OnDestroy();  };   #ifndef _DEBUG  // OgreMFCView.cpp 中的调试版本  inline COgreMFCDoc* COgreMFCView::GetDocument() const     { return reinterpret_cast<COgreMFCDoc*>(m_pDocument); }  #endif  
2. 修改View对应的.cpp文件

// OgreMFCView.cpp : COgreMFCView 类的实现  //   #include "stdafx.h"  #include "OgreMFC.h"   #include "OgreMFCDoc.h"  #include "OgreMFCView.h"   #define OGRE_DEBUG_MEMORY_MANAGER 1          //#ifdef _DEBUG  //#define new DEBUG_NEW  //#endif      // COgreMFCView    IMPLEMENT_DYNCREATE(COgreMFCView, CView)    BEGIN_MESSAGE_MAP(COgreMFCView, CView)      // 标准打印命令      ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)      ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)      ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)      ON_WM_ERASEBKGND()      ON_WM_LBUTTONDOWN()      ON_WM_MOUSEMOVE()      ON_WM_TIMER()      ON_WM_CREATE()      ON_WM_DESTROY()  END_MESSAGE_MAP()    // COgreMFCView 构造/析构    COgreMFCView::COgreMFCView()  {      // TODO: 在此处添加构造代码      mRoot = 0;  }    COgreMFCView::~COgreMFCView()  {      delete mRoot;  }    BOOL COgreMFCView::PreCreateWindow(CREATESTRUCT& cs)  {      // TODO: 在此处通过修改      //  CREATESTRUCT cs 来修改窗口类或样式        return CView::PreCreateWindow(cs);  }    void COgreMFCView::setupResources()  {      // 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);          }      }  }      // COgreMFCView 绘制    void COgreMFCView::OnDraw(CDC* /*pDC*/)  {      static bool once = true;        COgreMFCDoc* pDoc = GetDocument();      ASSERT_VALID(pDoc);      if (!pDoc)          return;              if(once)      {             mRoot = new Root();          setupResources();            RenderSystemList* rl = Root::getSingleton().getAvailableRenderers();          //D3D9RenderSystem           RenderSystem* rsys = NULL;            RenderSystemList::iterator it = rl->begin();            while( it != rl->end() )          {               if( -1 != ( *it )->getName().find( "Direct3D9" )  )              {                  rsys = (RenderSystem*)( *it );                  break;              }              it++;          }            //mRoot->showConfigDialog();            ////rsys->initConfigOptions();           //rsys->setConfigOption("Colour Depth", "32" );          ////rsys->setConfigOption("Anti aliasing", "None" );          ////rsys->setConfigOption("Floating-point mode", "Fastest" );          rsys->setConfigOption( "Full Screen", "No" );          ////rsys->setConfigOption("Rendering Device","NVIDIA GeForce FX 5700VE");          rsys->setConfigOption( "VSync", "No" );          //rsys->setConfigOption( "Video Mode", "800 x 600 @ 32-bit colour" );          rsys->setConfigOption( "Video Mode", "640 x 480" );          //rsys->setConfigOption( "Display Frequency", "60" );            // 起用          mRoot->setRenderSystem( rsys );           mRoot->initialise( false );            NameValuePairList miscParams;           unsigned int h = (unsigned int)this->GetSafeHwnd();          miscParams["externalWindowHandle"] = StringConverter::toString(h);          mWindow = NULL;          mWindow = mRoot->createRenderWindow( "View", 640, 480, false, &miscParams );           once = false;              mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");            // 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);            // 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()));            ResourceGroupManager::getSingleton().initialiseAllResourceGroups();              //createScene();          // Set ambient light          mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));            // Create a skydome          mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);            // Create a light          Light* l = mSceneMgr->createLight("MainLight");          // Accept default settings: point light, white diffuse, just set position          // NB I could attach the light to a SceneNode if I wanted it to move automatically with          //  other objects, but I don't          l->setPosition(20,80,50);            Entity *ent;            // Define a floor plane mesh          Plane p;          p.normal = Vector3::UNIT_Y;          p.d = 200;          MeshManager::getSingleton().createPlane("FloorPlane",              ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,               p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Z);            // Create an entity (the floor)          ent = mSceneMgr->createEntity("floor", "FloorPlane");          ent->setMaterialName("Examples/RustySteel");            mSceneMgr->getRootSceneNode()->attachObject(ent);            ent = mSceneMgr->createEntity("head", "ogrehead.mesh");          // Attach to child of root node, better for culling (otherwise bounds are the combination of the 2)          mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);            mWindow->update();      }      else      {          //mRoot->startRendering();          mWindow->update();          //drawScene();      }  }      // COgreMFCView 打印    BOOL COgreMFCView::OnPreparePrinting(CPrintInfo* pInfo)  {      // 默认准备      return DoPreparePrinting(pInfo);  }    void COgreMFCView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)  {      // TODO: 添加额外的打印前进行的初始化过程  }    void COgreMFCView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)  {      // TODO: 添加打印后进行的清除过程  }      // COgreMFCView 诊断   #ifdef _DEBUG  void COgreMFCView::AssertValid() const  {      CView::AssertValid();  }    void COgreMFCView::Dump(CDumpContext& dc) const  {      CView::Dump(dc);  }    COgreMFCDoc* COgreMFCView::GetDocument() const // 非调试版本是内联的  {      ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COgreMFCDoc)));      return (COgreMFCDoc*)m_pDocument;  }  #endif //_DEBUG      // COgreMFCView 消息处理程序    BOOL COgreMFCView::OnEraseBkgnd(CDC* pDC)  {      // TODO: Add your message handler code here and/or call default        //return CView::OnEraseBkgnd(pDC);      return true;  }    void COgreMFCView::OnLButtonDown(UINT nFlags, CPoint point)  {      // TODO: Add your message handler code here and/or call default        m_mouseLast = point;      CView::OnLButtonDown(nFlags, point);  }    void COgreMFCView::OnMouseMove(UINT nFlags, CPoint point)  {      // TODO: Add your message handler code here and/or call default        if(nFlags & MK_LBUTTON)      {          CPoint mouseDiff = point - m_mouseLast;          m_mouseLast = point;            mCamera->yaw(Degree(mouseDiff.x) * 0.2);          mCamera->pitch(Degree(mouseDiff.y) * 0.2);      }      CView::OnMouseMove(nFlags, point);  }    void COgreMFCView::OnTimer(UINT_PTR nIDEvent)  {      // TODO: Add your message handler code here and/or call default        Invalidate();      CView::OnTimer(nIDEvent);  }    int COgreMFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)  {      if (CView::OnCreate(lpCreateStruct) == -1)          return -1;        // TODO:  Add your specialized creation code here      SetTimer(1, 30, NULL);      return 0;  }    void COgreMFCView::OnDestroy()  {      CView::OnDestroy();        // TODO: Add your message handler code here      KillTimer(1);  }
3.生成解决方案,调试运行,出现如下界面,大功告成。



后记

可参考文档:

1)一步一步教你把Ogre嵌入MFC – FreeStyle


http://www.zyh1690.org/step-by-step-to-teach-you-the-ogre-embedded-mfc/
(2)ogre+MFC - tulun的专栏 - 博客频道 - CSDN.NET


http://blog.csdn.net/tulun/article/details/5486828
(3)ogre的初始化与启动以及显示对象设置 - 程序园


http://www.kwstu.com/ArticleView/kwstu_20139108019768

































0 0
原创粉丝点击