cocos2d-x 3.3 RC 个人升级总结 Director的主线解析

 /**
     *  Sets the Resource root path.
     *  @deprecated Please use FileUtils::getInstance()->setSearchPaths() instead.
     */
    CC_DEPRECATED_ATTRIBUTE void setResourceRootPath(const std::string& rootResDir);

    /**
     *  Gets the Resource root path.
     *  @deprecated Please use FileUtils::getInstance()->getSearchPaths() instead.
     */
    CC_DEPRECATED_ATTRIBUTE const std::string& getResourceRootPath(void);

1、越来越多的api变化,怎么办?鉴于此,以后每次升级引擎的时候,在全局中搜索:CC_DEPRECATED_ATTRIBUTE,这样子就可以看到那些api进行了修改。如果是在mac环境中,则可以继续查找结果中匹配的字符,比如某个api,直接搜索看看说明。这样子就能方便的切换新api,而不是经常跳转。

2、我终于明白引擎的运行完整路线了。

首先,通过director和scene的create和add分别完成资源创建和渲染树构造,之前一直漏掉了这句,现在已经补上了。可以去相关博客重新阅读。

接着,每次循环中执行cocos2d-x的引擎主线和轮询OpenGL的事件

 <span style="white-space: pre;">		</span>director->mainLoop();
           <span style="white-space: pre;">	</span>glview->pollEvents();

然后,在mainLoop中完成drawScene和清理当前垃圾(未处理的内存要求开发自己去管理),drawScene主要完成了:

 // calculate "global" dt  计算时间切片
    calculateDeltaTime();

    // skip one flame when _deltaTime equal to zero. 是否跳过当前帧的绘制
    if(_deltaTime < FLT_EPSILON)
    {
        return;
    }

    if (_openGLView)  //轮询OpenGL的回调事件处理,可以看到目前是个空实现
    {
        _openGLView->pollEvents();
    }

进入平时主线相关的定时器刷新、事件的派发。

//tick before glClear: issue #533
    if (! _paused)
    {
        _scheduler->update(_deltaTime);
        _eventDispatcher->dispatchEvent(_eventAfterUpdate);
    }

完了原本的数据处理之后开始进入图像渲染的工作流:

/* 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 */
    if (_nextScene)
    {
        setNextScene();
    }

1、setNextScene的工作内容和代码:根据是否需要切换场景完成场景切换相关:添加节点:执行完init()方法进入replaceScene后,在渲染树中,新旧场景是同时存在的
,1.1、先清理旧场景,执行旧场景的清场 1.2
执行新场景的入场和入场后动作。我再次瞄了一下3.3、3.2、2.2.3和是一样的,我曾经因为听别人说先进入新场景进场再执行旧场景的退场(这可能是之前某个版本的bug,现在不再去考究了)。大家记住,一定要自己看源码,要不然就不选开源引擎啦。

void Director::setNextScene()
{
    bool runningIsTransition = dynamic_cast<TransitionScene*>(_runningScene) != nullptr;
    bool newIsTransition = dynamic_cast<TransitionScene*>(_nextScene) != nullptr;

    // If it is not a transition, call onExit/cleanup
     if (! newIsTransition)
     {
         if (_runningScene)
         {
             _runningScene->onExitTransitionDidStart();
             _runningScene->onExit();
         }

         // issue #709. the root node (scene) should receive the cleanup message too
         // otherwise it might be leaked.
         if (_sendCleanupToScene && _runningScene)
         {
             _runningScene->cleanup();
         }
     }

    if (_runningScene)
    {
        _runningScene->release();
    }
    _runningScene = _nextScene;
    _nextScene->retain();
    _nextScene = nullptr;

    if ((! runningIsTransition) && _runningScene)
    {
        _runningScene->onEnter();
        _runningScene->onEnterTransitionDidFinish();
    }
}

设置完场景,即挂载了当前的渲染树,就开始进入OpenGL的图像处理阶段:

//入栈,设置OpenGL的状态机,跟2D、3D切换相关,悲剧的是我没看懂,求大家一起来

pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);

 // draw the scene
    if (_runningScene)
    {
        //clear draw stats  3.3才有几这句,3.2是没有的
        _renderer->clearDrawStats();
        
        //render the scene
        _runningScene->render(_renderer);
        
        _eventDispatcher->dispatchEvent(_eventAfterVisit);
    }

绘制未变化或刚刚设置挂载的渲染树(在跟渲染相关时,我比较喜欢把scene成为渲染树,因为它就是rootNode,在游戏引擎为单窗口单线程中只有一个Scene)

//下面这段代码是完成弹窗通知,因为其绘制永远在主渲染树之后,所以永远会遮盖当前的游戏主图像
// draw the notifications node
    if (_notificationNode)
    {
        _notificationNode->visit(_renderer, Mat4::IDENTITY, false);
    }

//设置debug状态下的OpenGL绘制信息,不影响游戏情节
    if (_displayStats)
    {
        showStats();
    }

接下来又是一句新代码:

 _renderer->render();

待续!!!绘制命令的执行。

首先得说一句:在2.x中OpenGL的绘制是使用立即模式绘制,所以才有SpriteBatchNode这个产物

立即模式下是直接在引擎的每个渲染节点中使用OpenGL的绘制命令,所以会有这样类似的代码:kmGLPushMatrix、kmGLPopMatrix 管理OpenGL的状态。

   kmGLPushMatrix();

    // draw the scene
    if (m_pRunningScene)
    {
        m_pRunningScene->visit();
    }

    // draw the notifications node
    if (m_pNotificationNode)
    {
        m_pNotificationNode->visit();
    }

    if (m_bDisplayStats)
    {
        showStats();
    }

    kmGLPopMatrix();

但是这个是v2版本的代码。v3中使用的OpenGL 可以参考这个帖子:点击打开链接

v3用的是显示列表模式(不再需要我们自己去使用OpenGL的命令,因为已经有封装好立即模式的DrawPrimitives了)

绘制完之后:

<span style="white-space:pre">	</span>_eventDispatcher->dispatchEvent(_eventAfterDraw);//派发绘制结束的事件,在OpenGL绘制之后主线程回到cocos引擎中

    <span style="white-space:pre">	</span>popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); //回复原先的opengl状态

双缓冲,切换缓冲区,准备进入下一张画布的绘制。

// swap buffers
    if (_openGLView)
    {
        _openGLView->swapBuffers();
    }

    if (_displayStats)
    {
        calculateMPF();
    }
时间: 2024-10-13 21:33:55

cocos2d-x 3.3 RC 个人升级总结 Director的主线解析的相关文章

Android在线升级相关笔记一(解析服务器版本与当前版本比较)

大概流程:Android客户端去访问服务器上的封装了版本号等信息的xml文件,对服务器上的版本和当前版本进行比较, 如果低于服务器的版本,则下载服务器上的新版软件,进行安装替换,完成升级. 一.首先用tomcat搭建服务器,用于开发测试. 下载tomcat请参考:http://blog.csdn.net/only_tan/article/details/25110625 1.在tomcat中新建自己的项目: \apache-tomcat-6.0.39\webapps 目录下新建自己的项目文件夹,

cocos2d lua绑定感悟---像cc.Sprite,cc.Director这些是如何识别的

其实自从打开GameScene.lua文件以来,我一直都很想搞清楚的一个问题就是cc.Sprite这些是如何识别的.其实第一反应肯定就是:它肯定是一个全局变量,要不然怎么调用create方法呢.先不考究cocos的C++类方法是如何绑定到lua的,我就是想知道这个全局变量是什么时候注册的? 知道一点lua知识的都知道 lua里面的全局变量会保存到一个全局表_G中去,问题就转换为了 什么时候向_G中注册的?在使用cc.Sprite的create之前,我好像没有没有在lua中定义cc.Sprite这

Android init.rc 文件解析

init.rc文件解析过程 我们已经知道init.rc的结构,应该可以想到解析init.rc的过程就是识别一个个section的过程,将各个section的信息保存下来,然后在init.c的main()中去执行一个个命令. android采用双向链表(关于双向链表详解见本文第三部分)来存储section的信息,解析完成之后,会得到三个双向链表action_list.service_list.import_list来分别存储三种section的信息上. 1. init.c中调用init_parse

20190528-JavaScriptの打怪升级旅行 { 语句 [ 赋值 ,数据 ] }

写在前面的乱七八糟:今天考了试,emmm很基础的题,还是Mrs房的面试题让人绝望啊┓( ´∀` )┏,补了很多知识,很综合的题,坑也很多,总的来说,查漏补缺,其实是啥都缺~ 今天打的小BOSS主要是数据,但也不得不提到赋值,┓( ´∀` )┏ 语句:声明  变量  赋值   数据: 3.赋值 在说赋值方式之前,需要先引入js的数值类型:基本类型和引用类型(boss4会细剖),下面我就假装都懂这俩个小怪的区别了,开始我一本正经的吹~,咳,一本正经地打怪升级了. 现象: 解析:莫得慌,一步步来,首先

cocos2dx 3.2之Lua打飞机项目

1          创建lua打飞机项目 cocos new T32Lua -dE:\Installed\cocos2d-x-3.2\cocos2d-x-3.2\projects -l lua 2  项目代码 Common.lua --用于打印日志信息 function cclog(...) print(string.format(...)) end function createBackMenu(node, callback) -- 获得窗口的大小 local winSize = cc.Di

Could not find property &#39;outputFile&#39; on com.android.build.gradle.internal.api.ApplicationVariantImpl

Android studio从1.0 RC 4升级到1.0(其实就是打了一个8M的patch)后,这个时候相应的gradle的版本也会直接使用"com.android.tools.build:gradle:1.0.0",如果这时你在gradle文件中又用到outputFile就会出现上述的问题.好吧,其实这也是gradle团队搞的问题,有时候我们多希望gradle能像android一样,对旧版本有一个非常好的兼容性. 废话不多说,直接说怎么解决这个问题吧,这个问题的原因是outputF

Kubernetes 编排系统

1.1.1 什么是Kubernetes Kubernetes (通常称为K8s,K8s是将8个字母"ubernete"替换为"8"的缩写) 是用于自动部署.扩展和管理容器化(containerized)应用程序的开源系统.Google设计并捐赠给Cloud Native Computing Foundation(今属Linux基金会)来使用的. 它旨在提供"跨主机集群的自动部署.扩展以及运行应用程序容器的平台".它支持一系列容器工具, 包括Doc

Kubernetes 入门基础篇

Kubernetes 1.4 基础课程 Kubernetes 介绍 Kubernetes的发展历史 Kubernetes是一个开源的用于管理大量异构主机组成的云平台中容器的应用,Kubernetes的目标是让部署容器化的应用及微服务简单且高效.Kubernetes提供了应用部署.规划.更新和维护的软件集合,它的核心特点之一就是保证云平台中的容器按照用户的期望自动化的运行,云平台管理人员仅仅需要加载一个微型服务,规划器会自动找到合适的位置高可用的运行这个微服务. 在Docker作为高级容器引擎快速

kuberbetes基础概念

部署了一大堆,来了解一下K8S一些基本的概念. 1.Node Node作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod.Node上运行着Kubernetes的Kubelet.kube-proxy服务进程,这些服务进程负责Pod的创建.启动.监控.重启.销毁.以及实现软件模式的负载均衡. Node包含的信息: Node地址:主机的IP地址,或Node ID. Node的运行状态:Pending.Running.Terminated三种状态. No