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

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

    GLView*GLView::create(@H_301_31@const@H_301_31@std::string&viewName)@H_301_31@@H_301_31@
  1. autoret=new@H_301_31@GLView;@H_301_31@@H_301_31@
    @H_301_31@//调用了initWithRect()</span>@H_301_31@@H_301_31@@H_301_31@
  1. if@H_301_31@(ret&&ret->initWithRect(viewName,Rect(0,960,640),1)){@H_301_31@@H_301_31@
  2. ret->autorelease();@H_301_31@
  3. return@H_301_31@ret;@H_301_31@@H_301_31@
  4. return@H_301_31@nullptr;@H_301_31@@H_301_31@
  5. }@H_301_31@


4.initWithRect 代码@H_301_31@

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

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

6.下面开始修改代码

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

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

给GLView类添加成员:@H_301_31@

    HWND@H_301_31@getHwnd();@H_301_31@@H_301_31@
  1. void@H_301_31@closeWindow();@H_301_31@@H_301_31@
  2. HWND@H_301_31@m_hwnd;@H_301_31@@H_301_31@

    HWND@H_301_31@GLView::getHwnd()@H_301_31@@H_301_31@
  1. return@H_301_31@m_hwnd;@H_301_31@@H_301_31@
  2. void@H_301_31@GLView::closeWindow()@H_301_31@@H_301_31@
  3. glfwSetWindowShouldClose(_mainWindow,1);@H_301_31@
  4. }@H_301_31@

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

函数最后添加

    m_hwnd=glfwGetWin32Window(_mainWindow);@H_301_31@@H_301_31@

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

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

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

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

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

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

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

            void@H_301_31@CCocosEditorDlg::OnClose()@H_301_31@@H_301_31@
          1. cocos2d::Application::getInstance()->closeWindow();@H_301_31@
          2. CDialogEx::OnClose();@H_301_31@
          3. }@H_301_31@

          13.编译运行程序:@H_301_31@


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

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

            转载请注明出处。


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



            转子:

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

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