OGRE + MFC 多线程框架

时间:2022-09-28 18:31:17

http://blog.csdn.net/pizi0475

痞子龙3D编程

 

OgreApplication.h

 

#pragma once
#include <Ogre.h>
#include <OIS/OIS.h>
#include <CEGUI/CEGUI.h>
#include <OgreCEGUIRenderer.h>
#include "OgreFrameListener.h"

class COgreApplication
{
public:
 COgreApplication(void);
 ~COgreApplication(void);
public:
 void Initialize(HWND hWnd, HWND hWndMouse, LPRECT windowRect, BOOL* pbSizing);
 void Update(void);
 void Exit(void);
 void OnSize(void);
 void OnPosChange(void);

protected:
 Ogre::Root               *m_pOgreRoot;
 OIS::Keyboard            *m_pOisKeyboard;
 OIS::Mouse               *m_pOisMouse;
 OIS::InputManager        *m_pOisInputManager;
 CEGUI::OgreCEGUIRenderer *m_pCeguiRenderer;
 CEGUI::System            *m_pCeguiSystem;
 COgreFrameListener       *m_pOgreListener;
    Ogre::RenderWindow       *m_pOgreWindow;
 Ogre::Camera             *m_pOgreCamera;
    Ogre::SceneManager       *m_pOgreSceneMgr;
 LPRECT                   m_pOgreWindowRect;
    HWND                     m_hWnd;
 HWND                     m_hWndMouse;
    BOOL                     m_bExit;
    BOOL                     *m_pbSizing;

protected:
 void CreateRoot();
 void DefineResources();
 void SetupRenderSystem();
 void CreateRenderWindow();
 void InitializeResourceGroups();
 void SetupScene();
 void SetupInputSystem();
 void SetupCEGUI();
 void CreateFrameListener();
};

 

 

OgreApplication.cpp

 

#include "StdAfx.h"
#include "OgreApplication.h"
#include "OgreMFC_frame.h"

COgreApplication::COgreApplication(void)
{
 m_bExit = FALSE;
}

COgreApplication::~COgreApplication(void)
{
 m_pOisInputManager->destroyInputObject(m_pOisKeyboard);
 m_pOisInputManager->destroyInputObject(m_pOisMouse);
 OIS::InputManager::destroyInputSystem(m_pOisInputManager);

 delete m_pCeguiRenderer;
 delete m_pCeguiSystem;

 delete m_pOgreListener;
 delete m_pOgreRoot;
}

void COgreApplication::Initialize(HWND hWnd,HWND hWndMouse,LPRECT windowRect, BOOL* pbSizing)
{
 m_hWnd = hWnd;
    m_hWndMouse = hWndMouse;
 m_pOgreWindowRect = windowRect;
 m_pbSizing = pbSizing;

 CreateRoot();
 DefineResources();
 SetupRenderSystem();
 CreateRenderWindow();
 InitializeResourceGroups();
 SetupScene();
 SetupInputSystem();
 SetupCEGUI();
 CreateFrameListener();
}

void COgreApplication::CreateRoot()
{
 m_pOgreRoot = new Ogre::Root("Plugins.cfg");
 TRACE("new Ogre::Root/n");

}

void COgreApplication::DefineResources()
{
 Ogre::String secName, typeName, archName;
 Ogre::ConfigFile cf;
 cf.load("resources.cfg");

 Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
 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 COgreApplication::SetupRenderSystem()
{
 if (!m_pOgreRoot->restoreConfig() && !m_pOgreRoot->showConfigDialog())
  throw Ogre::Exception(52, "User canceled the config dialog!", "Application::setupRenderSystem()");

 //// Do not add this to the application
 //RenderSystem *rs = m_pOgreRoot->getRenderSystemByName("Direct3D9 Rendering Subsystem");
 //                                      // or use "OpenGL Rendering Subsystem"
 //m_pOgreRoot->setRenderSystem(rs);
 //rs->setConfigOption("Full Screen", "No");
 //rs->setConfigOption("Video Mode", "800 x 600 @ 32-bit colour");
}

void COgreApplication::CreateRenderWindow()
{
 m_pOgreRoot->initialise(FALSE);
 Ogre::NameValuePairList misc;
 misc["externalWindowHandle"] = Ogre::StringConverter::toString((int)m_hWnd);
 m_pOgreWindow = m_pOgreRoot->createRenderWindow("Main RenderWindow", 800, 600, FALSE, &misc);
}

void COgreApplication::InitializeResourceGroups()
{
 Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
 Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}

void COgreApplication::SetupScene()
{
 m_pOgreSceneMgr = m_pOgreRoot->createSceneManager(Ogre::SceneType::ST_GENERIC, "Default SceneManager");
 m_pOgreCamera = m_pOgreSceneMgr->createCamera("Camera");
 Ogre::Viewport *vp = m_pOgreWindow->addViewport(m_pOgreCamera);

 Ogre::Entity *ent = m_pOgreSceneMgr->createEntity("head", "ogrehead.mesh");
 m_pOgreSceneMgr->getRootSceneNode()->createChildSceneNode("head")->attachObject(ent);
 m_pOgreSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));
 Ogre::Light* light = m_pOgreSceneMgr->createLight("MainLight");
 light->setPosition(20,80,50);
 m_pOgreCamera->setPosition(0,0,150);
 m_pOgreCamera->setDirection(0,0,-1);
}

void COgreApplication::SetupInputSystem()
{
 size_t windowHnd = (size_t )m_hWndMouse;

 std::ostringstream windowHndStr;
 OIS::ParamList pl;
 windowHndStr << windowHnd;
 pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
 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_FOREGROUND" )));
 pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
 m_pOisInputManager = OIS::InputManager::createInputSystem(pl);

 try
 {
  m_pOisKeyboard = static_cast<OIS::Keyboard*>(m_pOisInputManager->createInputObject(OIS::OISKeyboard, FALSE));
  m_pOisMouse = static_cast<OIS::Mouse*>(m_pOisInputManager->createInputObject(OIS::OISMouse, FALSE));
  //mJoy = static_cast<OIS::JoyStick*>(m_pOisInputManager->createInputObject(OIS::OISJoyStick, FALSE));
  RECT mainRect;
  AfxGetMainWnd()->GetClientRect(&mainRect);
  m_pOisMouse->getMouseState().width = mainRect.right;
  m_pOisMouse->getMouseState().height = mainRect.bottom;
 }
 catch (const OIS::Exception &e)
 {
  throw new Ogre::Exception(42, e.eText, "Application::setupInputSystem");
 }
}

void COgreApplication::SetupCEGUI()
{
 // CEGUI setup
 m_pCeguiRenderer = new CEGUI::OgreCEGUIRenderer(m_pOgreWindow, Ogre::RENDER_QUEUE_OVERLAY, FALSE, 3000, m_pOgreSceneMgr);
 TRACE("new CEGUI::OgreCEGUIRenderer/n");

 m_pCeguiSystem = new CEGUI::System(m_pCeguiRenderer);
 TRACE("new CEGUI::System/n");

 // Other CEGUI setup here.
}

void COgreApplication::CreateFrameListener()
{
 m_pOgreListener = new COgreFrameListener(m_pOisKeyboard,m_pOisMouse,m_pOgreCamera,m_pOgreWindow,m_pOgreWindowRect,&m_bExit,m_pbSizing);
 TRACE("new COgreFrameListener/n");
 m_pOgreRoot->addFrameListener(m_pOgreListener);
}

void COgreApplication::Update(void)
{
 m_pOgreRoot->renderOneFrame();
}

void COgreApplication::Exit(void)
{
 m_bExit = TRUE;
 m_pOgreWindow = NULL;
 m_pOgreRoot->shutdown();
}

void COgreApplication::OnSize(void)
{
 if (m_pOgreWindow)
 {
  m_pOgreWindow->windowMovedOrResized();
  if ( m_pOgreCamera )
      m_pOgreCamera->setAspectRatio((Ogre::Real)m_pOgreWindow->getWidth() / (Ogre::Real)m_pOgreWindow->getHeight());
  m_pOgreCamera->yaw(Ogre::Radian(0));
 }
 OnPosChange();
}

void COgreApplication::OnPosChange(void)
{
 RECT mainRect;
 AfxGetMainWnd()->GetClientRect(&mainRect);
 m_pOisMouse->getMouseState().width = mainRect.right;
 m_pOisMouse->getMouseState().height = mainRect.bottom;
}

 

 

OgreFrameListener.h

 

#pragma once
#include <Ogre.h>
#include <OIS/OIS.h>
#include <CEGUI/CEGUI.h>
#include <OgreCEGUIRenderer.h>

class COgreFrameListener : public Ogre::FrameListener
{
public:
 COgreFrameListener(OIS::Keyboard *keyboard, OIS::Mouse *mouse,
  Ogre::Camera *camera, Ogre::RenderWindow *window,RECT *windowRect, BOOL *exit,BOOL* pbSizing);
 ~COgreFrameListener(void);
 bool frameStarted(const Ogre::FrameEvent& evt);

private:
 OIS::Keyboard        *m_pOisKeyboard;
 OIS::Mouse           *m_pOisMouse;
 Ogre::Camera         *m_pOgreCamera;
 Ogre::RenderWindow   *m_pOgreWindow;
 LPRECT               m_pOgreWindowRect;
 BOOL                 *m_pbExit;
 BOOL                 *m_pbSizing;
};

 

OgreFrameListener.cpp

 

#include "StdAfx.h"
#include "OgreFrameListener.h"

COgreFrameListener::COgreFrameListener(OIS::Keyboard *keyboard,OIS::Mouse *mouse,Ogre::Camera *camera,
            Ogre::RenderWindow *window,RECT *windowRect,BOOL *exit, BOOL* pbSizing):
                                       m_pOisKeyboard(keyboard),m_pOisMouse(mouse),m_pOgreCamera(camera),
            m_pbExit(exit),m_pOgreWindow(window),m_pOgreWindowRect(windowRect),
            m_pbSizing(pbSizing)
{
}

COgreFrameListener::~COgreFrameListener(void)
{
}

bool COgreFrameListener::frameStarted(const Ogre::FrameEvent& evt)
{
 // 退出
 if(*m_pbExit)
  return FALSE;

 if(*m_pbSizing)
  return TRUE;

 // 捕捉键盘鼠标
 m_pOisKeyboard->capture();
 m_pOisMouse->capture();
 OIS::MouseState ms = m_pOisMouse->getMouseState(); 
 Ogre::Angle angle(0.05);
 Ogre::Angle angle2(-0.05);

  //键盘控制
 if (m_pOisKeyboard->isKeyDown(OIS::KC_A))
 {
  m_pOgreCamera->yaw(angle);
 }
 if (m_pOisKeyboard->isKeyDown(OIS::KC_D))
 {
  m_pOgreCamera->yaw(angle2);
 }
 if (m_pOisKeyboard->isKeyDown(OIS::KC_W))
 {
  m_pOgreCamera->pitch(angle);
 }
 if (m_pOisKeyboard->isKeyDown(OIS::KC_S))
 {
  m_pOgreCamera->pitch(angle2);
 }

 POINT mousePos;
 mousePos.x = ms.X.abs;
 mousePos.y = ms.Y.abs;
 AfxGetMainWnd()->ClientToScreen(&mousePos);
 if(mousePos.x<m_pOgreWindowRect->left||mousePos.x>m_pOgreWindowRect->right
    ||mousePos.y>m_pOgreWindowRect->bottom||mousePos.y<m_pOgreWindowRect->top)
 {
  return TRUE;
 }

 //鼠标
 if (ms.buttonDown(OIS::MB_Left))
 {
  Ogre::Vector3 v3Pos = m_pOgreCamera->getPosition();
  Ogre::Vector3 v3Dir = m_pOgreCamera->getDirection();
  m_pOgreCamera->setPosition(v3Pos+v3Dir);
 }
 if (ms.buttonDown(OIS::MB_Right))
 {
  Ogre::Vector3 v3Pos = m_pOgreCamera->getPosition();
  Ogre::Vector3 v3Dir = m_pOgreCamera->getDirection();
  m_pOgreCamera->setPosition(v3Pos-v3Dir);
 }
 if (ms.Z.rel>0)
 {
  Ogre::Vector3 v3Pos = m_pOgreCamera->getPosition();
  Ogre::Vector3 v3Dir = m_pOgreCamera->getDirection();
  m_pOgreCamera->setPosition(v3Pos+v3Dir*10);
 }
 if (ms.Z.rel<0)
 {
  Ogre::Vector3 v3Pos = m_pOgreCamera->getPosition();
  Ogre::Vector3 v3Dir = m_pOgreCamera->getDirection();
  m_pOgreCamera->setPosition(v3Pos-v3Dir*10);
 }

 return TRUE;
}

 

 

OgreAppThread.h

 

#pragma once

 

// COgreAppThread

class COgreAppThread : public CWinThread, COgreApplication
{
 DECLARE_DYNCREATE(COgreAppThread)

protected:
 COgreAppThread();           // 动态创建所使用的受保护的构造函数
 virtual ~COgreAppThread();

public:
 virtual BOOL InitInstance();
 virtual int ExitInstance();

protected:
 DECLARE_MESSAGE_MAP()
public:
 virtual BOOL OnIdle(LONG lCount);
 virtual BOOL PreTranslateMessage(MSG* pMsg);
};

 

 

OgreAppThread.cpp

 

// OgreAppThread.cpp : 实现文件
//

#include "stdafx.h"
#include "OgreMFC_frame.h"
#include "OgreAppThread.h"
#include "MainFrm.h"
#include "OgreMFC_frameView.h"

#define WM_SIZE_VIEW  WM_USER+100

// COgreAppThread

IMPLEMENT_DYNCREATE(COgreAppThread, CWinThread)

COgreAppThread::COgreAppThread()
{
}

COgreAppThread::~COgreAppThread()
{
}

BOOL COgreAppThread::InitInstance()
{
 // TODO: 在此执行任意逐线程初始化
 HWND hWnd = ((CMainFrame*)AfxGetApp()->GetMainWnd())->GetActiveView()->GetSafeHwnd();
 HWND hWndMain = AfxGetMainWnd()->GetSafeHwnd();
 LPRECT pOgreWindowRect = ((COgreMFC_frameView*)((CMainFrame*)AfxGetApp()->GetMainWnd())->GetActiveView())->GetOgreWindowRectPtr();
 BOOL* pbSizing = ((CMainFrame*)AfxGetApp()->GetMainWnd())->GetSizingPtr();
 Initialize(hWnd, hWndMain, pOgreWindowRect,pbSizing);
 OnSize();
 return TRUE;
}

int COgreAppThread::ExitInstance()
{
 // TODO: 在此执行任意逐线程清理
 //Exit();
 return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(COgreAppThread, CWinThread)
END_MESSAGE_MAP()


// COgreAppThread 消息处理程序

BOOL COgreAppThread::OnIdle(LONG lCount)
{
 // TODO: 在此添加专用代码和/或调用基类
 Update();
 return __super::OnIdle(0);
}

BOOL COgreAppThread::PreTranslateMessage(MSG* pMsg)
{
 // TODO: 在此添加专用代码和/或调用基类
 if(pMsg->message == WM_SIZE_VIEW)
 {
  OnSize();

 }
 return __super::PreTranslateMessage(pMsg);
}

 

 

OgreMFC_frameView.h

 

// OgreMFC_frameView.h : COgreMFC_frameView 类的接口
//


#pragma once
#include <Ogre.h>
#include <OIS/OIS.h>
#include <CEGUI/CEGUI.h>
#include <OgreCEGUIRenderer.h>
#include "OgreFrameListener.h"
#include "OgreApplication.h"
#include "OgreMFC_frameDoc.h"

class COgreMFC_frameView : public CView
{
protected: // 仅从序列化创建
 COgreMFC_frameView();
 DECLARE_DYNCREATE(COgreMFC_frameView)

// 属性
public:
 COgreMFC_frameDoc* GetDocument() const;
    void ReflashViewWindowRect();
 LPRECT  GetOgreWindowRectPtr();
 CWinThread*                  m_winThreadOgre;

// 操作
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);

// 实现
public:
 virtual ~COgreMFC_frameView();
#ifdef _DEBUG
 virtual void AssertValid() const;
 virtual void Dump(CDumpContext& dc) const;
#endif

protected:
 BOOL                         m_bOgreInited;
    COgreApplication*            m_pOgreApp;
 RECT                         m_rectWindow;

// 生成的消息映射函数
protected:
 DECLARE_MESSAGE_MAP()
public:
 afx_msg void OnTimer(UINT_PTR nIDEvent);
 afx_msg void OnSize(UINT nType, int cx, int cy);
 afx_msg void OnDestroy();
};

#ifndef _DEBUG  // OgreMFC_frameView.cpp 中的调试版本
inline COgreMFC_frameDoc* COgreMFC_frameView::GetDocument() const
   { return reinterpret_cast<COgreMFC_frameDoc*>(m_pDocument); }
#endif

 

 

OgreMFC_frameView.cpp

 

// OgreMFC_frameView.cpp : COgreMFC_frameView 类的实现
//

#include "stdafx.h"
#include "OgreMFC_frame.h"

#include "OgreMFC_frameDoc.h"
#include "OgreMFC_frameView.h"

#include "OgreAppThread.h"

#define OGRE_DEBUG_MEMORY_MANAGER 1
#define OGRE_RENDER_TIMER 100       // 渲染TIMER
#define OGRE_FRAME_RATE 50          // 帧速 /s
#define WM_SIZE_VIEW  WM_USER+100

// COgreMFC_frameView

IMPLEMENT_DYNCREATE(COgreMFC_frameView, CView)

BEGIN_MESSAGE_MAP(COgreMFC_frameView, 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_TIMER()
 ON_WM_SIZE()
 ON_WM_DESTROY()
END_MESSAGE_MAP()

// COgreMFC_frameView 构造/析构

COgreMFC_frameView::COgreMFC_frameView()
{
 // TODO: 在此处添加构造代码
    m_bOgreInited = FALSE;
}

COgreMFC_frameView::~COgreMFC_frameView()
{
}

BOOL COgreMFC_frameView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: 在此处通过修改
 //  CREATESTRUCT cs 来修改窗口类或样式

 return CView::PreCreateWindow(cs);
}

// COgreMFC_frameView 绘制

void COgreMFC_frameView::OnDraw(CDC* /*pDC*/)
{
 COgreMFC_frameDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 if (!pDoc)
  return;
   
 // TODO: 在此处为本机数据添加绘制代码

 // 获取Ogre渲染窗口矩形
 GetClientRect(&m_rectWindow);
 ClientToScreen(&m_rectWindow);

 // 初始化Ogre
 if(!m_bOgreInited)
 {
  m_bOgreInited = TRUE;
        m_winThreadOgre = AfxBeginThread(RUNTIME_CLASS(COgreAppThread));
  CClientDC cdc(this);
  cdc.TextOut(100,100,L"请稍候正在初始化........");
 }
}


// COgreMFC_frameView 打印

BOOL COgreMFC_frameView::OnPreparePrinting(CPrintInfo* pInfo)
{
 // 默认准备
 return DoPreparePrinting(pInfo);
}

void COgreMFC_frameView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
 // TODO: 添加额外的打印前进行的初始化过程
}

void COgreMFC_frameView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
 // TODO: 添加打印后进行的清理过程
}


// COgreMFC_frameView 诊断

#ifdef _DEBUG
void COgreMFC_frameView::AssertValid() const
{
 CView::AssertValid();
}

void COgreMFC_frameView::Dump(CDumpContext& dc) const
{
 CView::Dump(dc);
}

COgreMFC_frameDoc* COgreMFC_frameView::GetDocument() const // 非调试版本是内联的
{
 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COgreMFC_frameDoc)));
 return (COgreMFC_frameDoc*)m_pDocument;
}
#endif //_DEBUG


// COgreMFC_frameView 消息处理程序

void COgreMFC_frameView::OnTimer(UINT_PTR nIDEvent)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 if(m_bOgreInited)
        m_pOgreApp->Update();

 CView::OnTimer(nIDEvent);
}

void COgreMFC_frameView::OnSize(UINT nType, int cx, int cy)
{
 CView::OnSize(nType, cx, cy);

 // TODO: 在此处添加消息处理程序代码
 if(m_bOgreInited)   
  m_winThreadOgre->PostThreadMessage(WM_SIZE_VIEW,NULL,NULL);
}

void COgreMFC_frameView::OnDestroy()
{
 CView::OnDestroy();

 // TODO: 在此处添加消息处理程序代码
 m_winThreadOgre->PostThreadMessage(WM_QUIT,NULL,NULL);
}
void COgreMFC_frameView::ReflashViewWindowRect()
{
 GetClientRect(&m_rectWindow);
 ClientToScreen(&m_rectWindow);
}

LPRECT  COgreMFC_frameView::GetOgreWindowRectPtr()
{
    return &m_rectWindow;
}

 

OgreMFC_frame.h

 

// OgreMFC_frame.h : OgreMFC_frame 应用程序的主头文件
//
#pragma once

#ifndef __AFXWIN_H__
 #error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif

#include "resource.h"       // 主符号
#include "OgreApplication.h"

// COgreMFC_frameApp:
// 有关此类的实现,请参阅 OgreMFC_frame.cpp
//

class COgreMFC_frameApp : public CWinApp
{
public:
 COgreMFC_frameApp();

// 重写
public:
 virtual BOOL InitInstance();

public:
// 实现
 afx_msg void OnAppAbout();
 DECLARE_MESSAGE_MAP()
 virtual int ExitInstance();

public:
 COgreApplication* GetOgreAppPtr();
 RECT* GetOgreWindowRectPtr();
 HWND  GetOgreWindowHwnd();
 HWND  GetMainWindowHwnd();
 CWinThread *GetOgreThreadPtr();

protected:
 COgreApplication  *m_pOgreApp;
 RECT   *m_pOgreWindowRect;
 HWND   m_hWnd;
 HWND   m_hWndMain;
 CWinThread *m_winThreadOgre;
};

extern COgreMFC_frameApp theApp;

 

 

OgreMFC_frame.cpp

 

// OgreMFC_frame.cpp : 定义应用程序的类行为。
//

#include "stdafx.h"
#include "OgreMFC_frame.h"
#include "MainFrm.h"

#include "OgreMFC_frameDoc.h"
#include "OgreMFC_frameView.h"

#define OGRE_DEBUG_MEMORY_MANAGER 1


// COgreMFC_frameApp

BEGIN_MESSAGE_MAP(COgreMFC_frameApp, CWinApp)
 ON_COMMAND(ID_APP_ABOUT, &COgreMFC_frameApp::OnAppAbout)
 // 基于文件的标准文档命令
 ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)
 ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
 // 标准打印设置命令
 ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()


// COgreMFC_frameApp 构造

COgreMFC_frameApp::COgreMFC_frameApp()
{
 // TODO: 在此处添加构造代码,
 // 将所有重要的初始化放置在 InitInstance 中
    m_winThreadOgre = NULL;
}


// 唯一的一个 COgreMFC_frameApp 对象

COgreMFC_frameApp theApp;


// COgreMFC_frameApp 初始化

BOOL COgreMFC_frameApp::InitInstance()
{
 // 如果一个运行在 Windows XP 上的应用程序清单指定要
 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
 //则需要 InitCommonControlsEx()。否则,将无法创建窗口。
 INITCOMMONCONTROLSEX InitCtrls;
 InitCtrls.dwSize = sizeof(InitCtrls);
 // 将它设置为包括所有要在应用程序中使用的
 // 公共控件类。
 InitCtrls.dwICC = ICC_WIN95_CLASSES;
 InitCommonControlsEx(&InitCtrls);

 CWinApp::InitInstance();

 // 初始化 OLE 库
 if (!AfxOleInit())
 {
  AfxMessageBox(IDP_OLE_INIT_FAILED);
  return FALSE;
 }
 AfxEnableControlContainer();
 // 标准初始化
 // 如果未使用这些功能并希望减小
 // 最终可执行文件的大小,则应移除下列
 // 不需要的特定初始化例程
 // 更改用于存储设置的注册表项
 // TODO: 应适当修改该字符串,
 // 例如修改为公司或组织名
 SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
 LoadStdProfileSettings(4);  // 加载标准 INI 文件选项(包括 MRU)
 // 注册应用程序的文档模板。文档模板
 // 将用作文档、框架窗口和视图之间的连接
 CSingleDocTemplate* pDocTemplate;
 pDocTemplate = new CSingleDocTemplate(
  IDR_MAINFRAME,
  RUNTIME_CLASS(COgreMFC_frameDoc),
  RUNTIME_CLASS(CMainFrame),       // 主 SDI 框架窗口
  RUNTIME_CLASS(COgreMFC_frameView));
 if (!pDocTemplate)
  return FALSE;
 AddDocTemplate(pDocTemplate);

 // 分析标准外壳命令、DDE、打开文件操作的命令行
 CCommandLineInfo cmdInfo;
 ParseCommandLine(cmdInfo);

 // 调度在命令行中指定的命令。如果
 // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
 if (!ProcessShellCommand(cmdInfo))
  return FALSE;

 // 唯一的一个窗口已初始化,因此显示它并对其进行更新
 m_pMainWnd->ShowWindow(SW_SHOW);
 m_pMainWnd->UpdateWindow();
 // 仅当具有后缀时才调用 DragAcceptFiles
 //  在 SDI 应用程序中,这应在 ProcessShellCommand 之后发生
 m_pMainWnd->SetWindowText(L"痞子龙3D编程 - Ogre 1.6 + MFC (多线程)");

 return TRUE;
}

 

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// 对话框数据
 enum { IDD = IDD_ABOUTBOX };

protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

// 用于运行对话框的应用程序命令
void COgreMFC_frameApp::OnAppAbout()
{
 CAboutDlg aboutDlg;
 aboutDlg.DoModal();
}


// COgreMFC_frameApp 消息处理程序


int COgreMFC_frameApp::ExitInstance()
{
 // TODO: 在此添加专用代码和/或调用基类

 return CWinApp::ExitInstance();
}

COgreApplication *COgreMFC_frameApp::GetOgreAppPtr()
{
    return m_pOgreApp;
}

RECT* COgreMFC_frameApp::GetOgreWindowRectPtr()
{
    return m_pOgreWindowRect;
}

HWND  COgreMFC_frameApp::GetOgreWindowHwnd()
{
    return m_hWnd;
}

 

MainFrm.h

 

// MainFrm.h : CMainFrame 类的接口
//


#pragma once

class CMainFrame : public CFrameWnd
{
 
protected: // 仅从序列化创建
 CMainFrame();
 DECLARE_DYNCREATE(CMainFrame)

// 属性
public:
    BOOL* GetSizingPtr();

// 操作
public:

// 重写
public:
 virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

// 实现
public:
 virtual ~CMainFrame();
#ifdef _DEBUG
 virtual void AssertValid() const;
 virtual void Dump(CDumpContext& dc) const;
#endif

protected:  // 控件条嵌入成员
 CStatusBar  m_wndStatusBar;
 CToolBar    m_wndToolBar;
    BOOL        m_bSizing;

// 生成的消息映射函数
protected:
 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 DECLARE_MESSAGE_MAP()
public:
 afx_msg void OnClose();
 afx_msg void OnWindowPosChanged(WINDOWPOS* lpwndpos);
 afx_msg void OnSizing(UINT fwSide, LPRECT pRect);
 afx_msg void OnSize(UINT nType, int cx, int cy);
};


MainFrm.cpp

 

// MainFrm.cpp : CMainFrame 类的实现
//

#include "stdafx.h"
#include "OgreMFC_frame.h"

#include "MainFrm.h"
#include "OgreMFC_frameView.h"

#define OGRE_DEBUG_MEMORY_MANAGER 1
#define WM_SIZE_VIEW  WM_USER+100


// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_CLOSE()
ON_WM_WINDOWPOSCHANGED()
ON_WM_SIZING()
ON_WM_SIZE()
END_MESSAGE_MAP()

static UINT indicators[] =
{
 ID_SEPARATOR,           // 状态行指示器
 ID_INDICATOR_CAPS,
 ID_INDICATOR_NUM,
 ID_INDICATOR_SCRL,
};


// CMainFrame 构造/析构

CMainFrame::CMainFrame()
{
 // TODO: 在此添加成员初始化代码
 m_bSizing = FALSE;
}

CMainFrame::~CMainFrame()
{
}


int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  return -1;
 
 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
  | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
 {
  TRACE0("未能创建工具栏/n");
  return -1;      // 未能创建
 }

 if (!m_wndStatusBar.Create(this) ||
  !m_wndStatusBar.SetIndicators(indicators,
    sizeof(indicators)/sizeof(UINT)))
 {
  TRACE0("未能创建状态栏/n");
  return -1;      // 未能创建
 }

 // TODO: 如果不需要可停靠工具栏,则删除这三行
 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
 EnableDocking(CBRS_ALIGN_ANY);
 DockControlBar(&m_wndToolBar);

 return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 if( !CFrameWnd::PreCreateWindow(cs) )
  return FALSE;
 // TODO: 在此处通过修改
 //  CREATESTRUCT cs 来修改窗口类或样式

 return TRUE;
}


// CMainFrame 诊断

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
 CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
 CFrameWnd::Dump(dc);
}

#endif //_DEBUG


// CMainFrame 消息处理程序

void CMainFrame::OnClose()
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值

 CFrameWnd::OnClose();
}

void CMainFrame::OnWindowPosChanged(WINDOWPOS* lpwndpos)
{
 CFrameWnd::OnWindowPosChanged(lpwndpos);

 // TODO: 在此处添加消息处理程序代码
 COgreMFC_frameView *pView = (COgreMFC_frameView*) GetActiveView();
 if( NULL != pView )
  pView->ReflashViewWindowRect();
}

void CMainFrame::OnSizing(UINT fwSide, LPRECT pRect)
{
 CFrameWnd::OnSizing(fwSide, pRect);

 // TODO: 在此处添加消息处理程序代码
    m_bSizing = TRUE;
 if(AfxGetThread()!=NULL)   
  ((COgreMFC_frameView*)GetActiveView())->m_winThreadOgre->PostThreadMessage(WM_SIZE_VIEW,NULL,NULL);
}

void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
 CFrameWnd::OnSize(nType, cx, cy);

 // TODO: 在此处添加消息处理程序代码
 m_bSizing = FALSE;
}

BOOL* CMainFrame::GetSizingPtr()
{
 return  &m_bSizing;
}