分析cocos2dx 3.3运行流程
<1>不管在哪个平台xode也好,windows下也好,都先进入: cocos2d::Application *app =Application::getInstance(); app->run();
intApplication::run() { if (applicationDidFinishLaunching()) { [[CCDirectorCallersharedDirectorCaller]startMainLoop]; } return0; } boolAppDelegate::applicationDidFinishLaunching() { // initialize director auto director =Director::getInstance(); auto glview = director->getOpenGLView(); if(!glview) { glview = GLViewImpl::create("Cpp Empty Test"); director->setOpenGLView(glview); } director->setOpenGLView(glview); // Set the design resolution glview->setDesignResolutionSize(designResolutionSize.width,designResolutionSize.height,ResolutionPolicy::NO_BORDER); Size frameSize = glview->getFrameSize();
vector<string> searchPath; // In this demo,we select resource according to the frame's height. // If the resource size is different from design resolution size,you need to set contentScaleFactor. // We use the ratio of resource's height to the height of design resolution, // this can make sure that the resource's height could fit for the height of design resolution. // if the frame's height is larger than the height of medium resource size,select large resource. if (frameSize.height >mediumResource.size.height) { searchPath.push_back(largeResource.directory); director->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height,largeResource.size.width/designResolutionSize.width)); } // if the frame's height is larger than the height of small resource size,select medium resource. elseif (frameSize.height >smallResource.size.height) { searchPath.push_back(mediumResource.directory);
director->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height,mediumResource.size.width/designResolutionSize.width)); } // if the frame's height is smaller than the height of medium resource size,select small resource. else { searchPath.push_back(smallResource.directory); director->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height,smallResource.size.width/designResolutionSize.width)); }
// set searching path FileUtils::getInstance()->setSearchPaths(searchPath);
// turn on display FPS director->setDisplayStats(true); // set FPS. the default value is 1.0/60 if you don't call this director->setAnimationInterval(1.0 /60); // create a scene. it's an autorelease object auto scene =HelloWorld::scene(); // run director->runWithScene(scene); returntrue; } <3>资源分辨率设置过之后,每一帧调用一次函数doCaller -(void) startMainLoop { // Director::setAnimationInterval() is called,we should invalidate it first [selfstopMainLoop];
displayLink = [NSClassFromString(@"CADisplayLink")displayLinkWithTarget:selfselector:@selector(doCaller:)]; [displayLinksetFrameInterval:self.interval]; [displayLinkaddToRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode]; }
<4>每一帧都进行mainLoop函数 -(void) doCaller: (id) sender { cocos2d::Director* director =cocos2d::Director::getInstance(); [EAGLContextsetCurrentContext: [(CCEAGLView*)director->getOpenGLView()->getEAGLView()context]]; director->mainLoop(); } <5> voidDisplayLinkDirector::mainLoop() { if (_purgeDirectorInNextLoop) { _purgeDirectorInNextLoop =false; purgeDirector(); } elseif (_restartDirectorInNextLoop) { _restartDirectorInNextLoop =false; restartDirector(); } elseif (! _invalid) { drawScene();
// release the objects PoolManager::getInstance()->getCurrentPool()->clear(); } } <6>绘制玩每一帧都,都会被刚添加到自动管理池AutoReleasePool中的对象进行一次遍历。
void AutoreleasePool::clear() { #if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) _isClearing = true; #endif std::vector<Ref*> releasings; releasings.swap(_managedObjectArray); for (const auto &obj : releasings) { obj->release(); } _isClearing = false; #endif } 总结: std::vector<Ref*> releasings; releasings.swap(_managedObjectArray); 这行代码很有意思,将releasings和_managedObjectArray内容进行交换,交换后,_managedObjectArray就为空了,然后将releasings遍历一遍,将引用计数减去1,为0的就回收内存了。
<7>
// Draw the Scene voidDirector::drawScene() { // calculate "global" dt calculateDeltaTime();
if (_openGLView) { _openGLView->pollEvents(); } //tick before glClear: issue #533 if (!_paused) { _scheduler->update(_deltaTime); _eventDispatcher->dispatchEvent(_eventAfterUpdate); } _renderer->clear(); experimental::FrameBuffer::clearAllFBOs(); /* to avoid flickr,nextScene MUST be here: after tick and before draw. * FIXME: Which bug is this one. It seems that it can't be reproduced with v0.9 */ if (_nextScene) { setNextScene(); } pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
if (_runningScene) { #if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION) || CC_USE_NAVMESH) _runningScene->stepPhysicsAndNavigation(_deltaTime); #endif //clear draw stats _renderer->clearDrawStats();
//render the scene _runningScene->render(_renderer);
_eventDispatcher->dispatchEvent(_eventAfterVisit); } // draw the notifications node if (_notificationNode) { _notificationNode->visit(_renderer,Mat4::IDENTITY,0); } if (_displayStats) { showStats(); } _renderer->render(); _eventDispatcher->dispatchEvent(_eventAfterDraw); popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); _totalFrames++; // swap buffers if (_openGLView) { _openGLView->swapBuffers(); } if (_displayStats) { calculateMPF(); } } <8>在Scene中调用其render方法回执场景。 voidScene::render(Renderer* renderer) { auto director =Director::getInstance(); Camera* defaultCamera =nullptr; constauto& transform =getNodeToParentTransform(); for (constauto& camera :getCameras()) { if (!camera->isVisible()) continue;
Camera::_visitingCamera = camera; if (Camera::_visitingCamera->getCameraFlag() == CameraFlag::DEFAULT) { defaultCamera = Camera::_visitingCamera; }
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION,Camera::_visitingCamera->getViewProjectionMatrix()); camera->apply(); //clear background with max depth camera->clearBackground(); //visit the scene visit(renderer,transform,0); #if CC_USE_NAVMESH if (_navMesh &&_navMeshDebugCamera == camera) { _navMesh->debugDraw(renderer); } #endif
renderer->render();
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); }
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION if (_physics3DWorld &&_physics3DWorld->isDebugDrawEnabled()) { _physics3dDebugCamera !=nullptr ?_physics3dDebugCamera->getViewProjectionMatrix() : defaultCamera->getViewProjectionMatrix()); _physics3DWorld->debugDraw(renderer); renderer->render(); director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); } #endif Camera::_visitingCamera =nullptr; experimental::FrameBuffer::applyDefaultFBO(); } voidNode::visit(Renderer* renderer,constMat4 &parentTransform,uint32_t parentFlags) { // quick return if not visible. children won't be drawn. if (!_visible) { return; } uint32_t flags =processParentFlags(parentTransform,parentFlags); // IMPORTANT: // To ease the migration to v3.0,we still support the Mat4 stack,0)"> // but it is deprecated and your code should not rely on it _director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); _director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW,_modelViewTransform);
bool visibleByCamera =isVisitableByVisitingCamera(); int i =0; if(!_children.empty()) { sortAllChildren(); // draw children zOrder < 0 for( ; i <_children.size(); i++ ) { auto node =_children.at(i); if (node && node->_localZOrder <0) node->visit(renderer,_modelViewTransform,flags); else break; } // self draw if (visibleByCamera) this->draw(renderer,flags); for(auto it=_children.cbegin()+i; it != _children.cend(); ++it) (*it)->visit(renderer,flags); } elseif (visibleByCamera) { this->draw(renderer,flags); } _director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
// FIX ME: Why need to set _orderOfArrival to 0?? // Please refer tohttps://github.com/cocos2d/cocos2d-x/pull/6920 // reset for next frame // _orderOfArrival = 0; }
首先绘制_localZOrder < 0的,其次在for(autoit=_children.cbegin()+i; it !=cend(); ++it)绘制 >=0 的
<10>
voidNode::sortAllChildren() { if (_reorderChildDirty) { std::sort(std::begin(_children),std::end(_children),nodeComparisonLess); _reorderChildDirty =false; } } bool nodeComparisonLess(Node* n1,Node* n2) { return( n1->getLocalZOrder() < n2->getLocalZOrder() || ( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() ) ); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |