cocs2d-x 3.2源码分析(一)

从本篇文章开始,将分析cocos2d-X 3.2源代码,本篇首先介绍cocos2d-X 3.2的渲染结构,使用的是3.2正式版。

首先是程序入口:

<pre name="code" class="cpp">int Application::run()
{
    PVRFrameEnableControlWindow(false);

    // Main message loop:
    LARGE_INTEGER nFreq;
    LARGE_INTEGER nLast;
    LARGE_INTEGER nNow;

    QueryPerformanceFrequency(&nFreq);
    QueryPerformanceCounter(&nLast);

    // Initialize instance and cocos2d.进入主循环之前做初始化工作
    if (!applicationDidFinishLaunching())
    {
        return 0;
    }
   //获取单例的director和绘图窗口
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();

    // Retain glview to avoid glview being released in the while loop
    glview->retain();
    while(!glview->windowShouldClose())
    {
        QueryPerformanceCounter(&nNow);
        if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart)
        {
            nLast.QuadPart = nNow.QuadPart;
            //进入主循环
            director->mainLoop();
            glview->pollEvents();
        }
        else
        {
            Sleep(0);
        }
    }

    // Director should still do a cleanup if the window was closed manually.这里是说游戏窗口关闭之后需要再运行一次主循环释放内存,否则会报错
    if (glview->isOpenGLReady())
    {
        director->end();
        director->mainLoop();
        director = nullptr;
    }
    glview->release();
    return true;
}



</pre><pre name="code" class="cpp">
游戏主循环mainloop()方法:游戏主循环每一帧所做的事无非就是加载数据,绘制屏幕,释放内存
<pre name="code" class="cpp">void DisplayLinkDirector::mainLoop()
{
//导演类调用end函数 ,会调用到这里来

    if (_purgeDirectorInNextLoop)
    {
        _purgeDirectorInNextLoop = false;
        purgeDirector();//清除导演类
    }
    else if (! _invalid)
    {
        drawScene();//绘制屏幕
     
        // release the objects
        PoolManager::getInstance()->getCurrentPool()->clear();//释放内存
    }
}
绘制屏幕drawScene():
void Director::drawScene()
{
    // calculate "global" dt 计算上一帧开始到即将开始这一帧的时间间隔<span style="font-family: Arial, Helvetica, sans-serif;">_deltaTime </span>
    calculateDeltaTime();
    
    // skip one flame when _deltaTime equal to zero.间隔时间太短则忽略
    if(_deltaTime < FLT_EPSILON)
    {
        return;
    }
//空实现
    if (_openGLView)
    {
        _openGLView->pollInputEvents();
    }
   //自己加的游戏循环
    if(! _pausePreDrawListener && _preDrawListener)
     {
	_preDrawListener->onPreDraw(_deltaTime);
     }

    //tick before glClear: issue #533 非暂停状态
    if (! _paused)
    {
        _scheduler->update(_deltaTime);
        _eventDispatcher->dispatchEvent(_eventAfterUpdate);
    }
    //自己的游戏逻辑
	if(_speedStep > 0.0f && _speedTime > 0.0f)
	{
		for(float time = 0.0f; time < _speedTime; time += _speedStep)
		{
			if(_preDrawListener)
			{
				_preDrawListener->onPreDraw(_speedStep);
			}

			_scheduler->update(_speedStep);
		}

		_speedStep = 0.0f;
		_speedTime = 0.0f;
	}

    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //edit by chenyingpeng


    /* 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 */切换下一场景,必须放在逻辑后绘制前,否则会出bug  
    if (_nextScene)
    {
        setNextScene();
    }

    pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);

    // draw the scene绘制场景
    if (_runningScene)
    {
        _runningScene->visit(_renderer, Mat4::IDENTITY, false);
        _eventDispatcher->dispatchEvent(_eventAfterVisit);
    }

    // draw the notifications node //绘制观察节点,如果你需要在场景中设立观察节点,请调用摄像机的setNotificationNode函数 
    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();
    }
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值