<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;
}
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() )
);
}