cocos2dx win32下的MainLoop分析(启动流程)

cocos2dx win32下的MainLoop分析(启动流程),第1张

概述大家都知道,游戏其实就是在死循环中无限绘制,渲染的过程,里面参杂了许多 *** 作,接下来在win32中查看一下cocos2dx的循环过程 一般游戏主循环的简单逻辑如下 float dt;  while (1)  {  ...  update(dt); //通过时间差更新数据  present(dt);//通过时间差呈现、绘制游戏画面  ...  }  我是用VS在WIN32平台下查看,要分析cocos2

大家都知道,游戏其实就是在死循环中无限绘制,渲染的过程,里面参杂了许多 *** 作,接下来在win32中查看一下cocos2dx的循环过程

一般游戏主循环的简单逻辑如下

float dt;
while (1)
{
...
update(dt); //通过时间差更新数据
present(dt);//通过时间差呈现、绘制游戏画面
}

我是用VS在WIN32平台下查看,要分析cocos2dx的启动流程那么就从main函数开始吧,打开main.cpp文件可以看到这里有win32的入口函数,

下方代码为main函数中的核心代码

// create the application instance AppDelegate app; //实例化应用代理对象,这个对象是CCApplication的子类, //实现了applicationDIDFinishLaunching()等方法,目的 //目的是为了在底层框架中回调,做一些初始化或者结尾的工作 CCEGLVIEw* eglVIEw = CCEGLVIEw::sharedOpenGLVIEw();//继承和封装了一些对Opengl接口的 *** 作。不同平台实现不一样 eglVIEw->setVIEwname("TestCpp"); eglVIEw->setFrameSize(480,320); return CCApplication::sharedApplication()->run();//一个单实例类,通过run方法进入引擎主循环 

接着进入 CCApplication::run();\win32\CCApplication.cpp

int CCApplication::run(){    PVRFrameEnableControlWindow(false);//这个好像是专门用于windows的,写注册表禁用pvr frame。    // Main message loop:    MSG msg;     //获取cpu滴答数相关数据结构,可以认为是高精度的计时器。    LARGE_INTEGER nFreq;    LARGE_INTEGER nLast;    LARGE_INTEGER nNow;    queryPerformanceFrequency(&nFreq);    queryPerformanceCounter(&nLast);    // Initialize instance and cocos2d.    //执行AppDeletegate重载的applicationDIDFinishLaunching函数,如果进入这个函数里边可以看到这个函数里代码初始化了cocos2dx的导演类对象、文件模块对象,设置帧数创建场景等等。    if (!applicationDIDFinishLaunching())    {        return 0;    }    //创建窗口,并显示。    CCEGLVIEw* pMainWnd = CCEGLVIEw::sharedOpenGLVIEw();    pMainWnd->centerWindow();    ShowWindow(pMainWnd->getHWnd(),SW_SHOW);    //消息循环。    while (1)    {        if (! PeekMessage(&msg,NulL,PM_REMOVE))        {            // Get current time tick.            queryPerformanceCounter(&nNow);            // If it's the time to draw next frame,draw it,else sleep a while.控制帧数的。<span >判断时间差是不是达到了到下一帧的条件</span>
            if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart)            {
<span >		</span>//主要是看锁定多少的FPS                nLast.QuadPart = nNow.QuadPart;                CCDirector::sharedDirector()->mainLoop();//进入引擎的主循环            }            else            {                Sleep(0);//如果不需要绘制下一帧那么释放cpu控制权。            }            continue;        }        if (WM_QUIT == msg.message)        {            // Quit message loop.            break;        }        // Deal with windows message.消息分发        if (! m_hAcceltable || ! TranslateAccelerator(msg.hwnd,m_hAcceltable,&msg))        {            TranslateMessage(&msg);            dispatchMessage(&msg);        }    }    return (int) msg.wParam;}

从run()函数代码可以看出来,渲染主要发生在CCDirector::sharedDirector()->mainLoop();里边。mainLoop()函数循环检查程序是否退出的标志位(m_bPurgeDirecotorInNextLoop,导演类调用end()方法将会使这个标志位记为true。这个方法在窗口过程收到WM_CLOSE消息的时候调用的),如果为true则清除资源。如果m_bPurgeDirecotorInNextLoop为false并且m_bInvalID并没有被置为true(这个变量由startAnimation()和stopAnimation()控制),那么绘制场景以及检查是否需要释放没有引用计数的内存资源。

voID CCdisplaylinkDirector::mainLoop(voID)//实际上CCDirector::sharedDirector();获取的是CCdisplaylinkDirector类型对象。{    if (m_bPurgeDirecotorInNextLoop)//是否停止渲染。进入下一个主循环,也就是结束这次的主循环,就净化,也就是一些后期处理    {        m_bPurgeDirecotorInNextLoop = false;        purgeDirector();    }    else if (! m_bInvalID)//可以通过调用stopAnimation()的方式停止渲染,在win32下通常在对窗口进行缩小的时候会被调用。     {         drawScene();//绘制屏幕         // release the objects         CCPoolManager::sharedPoolManager()->pop(); //释放一些没有用的对象,主要保件内存的合理管理        }}
CCdisplaylinkDirector是CCdisplay的子类,从命名就应该可以很清晰的知道它的用处。通过CCDirector::sharedDirector()代码,得到的都是CCdisplaylinkDirector对象。通过drawScene()代码就可以实现场景的绘制了
// Draw the ScenevoID CCDirector::drawScene(voID){    // calculate "global" dt    calculateDeltaTime();//计算时间差    //tick before glClear: issue #533    if (! m_bPaused)//如果不暂停,就更新数据        m_pScheduler->update(m_fDeltaTime);//调度者对象,是整个框架中,非常重要的东东,他负责者引擎中精灵、动作等的调度,而里面所用的数据结构的组织,一定程<span >	</span>度决定者引擎的效率。    }    glClear(GL_color_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    /* to avoID flickr,nextScene MUST be here: after tick and before draw.     XXX: Which BUG is this one. It seems that it can't be reproduced with v0.9 */    if (m_pNextScene)    {        setNextScene();//如果有m_pNextScene对象不为空,就说明需要调用到新的场景中,在其中onEnter()、onEnterTransitionDIDFinish()等函数被回调。    }    kmGLPushmatrix();//opengl:把当前矩阵放到栈中    // draw the scene    if (m_pRunningScene)    {        m_pRunningScene->visit();//通过访问方法,去绘制场景中包含的每个层和每个层中的每个节点的draw,这里面是一个递归的过程,其中transform()方法实现,open<span >	</span>gl矩阵的变化 //,移动,旋转等。    }    // draw the notifications node    if (m_pNotificationNode)    {        m_pNotificationNode->visit()//绘制通知节点    }        if (m_bdisplayStats)    {        showStats();    }        kmGLPopMatrix();//opengl:把当前矩阵从栈中移除,回复之前的矩阵    m_uTotalFrames++;//记录总帧数</span>    // swap buffers    if (m_pobOpenGLVIEw)    {        m_pobOpenGLVIEw->swapBuffers();//opengl:交换帧缓冲区,把绘制的东东显示在屏幕。    }        if (m_bdisplayStats)    {        calculateMPF();    }}
参考http://blog.csdn.net/crazy_number/article/details/37915145 总结

以上是内存溢出为你收集整理的cocos2dx win32下的MainLoop分析(启动流程)全部内容,希望文章能够帮你解决cocos2dx win32下的MainLoop分析(启动流程)所遇到的程序开发问题。

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

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

原文地址: https://outofmemory.cn/web/1051429.html

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

发表评论

登录后才能评论

评论列表(0条)

保存