现在的位置: 首页 > 综合 > 正文

将Ogre写入MFC框架中

2014年02月02日 ⁄ 综合 ⁄ 共 3013字 ⁄ 字号 评论关闭

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类中增加成员 

    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. 渲染是通过APP中的OnIdle函数里面调用Root的renderOneFrame()函数实现的

    有个缺点, 就是帧率变化幅度很大, 如果愿意用定时器也不错, 只是感觉如果每帧渲染的时间不够容易出现问题

    我打算之后的程序两者交替使用

抱歉!评论已关闭.