将Ogre写入MFC框架中

将Ogre写入MFC框架中

1. 新建MFC单文档程序
2. 修改项目选项配置
    常规 --> 输出目录 --> ..\bin\$(ConfigurationName)
    常规 --> 中间目录 --> ..\obj\$(ConfigurationName)
    常规 --> MFC的使用 --> 在静态库中使用MFC
    C/C++ --> 预处理器 --> 预处理器定义 --> 增加 _AFXDLL
    C/C++ --> 代码生成 --> 运行时库 --> 多线程DLL(/MD) 
    链接器 --> 附加依赖项 mfc80d.lib OgreMain_d.lib OIS_d.lib
3. 复制ExampleApplication.h 和 ExampleFrameListener.h, 替换类名
4. 替换
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    为
    #ifdef _DEBUG
    #define OGRE_DEBUG_MEMORY_MANAGER 1
    #endif
5. 在APP类中增加成员 , 在APP中进行初始化和删除, 其他地方容易出现问题
    MyOgreDemo* theOgreApp;
    在函数 InitInstance() 中初始化
        theOgreApp = new MyOgreDemo();
    在函数 ExitInstance() 中删除
        if(theOgreApp)
            delete theOgreApp;    
6. OgreDemo中增加几个接口函数, 初始化几个变量
    void setValue(HWND viewHwnd, HWND mainHwnd, int width, int height)
    {
        mViewHwnd = viewHwnd;        // View的HWND
        mMainHwnd = mainHwnd;        // 主框架的HWND, 用于鼠标事件
        mWidth = width;                // 要渲染的大小
        mHeight = height;
    }
    Root* getRoot()
    {
        return mRoot;
    }
7. 增加函数
        setupRenderSystem();
        增加的渲染系统
        createRenderWindow(mHwnd, mWidth, mHeight);
        创建了渲染窗口
        
    virtual void setupRenderSystem()
    {
        Ogre::RenderSystemList::iterator pRend = mRoot->getAvailableRenderers()->begin();
        while(pRend != mRoot->getAvailableRenderers()->end())
        {
            Ogre::String rName = (*pRend)->getName();
            if (rName == "OpenGL Rendering Subsystem")
                break;
            pRend++;
        }
        Ogre::RenderSystem *rsys = *pRend;
        // 配置框中的选项需要手动设置。
        rsys->setConfigOption("Colour Depth", "32" );
        rsys->setConfigOption( "Full Screen", "No" );
        rsys->setConfigOption( "VSync", "No" );
        rsys->setConfigOption( "Video Mode", "800 x 600" );
        rsys->setConfigOption( "Display Frequency", "60" );
        // 起用
        mRoot->setRenderSystem( rsys ); 
    }

    virtual void createRenderWindow(HWND hWnd, int width, int height)
    {
        // root初始化的时候,我们可以传入一个false值来告知Root不用给我们自动创建渲染窗口
        // 这样我们可以用外部窗口来作为MFC窗口

        mRoot->initialise(false);

        NameValuePairList miscParams; // 参数列表, 作为createRenderWindow函数的最后一个参数
        miscParams["externalWindowHandle"] = StringConverter::toString((long)hWnd);
        mWindow = mRoot->createRenderWindow("OgreRenderWindow", width, height, false, &miscParams);
    }        
8. 重写了监听器的输入系统
        // 获得输入系统
        size_t windowHnd = 0;
        std::ostringstream windowHndStr;
        OIS::ParamList pl;
        windowHnd = (size_t )mMainHwnd; // 这里这个窗口句柄就是我们传入的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);

9. 在View的绘制函数中增加以下代码
    if(m_isFirst)
    {
        m_isFirst = false;
        CRect rect;
        GetClientRect(&rect);
        theApp.theOgreApp->setValue(m_hWnd, AfxGetApp()->GetMainWnd()->GetSafeHwnd(), rect.Width(), rect.Height());
        theApp.theOgreApp->go();
    }

10. 渲染是通过APP中的OnIdle函数里面调用Root的renderOneFrame()函数实现的
    有个缺点, 就是帧率变化幅度很大, 如果愿意用定时器也不错, 只是感觉如果每帧渲染的时间不够容易出现问题
    我打算之后的程序两者交替使用

http://www.cppblog.com/summericeyl/archive/2009/12/23/103815.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值