上一篇我们配置了运行环境,但是并不完美,MFC窗口 和 cosos2d 窗口是分开运行的。 如果用来做工具 看起来不太好看,这一篇我们将修改cocos2d 代码,让其运行在MFC控件上
参考:http://blog.csdn.net/akof1314/article/details/8133800
要把cocos2d 窗口运行在 MFC 控件上, 我们就要找到这个窗口的句柄,下面我们来一步步找,看看怎样得到这个窗口句柄
1.首先我们来分析cocos2d的运行机制
打开cocos2d::Application::getInstance()->run(); run()函数的源码:
- intApplication::run()
- {
- PVRFrameEnableControlWindow(false);
-
-
- LARGE_INTEGERnFreq;
- LARGE_INTEGERnLast;
- LARGE_INTEGERnNow;
-
- QueryPerformanceFrequency(&nFreq);
- QueryPerformanceCounter(&nLast);
-
- //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() 代码:
boolAppDelegate::applicationDidFinishLaunching(){
- //initializedirector
- autodirector=Director::getInstance();
- autoglview=director->getOpenGLView();
- if(!glview){
//第一次运行肯定会进入这里,这个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;
- if(ret&&ret->initWithRect(viewName,Rect(0,960,640),1)){
- ret->autorelease();
- returnret;
- returnnullptr;
- }
4.initWithRect 代码
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)"> "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>
- 这样就解决闪一下的问题
转载请注明出处。
Test下载地址:点击打开链接
转子:
http://blog.csdn.net/greatchina01/article/details/39580767 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|