好记性不如铅笔头

C && C++, cocos2dx, 编程

cocos2dx学习笔记:cocos2dx3.x版本Director学习笔记

通过前面的分析【 cocos2dx学习笔记:cocos2dx3.x版本程序初始化流程 】,我们可以简单了解到Director的外部调用逻辑:

首先在 Application::run 中调用了 AppDelegate::applicationDidFinishLaunching 申请了一个实例,设定了View,并且开始运行一个场景:

auto director = Director::getInstance();
。。。。
director->setOpenGLView(glview);
。。。。
director->runWithScene(scene);

然后在 Application::run 方法中继续执行,进入了程序主循环:

while(!glview->windowShouldClose())
{
	。。。。。
		director->mainLoop();
	。。。。。
}

这里我们简单的笔记下Director的代码。

CONTENTS

先看下初始化相关代码:

//单例,注意这里的单例的类型是DisplayLinkDirector,是Director的一个子类。
static DisplayLinkDirector *s_SharedDirector = nullptr;
//默认1s中60帧
#define kDefaultFPS        60  // 60 frames per second
extern const char* cocos2dVersion(void);

//几个自定义的事件的名称
const char *Director::EVENT_PROJECTION_CHANGED = "director_projection_changed";
const char *Director::EVENT_AFTER_DRAW = "director_after_draw";
const char *Director::EVENT_AFTER_VISIT = "director_after_visit";
const char *Director::EVENT_AFTER_UPDATE = "director_after_update";

//单例
Director* Director::getInstance()
{
    if (!s_SharedDirector)
    {
        s_SharedDirector = new (std::nothrow) DisplayLinkDirector();
        CCASSERT(s_SharedDirector, "FATAL: Not enough memory");
        s_SharedDirector->init();
    }

    return s_SharedDirector;
}

Director::Director()
{
}
//Director的初始化方法,做了很多工作,包含了cocos2dx的放放面面,这里我们只关心几个流程。
bool Director::init(void)
{
    setDefaultValues();//设置程序默认值

		//初始化各种程序变量
。。。。。
。。。。。
    // scheduler
    _scheduler = new Scheduler();//定时器
    // action manager
    _actionManager = new ActionManager();//动作管理器,管理各种actions
    _scheduler->scheduleUpdate(_actionManager, Scheduler::PRIORITY_SYSTEM, false);

    _eventDispatcher = new EventDispatcher();//事件分发器
    //各种自定义事件
    _eventAfterDraw = new EventCustom(EVENT_AFTER_DRAW);
    _eventAfterDraw->setUserData(this);
    _eventAfterVisit = new EventCustom(EVENT_AFTER_VISIT);
    _eventAfterVisit->setUserData(this);
    _eventAfterUpdate = new EventCustom(EVENT_AFTER_UPDATE);
    _eventAfterUpdate->setUserData(this);
    _eventProjectionChanged = new EventCustom(EVENT_PROJECTION_CHANGED);
    _eventProjectionChanged->setUserData(this);

	  //init TextureCache
    //初始化TextureCache,用来管理用到的所有的材质
    initTextureCache();
    initMatrixStack();//初始化openGL绘制时的矩阵变换

    _renderer = new Renderer;//初始化cocos2dx的渲染器。这是cocos2dx3.x版本相对于2.x版本的最大的变动

#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
    _console = new Console;
#endif
    return true;
}

然后是Director::setOpenGLView:

void Director::setOpenGLView(GLView *openGLView)
{
    CCASSERT(openGLView, "opengl view should not be null");

    if (_openGLView != openGLView)
    {
        // Configuration. Gather GPU info
        Configuration *conf = Configuration::getInstance();
        conf->gatherGPUInfo();
        CCLOG("%s\n",conf->getInfo().c_str());

				//将传入的view的指针保存下来
        if(_openGLView)
            _openGLView->release();
        _openGLView = openGLView;
        _openGLView->retain();

        // set size
        _winSizeInPoints = _openGLView->getDesignResolutionSize();

        createStatsLabel();

        if (_openGLView)
        {//设置openGL的默认值
            setGLDefaultValues();
        }
				//初始化渲染器
        _renderer->initGLView();

        CHECK_GL_ERROR_DEBUG();

        if (_eventDispatcher)
        {//使能 事件分发
            _eventDispatcher->setEnabled(true);
        }
    }
}

mainLoop:

void DisplayLinkDirector::mainLoop()
{
	。。。。。
	 drawScene();
	。。。。。
}

// Draw the Scene
void Director::drawScene()
{
。。。。。
		//首先获取到输入事件
    if (_openGLView)
    {
        _openGLView->pollInputEvents();
    }

    //tick before glClear: issue #533
    if (! _paused)
    {
        _scheduler->update(_deltaTime);//定时器更新
        _eventDispatcher->dispatchEvent(_eventAfterUpdate);//特定事件分发
        //前面初始化时定义了一个自定义的事件,这里将它分发出去。这个时机为【 update调用之后 】
    }
		//清屏
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    /* 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();
    }
	//矩阵变换
    pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);

    // draw the scene
    if (_runningScene)
    {
        _runningScene->visit(_renderer, Mat4::IDENTITY, false);//调用visit方法将场景所有元素传入_renderer
        _eventDispatcher->dispatchEvent(_eventAfterVisit);//特定事件分发
        //前面初始化时定义了一个自定义的事件,这里将它分发出去。这个时机为【 visit调用之后 】
    }
    // draw the notifications node
    if (_notificationNode)
    {
        _notificationNode->visit(_renderer, Mat4::IDENTITY, false);
    }

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

笔记到这里,Director中比较有分量的代码已经贴出来了,其他的代码就不笔记了。可以发现,除了事件响应和渲染流程变化了之外,其他的和cocos2dx2.x版本没有太大的区别。

通过Director::init,我们知道了一下几个部件的初始化入口:
EventDispatcher  事件分发器
Scheduler  定时器
ActionManager  动作管理器
Renderer   cocos2dx的渲染器
。。。。
。。。。
后续会笔记下这几个部件的大致的流程,其他的部件和2.x版本差不多,就不再笔记了。

发表评论

3 × 5 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据