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

前端之家收集整理的这篇文章主要介绍了在MFC 窗口中运行 cocos2d-x 3.2 (二) 让其在MFC picture控件中运行前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

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


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


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

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

  1. intApplication::run()
  2. {
  3. PVRFrameEnableControlWindow(false);
  4. //Mainmessageloop:
  5. LARGE_INTEGERnFreq;
  6. LARGE_INTEGERnLast;
  7. LARGE_INTEGERnNow;
  8. QueryPerformanceFrequency(&nFreq);
  9. QueryPerformanceCounter(&nLast);
  10. //这里调用了AppDelegate中的<spanstyle="font-family:Arial,sans-serif;">applicationDidFinishLaunching()
  11. //Initializeinstanceandcocos2d.
  12. if(!applicationDidFinishLaunching())
  13. return0;
  14. }
  15. //那么游戏窗口一定是在这之前创建的</span>
  16. autodirector=Director::getInstance();
  17. autoglview=director->getOpenGLView();
  18. //Retainglviewtoavoidglviewbeingreleasedinthewhileloop
  19. glview->retain();
  20. //下面是游戏主循环</span>
  21. while(!glview->windowShouldClose())
  22. {
  23. QueryPerformanceCounter(&nNow);
  24. if(nNow.QuadPart-nLast.QuadPart>_animationInterval.QuadPart)
  25. nLast.QuadPart=nNow.QuadPart;
  26. director->mainLoop();
  27. glview->pollEvents();
  28. }
  29. else
  30. Sleep(0);
  31. //Directorshouldstilldoacleanupifthewindowwasclosedmanually.
  32. if(glview->isOpenGLReady())
  33. director->end();
  34. director->mainLoop();
  35. director=nullptr;
  36. glview->release();
  37. returntrue;
  38. }
2. 于是我们查看AppDelegate::applicationDidFinishLaunching() 代码

    boolAppDelegate::applicationDidFinishLaunching(){
  1. //initializedirector
  2. autodirector=Director::getInstance();
  3. autoglview=director->getOpenGLView();
  4. if(!glview){
    //第一次运行肯定会进入这里,这个create函数创建了GLView对象
  1. glview=GLView::create("MyGame");
  2. director->setOpenGLView(glview);
  3. //turnondisplayFPS
  4. director->setDisplayStats(true);
  5. //setFPS.thedefaultvalueis1.0/60ifyoudon'tcallthis
  6. director->setAnimationInterval(1.0/60);
  7. //createascene.it'sanautoreleaSEObject
  8. autoscene=HelloWorld::createScene();
  9. //run
  10. director->runWithScene(scene);
  11. true;
3. 我们看看GLView::create函数代码

    GLView*GLView::create(conststd::string&viewName)
  1. autoret=newGLView;
    //调用了initWithRect()</span>
  1. if(ret&&ret->initWithRect(viewName,Rect(0,960,640),1)){
  2. ret->autorelease();
  3. returnret;
  4. returnnullptr;
  5. }


4.initWithRect 代码

[html]
    boolGLView::initWithRect(conststd::string&viewName,Rectrect,floatframeZoomFactor)
  1. setViewName(viewName);
  2. _frameZoomFactor=frameZoomFactor;
  3. glfwWindowHint(GLFW_RESIZABLE,GL_FALSE);
    //找到了,glfwCreateWindow这个函数就是创建窗口的(我只知道glfw是个opengl的库,想了解的可以去搜一下),下面我们来取窗口句柄
  1. _mainWindow=glfwCreateWindow(rect.size.width*_frameZoomFactor,
  2. rect.size.height*_frameZoomFactor,
  3. _viewName.c_str(),
  4. _monitor,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> nullptr);
  5. glfwMakeContextCurrent(_mainWindow);
  6. glfwSetMouseButtonCallback(_mainWindow,GLFWEventHandler::onGLFWMouseCallBack);
  7. glfwSetCursorPosCallback(_mainWindow,GLFWEventHandler::onGLFWMouseMoveCallBack);
  8. glfwSetScrollCallback(_mainWindow,GLFWEventHandler::onGLFWMouseScrollCallback);
  9. glfwSetCharCallback(_mainWindow,GLFWEventHandler::onGLFWCharCallback);
  10. glfwSetKeyCallback(_mainWindow,GLFWEventHandler::onGLFWKeyCallback);
  11. glfwSetWindowPosCallback(_mainWindow,GLFWEventHandler::onGLFWWindowPosCallback);
  12. glfwSetFramebufferSizeCallback(_mainWindow,GLFWEventHandler::onGLFWframebuffersize);
  13. glfwSetWindowSizeCallback(_mainWindow,GLFWEventHandler::onGLFWWindowSizeFunCallback);
  14. setFrameSize(rect.size.width,rect.size.height);
  15. //checkOpenGLversionatfirst
  16. constGLubyte*glVersion=glGetString(GL_VERSION);
  17. if(utils::atof((constchar*)glVersion)<1.5)
  18. charstrComplain[256]={0};
  19. 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);
  20. MessageBox(strComplain,"OpenGLversiontooold");
  21. returnfalse;
  22. initGlew();
  23. //Enablepointsizebydefault.
  24. glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
  25. returntrue;
  26. }
5. 有个API 函数glfwGetWin32Window() 可以取得窗口句柄。(由于不了解glfw 网上搜了半天才找到这个。。。)

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

6.下面开始修改代码

在CCGLView.cpp 前面添加文件一定要在宏定义后面

    #defineGLFW_EXPOSE_NATIVE_WIN32
  1. #defineGLFW_EXPOSE_NATIVE_WGL
  2. #include"glfw3native.h"

给GLView类添加成员:

    HWNDgetHwnd();
  1. voidcloseWindow();
  2. HWNDm_hwnd;

    HWNDGLView::getHwnd()
  1. returnm_hwnd;
  2. voidGLView::closeWindow()
  3. glfwSetWindowShouldClose(_mainWindow,1);
  4. }

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

函数最后添加

    m_hwnd=glfwGetWin32Window(_mainWindow);

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

    intApplication::cocosrun()
  1. //Initializeinstanceandcocos2d.
  2. if(!applicationDidFinishLaunching())
  3. return0;
  4. //Retainglviewtoavoidglviewbeingreleasedinthewhileloop
  5. glview->retain();
  6. ShowWindow(glview->getHwnd(),SW_SHOW);
  7. while(!glview->windowShouldClose())
  8. QueryPerformanceCounter(&nNow);
  9. if(nNow.QuadPart-nLast.QuadPart>_animationInterval.QuadPart)
  10. nLast.QuadPart=nNow.QuadPart;
  11. glview->pollEvents();
  12. else
  13. Sleep(0);
  14. //Directorshouldstilldoacleanupifthewindowwasclosedmanually.
  15. if(glview->isOpenGLReady())
  16. director->end();
  17. director=nullptr;
  18. glview->release();
  19. true;
  20. }

8. 打开Application 类添加一个 void closeWindow()public成员函数

    voidApplication::closeWindow()
  1. autodirector=cocos2d::Director::getInstance();
  2. glview->closeWindow();
  3. 9. 给类AppDelegate添加 成员

      HWNDm_hwnd;
    1. RECTm_parentRect;
    2. voidAppDelegate::setParent(HWNDhwnd,RECTrect)
    3. m_hwnd=hwnd;
    4. m_parentRect.left=rect.left;
    5. m_parentRect.top=rect.top;
    6. m_parentRect.right=rect.right;
    7. m_parentRect.bottom=rect.bottom;
    8. 10 修改AppDelegate::applicationDidFinishLaunching() 函数

        if(!glview){
      1. ::SetParent(glview->getHwnd(),m_hwnd);
      2. SetWindowLong(glview->getHwnd(),GWL_STYLE,GetWindowLong(glview->getHwnd(),GWL_STYLE)&~WS_CAPTION);
      3. ::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);
      4. 11. 给对话框添加一个 Picture 控件(注意更改默认 ID),并为其添加Control 类型成员变量 m_cocosWin , 修改上篇中button的消息响应函数

          voidCCocosEditorDlg::OnBnClickedButton1()
        1. AppDelegateapp;
        2. RECTrc;
        3. m_cocos2dWin.GetClientRect(&rc);
        4. app.setParent(m_cocos2dWin.m_hWnd,rc);
        5. cocos2d::Application::getInstance()->cocosrun();
        6. 12. 关闭cocos2d窗口, 在类向导中 给MFC对话框窗口添加 WM_CLOSE消息响应函数

            voidCCocosEditorDlg::OnClose()
          1. cocos2d::Application::getInstance()->closeWindow();
          2. CDialogEx::OnClose();
          3. }

          13.编译运行程序:


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

            boolGLView::initWithRect(conststd::string&viewName,floatframeZoomFactor)
          1. _frameZoomFactor=frameZoomFactor;
          2. glfwWindowHint(GLFW_VISIBLE,GL_FALSE);
          3. _mainWindow=glfwCreateWindow(rect.size.width*_frameZoomFactor,0); background-color:inherit">//checkOpenGLversionatfirst
          4. constGLubyte*glVersion=glGetString(GL_VERSION);
          5. if(utils::atof((constchar*)glVersion)<1.5)
          6. charstrComplain[256]={0};
          7. "OpenGL1.5orhigherisrequired(yourversionis%s).Pleaseupgradethedriverofyourvideocard.",
          8. "OpenGLversiontooold");
          9. false;
          10. //Enablepointsizebydefault.
          11. m_hwnd=glfwGetWin32Window(_mainWindow);</span>
          12. 这样就解决闪一下的问题

            转载请注明出处。


            Test下载地址:点击打开链接



            转子:

            http://blog.csdn.net/greatchina01/article/details/39580767

            猜你在找的Cocos2d-x相关文章