cocos2dx - 在MFC中使用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)cocos\editor-support;$(EngineRoot)cocos;$(EngineRoot)cocos\platform;$(EngineRoot)cocos\platform\desktop;$(EngineRoot)external\glfw3\include\win32;$(EngineRoot)external\win32-specific\gles\include\OGLES;$(EngineRoot)external\freetype2\include\win32\freetype2;$(EngineRoot)external\freetype2\include\win32\;$(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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM