本节主要讲一下如何在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
, // preferred color depth
0, 0, 0, 0, 0, 0, // color bits (ignored)
, // 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 != && cy != )
{ if (!m_bCreated)
{
m_app.CreateWnd(m_hWnd);
SetTimer(, , NULL);
m_bCreated = true;
} m_app.Resize(cx, cy);
}
}
LRESULT CMFCApplicationView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: 在此添加专用代码和/或调用基类
if ( == m_app.WindowProc(message, wParam, lParam))
return ;
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

cocos2dx - 在MFC中使用cocos2dx的更多相关文章

  1. 强行在MFC窗体中渲染Cocos2d-x 3.6

    [前言] 把Cocos2dx渲染到另一个应用程序框架中的方法,在2.x时代有很多大神已经实现了,而3.x的做法网上几乎找不着.这两天抽空强行折腾了一下,不敢独享,贴出来供大家参考. [已知存在的问题] ...

  2. 使用“Cocos引擎”创建的cpp工程如何在VS中调试Cocos2d-x源码

    前段时间Cocos2d-x更新了一个Cocos引擎,这是一个集合源码,IDE,Studio这一家老小的整合包,我们可以使用这个Cocos引擎来创建我们的项目. 在Cocos2d-x被整合到Cocos引 ...

  3. cocos2dx 3.7中 AppDelegate.h的class TestController;这种写法的具体意思不太明白,只能猜是类似于外部定义的东西。

    cocos2dx 3.7中 AppDelegate.h的class TestController;这种写法的具体意思不太明白,只能猜是类似于外部定义的东西.

  4. 解决cocos2dx在Xcode中运行时报:convert: iCCP: known incorrect sRGB profile 的问题

    解决cocos2dx在Xcode中运行时报:convert: iCCP: known incorrect sRGB profile 的问题 本文的实践来源是参照了两个帖子完成的: http://dis ...

  5. cocos2d-x 3.0rc2中读取sqlite文件

    cocos2d-x 3.0rc2中读取sqlite文件的方式,在Android中直接读取软件内的会失败.须要复制到可写的路径下 sqlite3* dbFile = NULL; std::string ...

  6. ios怎样实现快速将显卡中数据读出压缩成视频在cocos2dx扩展开发中

    如果解决ios怎样实现快速将显卡中数据读出压缩成视频在cocos2dx扩展开发中 手机平台性能是个关键问题. 压缩视频分成3个步骤: 读取显卡数据, 使用编码器压缩,保存文件. 使用libav 压缩的 ...

  7. Cocos2d-x游戏开发中的消息机制:CCNotificationCenter的使用

    在HTML5游戏开发中,js可以使用Event对象的addEventListener(添加事件监听).dispatchEvent(触发事件)实现监听机制,如果在coocos2d-x中,去实现这种机制该 ...

  8. 深入分析Cocos2d-x 2.0中的“纹理”

    对CCImage的绘制是通过CCTexture2D来实现的(OPENGL es)通过纹理绘制到某个面. (本文中所提到的方法在cocos2d2.0中部分有调整,请应用时候具体察看源码)1. 首先来了解 ...

  9. lua 中处理cocos2dx 的button 事件

    lua 中处理cocos2dx 的button 事件 2014-05-08 09:44:32|  分类: lua |举报 |字号 订阅   1.引入这个类:require "GuiConst ...

随机推荐

  1. MongoDB学习之路(一)

    NoSQL简介 NoSQL(Not Only SQL),意为"不仅仅是SQL" 关系型数据库遵循ACID规则 1. A(Atomicity)原子性 指的是事务里的所有操作要么全部做 ...

  2. JAVA基础第一组(前5道题)

    1.[程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一 对兔子,假如兔子都不死,问每个月的兔子总数为多少?        1.程序分析: 兔 ...

  3. spring的配置文件和加载

    ①:创建applicationContext.xml配置文件放在src下 //applicationContext.xml代码 <?xml version="1.0" enc ...

  4. 201521123095 《Java程序设计》第3周学习总结

    ,1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传. 2. 书面 ...

  5. Java补码表和位移运算符

    在java中数据都是以二进制的形式保存的. 但是我们看到的数据怎么是10进制的? 因为java展示之前会自动调用toString()方法 这里以4位2进制为例,4位2进制只能表示16个数,即0-15. ...

  6. #黑客社会工程学攻防演练#[Chapter 1]

    1.1 什么是社会工程学 社会工程学(Social Engineering)是关于建立理论通过自然的.社会的和制度上的途径并特别强调根据现实的双向计划和设计经验来一步一步地解决各种社会问题.社会工程学 ...

  7. 201521123080《Java程序设计》第14周学习总结

    本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 书面作业 MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) ...

  8. 万物皆对象的JavaScript

    写在前面: 经过前段时间对于H5语言的学习,开始慢慢适应现在的生活节奏和代码语言.从一开始的毫无头绪到现在可以大概地写出部分的网站静态页面,用了两个周的时间.作为一个之前从未接触过计算机语言的初学者来 ...

  9. 个人-GIT使用方法

    团队开发中,遵循一个合理.清晰的Git使用流程,是非常重要的. 1.Git库中由三部分组成        Git 仓库就是那个.git 目录,其中存放的是我们所提交的文档索引内容,Git 可基于文档索 ...

  10. 在腾讯云上搭建WordPress博客

    笔者一直很羡慕那些搭建了个人博客的大牛,在最近工作之余也尝试着搭建了自己的博客,历时1周,这篇文章就将踩过的坑记录下来,先看下成果,链接在此 1- 购买腾讯云主机 腾讯云官网,我选了79元/月的最便宜 ...