Cocos2d-x 绘制节点的流程

来源:互联网 发布:ubuntu 命令行 编辑:程序博客网 时间:2024/06/03 17:37

一、引擎绘制节点的流程


在cocos2d-x中是通过分配一段连续的内存来存储children,当新的child被add进来,他会默认被添加到后面,如果不够会重新分配当前当前最大的两倍的容量,和STL的策略是一样的。在每一帧进行渲染的时候,根据child的zorder的大小进行排序(其实就是冒泡排序),zorder最小的排在前面进行绘制。


引擎都是以OpenGL为基础进行图像的绘制的,在main.cpp中完成OpenGL的准备以及绘制的流程的开始。

(以win下的流程为例)


CCEGLView* eglView = CCEGLView::sharedOpenGLView();     //触发OpenGL的初始化


CCEGLView* CCEGLView::sharedOpenGLView()

{

     static CCEGLView* s_pEglView = NULL;

     if (s_pEglView == NULL)

     {

          s_pEglView = new CCEGLView();     //

          if (!s_EglView->Create())

          {

               delete s_pEglView;

               s_pEglView = NULL;

          }

     }


     return s_pEglView;

}


CCEGLView::Create()函数主要做Windowos窗体程序的相关设置,调用CCEGLView::initGL()


bRet = initGL()


在initGL中准备各种OpenGL的设置。


int ret = CCApplication::sharedApplication()->run();


run函数调用applicationDidFinishLaunching()和开始一个死循环,驱动每一帧的绘制。

AppDelegate::applicationDidFinishLaunching()中初始化CCDirector(实际创建的是CCDisplayLinkDirector),设置设计尺寸(setDesignResolutionSize),设置资源路径(setResourceDirectory),创建一个场景,以这个场景作为第一个场景来运行。


CCScene直接继承自CCNode,项目节点树的根节点一定是CCScene,既绘制流程一定是从一个场景开始绘制。死循环就是应用的主循环,每次循环判断是否需要绘制一帧,如果是就开始绘制,否则。。。


while(1)

{

     //


     if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart)     //判断是否需要绘制,当前时刻与上次绘制时刻的差大于帧速

     {

          nLast.QuadPart = nNow.QuadPart;     //更新上次绘制时刻

          CCDirector::sharedDirector()->mainLoop();     //进入绘制流程          

     } else {

          Sleep(0);     //休息一段时间

     }

}


CCDisplayLinkDirector::mainLoop()调用drawScene(),CCDirector::drawScene()负责切换场景,以及从一个场景开始逐个节点访问并绘制。


if (m_pNextScene)

{

     setNextScene();

}


if (m_pRuningScene)

{

     m_pRunningScene->visit();

}


CCNode::visit()计算本节点的变形并更新模型视图矩阵,遍历访问子节点和绘制自身。


if (m_pChildren && m_pChildren->count() > 0)

{

     sortAllChildren();     // 


     ccArray *arrayData = m_pChildren->data;

     for(; i < arrayData->num; i++)

     {

          pNode = (CCNode*)arrayData->arr[i];

          if (pNode && pNode->m_nZorder < 0)

          {

               pNode->visit();

          } else {

               break;

          }

     }


     this->draw();


     for(; i < arrayData->num; i++)

     {

          pNode = (CCNode*)arrayData->arr[i];

          if (pNode)

          {

               pNode->visit();

          }

     }

} else {

     this->draw();

}


这样中序遍历节点树后,一帧的绘制就完成了。

原创粉丝点击