• cocos2dx


     本节主要讲一下如何在MFC窗口中使用cocos2dx

      在做比较复杂的游戏,有时需要通过一些工具来编辑生成关卡或者特效,技能等的配置文件。为了方便配置,需要可以通过修改参数直观得到显示的效果。这就需要将引擎加载到工具中进行效果显示,这里我们将cocos2dx应用到MFC,得到最终效果如下:

    一、通过HWND创建cocos2dx窗口View

      通过参考 GLViewImpl 及 GLView 创建MFC中可以使用的 CMyEGLView 。在GLView中我们可以看到如下所示,Win32中实际使用的窗口指针就是HWND

        

    同时,继承GLView时有4个必须重载实现的函数如下:

      

    因此,我们自己实现的 CMyEGLView 需要 接口如下:

    class /*CC_DLL*/ CMyEGLView : public cocos2d::GLView
    {
    public:
        static CMyEGLView* createWithRect(const std::string& viewName, Rect size, HWND  handle, float frameZoomFactor = 1.0f);
    
        bool initWithRect(const std::string& viewName, Rect rect, HWND  handle, float frameZoomFactor);/* override functions */
        virtual bool isOpenGLReady() override;
        virtual void end() override;
        virtual void swapBuffers() override;
        virtual void setIMEKeyboardState(bool bOpen) override;
    
        virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
    
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
        HWND getWin32Window() { return m_hWnd; }
    #endif /* (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) */
    
    protected:
    
        CMyEGLView();
        virtual ~CMyEGLView();
    
        bool initGlew();
    
        float _frameZoomFactor;
        HDC  m_hDC;
        HGLRC m_hRC;
        HWND m_hWnd;
    
        bool _captured;
    };

    由上述代码可以看到,这里多出了一个WindowProc接口,这是用来将MFC窗口的指令传入cocos2dx中并对应转成相应的消息。主要通过参考GLViewImpl 中的回调实现,详细可以参考文章结尾的源码。

      同时在initWithRect中通过窗口指针 m_hWnd 取得窗口 m_hDC 并通过SetupPixelFormat中设置如下代码实现窗口对Opengl的支持。

    static void SetupPixelFormat(HDC hDC)
    {
        int pixelFormat;
    
        PIXELFORMATDESCRIPTOR pfd =
        {
            sizeof(PIXELFORMATDESCRIPTOR),  // size
            1,                          // version
            PFD_SUPPORT_OPENGL |        // OpenGL window
            PFD_DRAW_TO_WINDOW |        // render to window
            PFD_DOUBLEBUFFER,           // support double-buffering
            PFD_TYPE_RGBA,              // color type
            32,                         // preferred color depth
            0, 0, 0, 0, 0, 0,           // color bits (ignored)
            0,                          // no alpha buffer
            0,                          // alpha bits (ignored)
            0,                          // no accumulation buffer
            0, 0, 0, 0,                 // accum bits (ignored)
            24,                         // depth buffer
            8,                          // no stencil buffer
            0,                          // no auxiliary buffers
            PFD_MAIN_PLANE,             // main layer
            0,                          // reserved
            0, 0, 0,                    // no layer, visible, damage masks
        };
    
        pixelFormat = ChoosePixelFormat(hDC, &pfd);
        SetPixelFormat(hDC, pixelFormat, &pfd);
    }

    其余初始化opengl es等同样直接参考GLViewImpl 中实现。

    二、在AppDelegate中创建CMyEGLView 

      参考Application::run() 实现并将其拆成3部分在AppDelegate中实现,添加如下接口:

        
       // 传入窗口指针并创建
        virtual void CreateWnd(HWND hwnd);
    
        // 刷新显示
        virtual void Run2();
        
        // 窗口大小变化
        void Resize(int width, int height);
        
        // MFC 消息
        LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);

    1、CreateWnd用于传入MFC窗口指针,同时调用applicationDidFinishLaunching来实现View的创建等;

    2、Run2用于原来run中的while循环部分,即执行 director->mainLoop();

    3、在析构函数中添加对view释放等操作。

    详细可以参考文章结尾的源码。

    三、在MFCAPPView中使用AppDelegate

    1、首先在cocos2dx项目中添加一个MFC项目,如下图所示:  

      

    2、添加MFC项目对cocos2dx的项目引用

      右键属性->通用属性->引用->添加新引用->libcocos2d

    3、在视图->属性管理器中添加现有的cocos2dx属性表,如下:

      右键添加现有属性表,在~/cocos2d/cocos/2d 目录找到对应的属性表进行添加,注意先后顺序。

      

      然后在项目的属性页->C/C++->常规->附加包含目录中添加如下头文件引用目录:

    $(EngineRoot)cocoseditor-support;$(EngineRoot)cocos;$(EngineRoot)cocosplatform;$(EngineRoot)cocosplatformdesktop;$(EngineRoot)externalglfw3includewin32;$(EngineRoot)externalwin32-specificglesincludeOGLES;$(EngineRoot)externalfreetype2includewin32freetype2;$(EngineRoot)externalfreetype2includewin32;$(EngineRoot)external

    4、然后对应的在MFCApplicationView.h中添加如下:

    // 操作
    public:
        afx_msg void OnTimer(UINT_PTR nIDEvent);
        virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
        afx_msg void OnSize(UINT nType, int cx, int cy);
    protected:
        AppDelegate m_app;
        bool        m_bCreated;

       在MFCApplicationView.cpp中添加对应的消息映射

    BEGIN_MESSAGE_MAP(CMFCApplicationView, CView)
        // 标准打印命令
        ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CMFCApplicationView::OnFilePrintPreview)
        ON_WM_CONTEXTMENU()
        ON_WM_RBUTTONUP()
    
    
        ON_WM_TIMER()
        ON_WM_SIZE()
    END_MESSAGE_MAP()

      同时实现.h中的三个函数,如下:

    void CMFCApplicationView::OnTimer(UINT_PTR nIDEvent)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        if (m_bCreated)
        {
            m_app.Run2();
        }
    }
    void CMFCApplicationView::OnSize(UINT nType, int cx, int cy)
    {
        CView::OnSize(nType, cx, cy);
        // TODO: 在此处添加消息处理程序代码
    
        if (cx != 0 && cy != 0)
        {
    
            if (!m_bCreated)
            {
                m_app.CreateWnd(m_hWnd);
                SetTimer(1, 16, NULL);
                m_bCreated = true;
            }
    
            m_app.Resize(cx, cy);
        }
    }
    LRESULT CMFCApplicationView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    {
        // TODO: 在此添加专用代码和/或调用基类
        if (1 == m_app.WindowProc(message, wParam, lParam))
                return 1;
        return CView::WindowProc(message, wParam, lParam);
    }

    到这里,即可以在MFC中正常使用cocos2dx了,同时还可以正常响应点击等消息。

    5、编译后发现MFC中定义OS_WINDOWS冲突,在stdafx.h添加如下:

    //去除MFC中与cocos2dx冲突的默认定义
    #ifdef OS_WINDOWS
    #undef OS_WINDOWS
    #endif

    四、其他

      然而同这里 http://www.cnblogs.com/GuyaWeiren/p/4600937.html 通过glfw创建一个新的窗口一样,我这里测试最新cocos2dx-3.9版本同样存在内存泄漏。经测试,直接用cocos2dx源码也一样,只要在MFC中用了AppDelegate就存在泄漏。暂无解决办法,希望有同学知道的可以知会一下~~

    完整代码地址:https://github.com/mydishes/cocos2dx-Ex/tree/master/MFCView

  • 相关阅读:
    MFC菜单、工具栏和状态栏
    MFC控件
    MFC对话框
    MFC消息映射机制
    性能优化可使用的工具
    常见的内存问题分析思路
    k8s之Probe
    docker swarm
    keepalived配置虚拟ip(vip)实现双机热备以及自动切换主备
    linux安装openjdk1.8
  • 原文地址:https://www.cnblogs.com/stratrail/p/5102667.html
Copyright © 2020-2023  润新知