<pre name="code" class="cpp">int Application::run() { // Initialize instance and cocos2d. if (! applicationDidFinishLaunching()) { return 0; } long lastTime = 0L; long curTime = 0L; auto director = Director::getInstance(); auto glview = director->getOpenGLView(); // Retain glview to avoid glview being released in the while loop glview->retain(); while (!glview->windowShouldClose()) { lastTime = getCurrentMillSecond(); //1? director循环</span> director->mainLoop(); //2? 这里的glview就是AppDelegate.cpp中GLView::create得到、并使用Director::setOpenGLView设置的。</span> //在许多平台下没这函数。。</span> glview->pollEvents(); //sleep, 使得达到指定帧率。 帧率是由cpu及所需的运算量决定。</span> curTime = getCurrentMillSecond(); if (curTime - lastTime < _animationInterval) { usleep((_animationInterval - curTime + lastTime)*1000); } } /* Only work on Desktop * Director::mainLoop is really one frame logic * when we want to close the window,we should call Director::end(); * then call Director::mainLoop to do release of internal resources */ if (glview->isOpenGLReady()) { director->end(); director->mainLoop(); director = nullptr; } glview->release(); return -1; } void DisplayLinkDirector::mainLoop() { //调用Director::end时才为true。</span> if (_purgeDirectorInNextLoop) { _purgeDirectorInNextLoop = false; purgeDirector(); } else if (! _invalid) {//_invalid. 初始值为false。 当StartAnimation时为false, StopAnimation时为true。</span> //3 ....</span> drawScene(); // release the objects</span> //对当前AutoReleasePool中所有object调用一次release</span> PoolManager::getInstance()->getCurrentPool()->clear(); } } void Director::drawScene() { // calculate "global" dt</span> //计算_deltaTime。 也就是本次drawScene与上次调用drawScene的时间差。</span> calculateDeltaTime(); // skip one flame when _deltaTime equal to zero. if(_deltaTime < FLT_EPSILON) { return; } if (_openGLView) { //在许多平台下, 该函数没有或者为空。 _openGLView->pollInputEvents(); } //tick before glClear: issue #533 if (! _paused)//Dierctor::pause时设置该值为true; Director::resume时设置该值为false { //update的逻辑:</span> //对_updateNegList,_update0List,_updatePosList 三种priority的调用回调。 这三种都是使用Schedule::scheduleUpdate加入的定时器</span> //对_hashForTimers调用回调。 这种是使用Schedule::schedule加入的定时器。</span> //然后依次从<span style="font-family: Arial,Helvetica,sans-serif;">_updateNegList,_updatePosList中删除需要删除的定时器</span></span> _scheduler->update(_deltaTime); //dispatch逻辑</span> //如果Event::Type::TOUCH, 找到单点触摸的listener和多点触摸的listener; 先执行单点触摸的回调, 然后执行多点触摸的回调</span> //否则可能为ACCELERATION/CUSTOM/KEYBOARD/MOUSE,找到对应的listener的associateNode, 执行_onEvent,如果返回_onEvent返回true、且调用了Event::stopPropagation(), 则不再向后传递事件。游戏开发之旅上说的是调用EventListener::setSwallowTouches(false)。</span> _eventDispatcher->dispatchEvent(_eventAfterUpdate); } 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 */ //如果调用了replaceScene/push/pop/popToSceneStackLevel之后, _nextScene就有效。</span> if (_nextScene) { setNextScene(); } kmGLPushMatrix(); // global identity matrix is needed... come on kazmath! kmMat4 identity; kmMat4Identity(&identity); // draw the scene //_runingScene始终有效。 只有当刚Director::init时以及Director::purgeDirector时才会被设为NULL</span> if (_runningScene) { _runningScene->visit(_renderer,identity,false); _eventDispatcher->dispatchEvent(_eventAfterVisit); } // draw the notifications node //是被Director::setNotificationNode设置的Node</span> if (_notificationNode) { //!!!!这里是绘制。将children按zOrder排序递归绘制: 先绘制_localZOrder<0的childrenNode;然后绘制自己;再绘制剩下的childrenNode</span> //这里的绘制, 只是将Node的{_globalZOrder,_texture->getName(),_shaderProgram,_blendFunc,...>构造成一个QuadCommand,放入 Rendererde 的容器中</span> _notificationNode->visit(_renderer,false); } if (_displayStats) {//显示统计信息。 Director::setDisplayStats(true); showStats(); } //!!!!这里是真正的绘制。。 这里有BatchCommand之类的处理。</span> _renderer->render(); _eventDispatcher->dispatchEvent(_eventAfterDraw); kmGLPopMatrix(); _totalFrames++; // swap buffers if (_openGLView) { _openGLView->swapBuffers(); } if (_displayStats) { calculateMPF(); } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。