Cocos2dx笔记(3.x)
1. 内存管理
Cocos2dx是通过引用计数方式管理内存,主要通过两种方式实现。
1.1 手动内存管理
手动retain和release
1.2 autorelease
创建一个对象后,可以使用autorelease()方法放入自动回收池,每一帧结束的时候自动release。函数调用关系为:
- director->mainLoop()
- PoolManager:getInstance->getCurrentPool->Clear()
- obj->release()
问题:
- 发生时机在帧结束时期,release出错难定位。
- 如果一帧创建大量对象,会导致释放池性能下降。
2. 渲染机制
Cocos2dx在每一帧进行一次渲染,mainloop()方法的drawScene()方法,先清除渲染状态,然后调用_runningScene->render()方法。render()里使用visit()方法,用sortAllChildren()(按LocalZOrder和OrderOfArrival排序)对子节点排序,通过调用draw函数,首先绘制LocalZOrder<0的节点,在绘制自身,最后绘制LocalZOrder>0的节点。draw函数里面并没有做实际的渲染工作,而是初始化渲染命令,添加到对应的渲染队列中。最后回到_runningScene->render()中执行Renderer::render()方法。
Renderer::render()方法中,对_renderGroups(_renderGroups是存储RenderQueue的容器,RenderQueue类实质是一个存储了5种渲染命令的容器)里的每个渲染队列执行sort方法排序,根据其GlobalZorder从小到大进行排序,对GZOrder小于0的渲染命令、GZOrder大于0的渲染命令按ZOrder从小到大进行排序。此时没有对GZOrder等于0的渲染命令排序,因为这些渲染命令的添加是按照所属的Node的LocalZOrder顺序添加的,即已经排好序,无需再次排序。
排序后执行visitRenderQueue(_renderGroups[0])(),该方法是按队列里命令分类的顺序,依次对每个分类的每个命令执行processRenderCommand方法。
processRenderCommand方法遍历队列内的每个分类,把命令加到容器中。在当前分类的命令都被遍历之后,执行flush()方法,该方法主要是调用了drawBatchedTriangles()方法。
drawBatchedTriangles()会判断批量渲染的条件是否成立,主要是比较当前命令材质ID和上个命令材质ID。
总结
渲染是在每帧结束前进行的;渲染之前是把每帧的所有元素的绘制用命令统一进行存储,在渲染时读取这些命令,进行绘制;渲染时还会进行批量绘制的判断,这能有效降低DrawCall值。
3. 程序开始和结束
3.1 开始
AppDelegate::applicationDidFinishLaunching()里的runWithScene。
3.2 结束
mainloop里的_purgeDirectorInNextLoop判断
3.2.1 _purgeDirectorInNextLoop何时改变
- director调用end()函数。
- popScene,无场景的时候也会调end。
3.2.2 purgeDirector()做了什么
- 清理定时器
- 回收当前场景
- 销毁缓冲区
- 执行glView的end()函数