在MFC 窗口中运行 cocos2d-x 3.2 (二) 让其在MFC picture控件中运行

在MFC 窗口中运行 cocos2d-x 3.2 (二) 让其在MFC picture控件中运行,第1张

概述转载地址:http://blog.csdn.net/greatchina01/article/details/39580767 上一篇我们配置了运行环境,但是并不完美,MFC窗口 和 cosos2d 窗口是分开运行的。 如果用来做工具 看起来不太好看,这一篇我们将修改cocos2d 代码,让其运行在MFC控件上 参考:http://blog.csdn.net/akof1314/article/de

转载地址:http://blog.csdn.net/greatchina01/article/details/39580767


上一篇我们配置了运行环境,但是并不完美,MFC窗口 和 cosos2d 窗口是分开运行的。 如果用来做工具 看起来不太好看,这一篇我们将修改cocos2d 代码,让其运行在MFC控件上

参考:http://blog.csdn.net/akof1314/article/details/8133800


要把cocos2d 窗口运行在 MFC 控件上, 我们就要找到这个窗口的句柄,下面我们来一步步找,看看怎样得到这个窗口句柄


1.首先我们来分析cocos2d的运行机制

打开cocos2d::Application::getInstance()->run(); run()函数的源码:

[cpp] view plain copy intApplication::run() { PVRFrameEnableControlWindow(false); //Mainmessageloop: LARGE_INTEGERnFreq; LARGE_INTEGERnLast; LARGE_INTEGERnNow; queryPerformanceFrequency(&nFreq); queryPerformanceCounter(&nLast); //这里调用了AppDelegate中的<span>applicationDIDFinishLaunching() //Initializeinstanceandcocos2d. if(!applicationDIDFinishLaunching()) return0; } //那么游戏窗口一定是在这之前创建的</span> autodirector=Director::getInstance(); autoglvIEw=director->getopenGLVIEw(); //RetainglvIEwtoavoIDglvIEwbeingreleasedinthewhileloop glvIEw->retain(); //下面是游戏主循环</span> while(!glvIEw->windowshouldClose()) { queryPerformanceCounter(&nNow); if(nNow.QuadPart-nLast.QuadPart>_animationInterval.QuadPart) nLast.QuadPart=nNow.QuadPart; director->mainLoop(); glvIEw->pollEvents(); } else Sleep(0); //Directorshouldstilldoacleanupifthewindowwasclosedmanually. if(glvIEw->isOpenglready()) director->end(); director->mainLoop(); director=nullptr; glvIEw->release(); returntrue; } 2. 于是我们查看AppDelegate::applicationDIDFinishLaunching() 代码:

copy boolAppDelegate::applicationDIDFinishLaunching(){ //initializedirector autodirector=Director::getInstance(); autoglvIEw=director->getopenGLVIEw(); if(!glvIEw){ copy //第一次运行肯定会进入这里,这个create函数创建了GLVIEw对象 glvIEw=GLVIEw::create("MyGame"); director->setopenGLVIEw(glvIEw); //turnondisplayFPS director->setdisplayStats(true); //setFPS.thedefaultvalueis1.0/60ifyoudon'tcallthis director->setAnimationInterval(1.0/60); //createascene.it'sanautoreleaSEObject autoscene=HelloWorld::createScene(); //run director->runWithScene(scene); true; 3. 我们看看GLVIEw::create函数代码

GLVIEw*GLVIEw::create(conststd::string&vIEwname) autoret=newGLVIEw; //调用了initWithRect()</span> if(ret&&ret->initWithRect(vIEwname,Rect(0,960,640),1)){ ret->autorelease(); returnret; returnnullptr; }


4.initWithRect 代码

[HTML] boolGLVIEw::initWithRect(conststd::string&vIEwname,Rectrect,floatframeZoomFactor) setVIEwname(vIEwname); _frameZoomFactor=frameZoomFactor; glfwWindowHint(GLFW_RESIZABLE,GL_FALSE); //找到了,glfwCreateWindow这个函数就是创建窗口的(我只知道glfw是个opengl的库,想了解的可以去搜一下),下面我们来取窗口句柄 _mainWindow=glfwCreateWindow(rect.size.wIDth*_frameZoomFactor, rect.size.height*_frameZoomFactor, _vIEwname.c_str(), _monitor,108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> nullptr); glfwMakeContextCurrent(_mainWindow); glfwSetMousebuttonCallback(_mainWindow,GLFWEventHandler::onGLFWMouseCallBack); glfwSetCursorPosCallback(_mainWindow,GLFWEventHandler::onGLFWMouseMoveCallBack); glfwSetScrollCallback(_mainWindow,GLFWEventHandler::onGLFWMouseScrollCallback); glfwSetCharCallback(_mainWindow,GLFWEventHandler::onGLFWCharCallback); glfwSetKeyCallback(_mainWindow,GLFWEventHandler::onGLFWKeyCallback); glfwSetwindowPosCallback(_mainWindow,GLFWEventHandler::onGLFWWindowPosCallback); glfwSetFramebufferSizeCallback(_mainWindow,GLFWEventHandler::onGLFWframebuffersize); glfwSetwindowsizeCallback(_mainWindow,GLFWEventHandler::onGLFWwindowsizefunCallback); setFrameSize(rect.size.wIDth,rect.size.height); //checkOpenGLversionatfirst constglubyte*glVersion=glGetString(GL_VERSION); if(utils::atof((constchar*)glVersion)<1.5) charstrComplain[256]={0}; sprintf(strComplain,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> "OpenGL1.5orhigherisrequired(yourversionis%s).PleaseupgradethedriverofyourvIDeocard.",108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> glVersion); MessageBox(strComplain,"OpenGLversiontooold"); returnfalse; initGlew(); //Enablepointsizebydefault. glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); returntrue; } 5. 有个API 函数glfwGetWin32Window() 可以取得窗口句柄。(由于不了解glfw 网上搜了半天才找到这个。。。)

参考: http://www.glfw.org/docs/3.0/group__native.HTML

6.下面开始修改代码

在CCGLVIEw.cpp 前面添加(头文件一定要在宏定义后面

#defineGLFW_EXPOSE_NATIVE_WIN32 #defineGLFW_EXPOSE_NATIVE_WGL #include"glfw3native.h"
给GLVIEw类添加成员:

HWNDgetHwnd(); voIDcloseWindow(); HWNDm_hwnd;
HWNDGLVIEw::getHwnd() returnm_hwnd; voIDGLVIEw::closeWindow() glfwSetwindowshouldClose(_mainWindow,1); }

修改函数bool GLVIEw::initWithRect(const std::string& vIEwname,Rect rect,float frameZoomFactor)

在函数最后添加

m_hwnd=glfwGetWin32Window(_mainWindow);

7. 打开Application 类添加一个 int cocosrun() public成员函数

intApplication::cocosrun() //Initializeinstanceandcocos2d. if(!applicationDIDFinishLaunching()) return0; //RetainglvIEwtoavoIDglvIEwbeingreleasedinthewhileloop glvIEw->retain(); ShowWindow(glvIEw->getHwnd(),SW_SHOW); while(!glvIEw->windowshouldClose()) queryPerformanceCounter(&nNow); if(nNow.QuadPart-nLast.QuadPart>_animationInterval.QuadPart) nLast.QuadPart=nNow.QuadPart; glvIEw->pollEvents(); else Sleep(0); //Directorshouldstilldoacleanupifthewindowwasclosedmanually. if(glvIEw->isOpenglready()) director->end(); director=nullptr; glvIEw->release(); true; }
8. 打开Application 类添加一个 voID closeWindow()public成员函数

voIDApplication::closeWindow() autodirector=cocos2d::Director::getInstance(); glvIEw->closeWindow(); 9. 给类AppDelegate添加 成员

HWNDm_hwnd; RECTm_parentRect; voIDAppDelegate::setParent(HWNDhwnd,RECTrect) m_hwnd=hwnd; m_parentRect.left=rect.left; m_parentRect.top=rect.top; m_parentRect.right=rect.right; m_parentRect.bottom=rect.bottom; 10 修改AppDelegate::applicationDIDFinishLaunching() 函数

if(!glvIEw){ ::SetParent(glvIEw->getHwnd(),m_hwnd); SetwindowLong(glvIEw->getHwnd(),GWL_STYLE,getwindowlong(glvIEw->getHwnd(),GWL_STYLE)&~WS_CAPTION); ::SetwindowPos(glvIEw->getHwnd(),HWND_top,m_parentRect.left,m_parentRect.top,m_parentRect.right-m_parentRect.left,m_parentRect.bottom-m_parentRect.top,SWP_NOcopYBITS|SWP_HIDEWINDOW); 11. 给对话框添加一个 Picture 控件(注意更改默认 ID),并为其添加Control 类型成员变量 m_cocosWin , 修改上篇中button的消息响应函数

voIDCCocosEditorDlg::OnBnClickedbutton1() AppDelegateapp; RECTrc; m_cocos2DWin.GetClIEntRect(&rc); app.setParent(m_cocos2DWin.m_hWnd,rc); cocos2d::Application::getInstance()->cocosrun(); 12. 关闭cocos2d窗口, 在类向导中 给MFC对话框窗口添加 WM_CLOSE消息响应函数:

voIDCCocosEditorDlg::OnClose() cocos2d::Application::getInstance()->closeWindow(); CDialogEx::OnClose(); }
13.编译运行程序:


14 .运行时会发现 cocos2d窗口闪了下,这个原因是cocos2d先创建,然后移到了Picture控件上,那我们让Cocos2d的窗口创建时 先不可见:

boolGLVIEw::initWithRect(conststd::string&vIEwname,floatframeZoomFactor) _frameZoomFactor=frameZoomFactor; glfwWindowHint(GLFW_VISIBLE,GL_FALSE); _mainWindow=glfwCreateWindow(rect.size.wIDth*_frameZoomFactor,0); background-color:inherit">//checkOpenGLversionatfirst constglubyte*glVersion=glGetString(GL_VERSION); if(utils::atof((constchar*)glVersion)<1.5) charstrComplain[256]={0}; "OpenGL1.5orhigherisrequired(yourversionis%s).PleaseupgradethedriverofyourvIDeocard.", "OpenGLversiontooold"); false; //Enablepointsizebydefault. m_hwnd=glfwGetWin32Window(_mainWindow);</span> 这样就解决闪一下的问题

现在MFC 中运行cocos2dx- 3.2 配置+环境 已经完成,可以进行一些工具的开发。(ps:哪位如果开发出好用的工具,不要忘记给大家分享呀)。但是还不完美,完美的做法是用MFC 完全接管cocos2d窗口的创建,和消息处理。3.x版本的窗口创建不再是直接调用Win32 API ,我暂时没找到解决办法,如果解决这个问题的,请留言哈.

转载请注明出处。

总结

以上是内存溢出为你收集整理的在MFC 窗口中运行 cocos2d-x 3.2 (二) 让其在MFC picture控件中运行全部内容,希望文章能够帮你解决在MFC 窗口中运行 cocos2d-x 3.2 (二) 让其在MFC picture控件中运行所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1022285.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存