Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cocos2dx 是如何渲染的 #1

Open
zhishu520 opened this issue Nov 16, 2018 · 0 comments
Open

cocos2dx 是如何渲染的 #1

zhishu520 opened this issue Nov 16, 2018 · 0 comments
Assignees

Comments

@zhishu520
Copy link
Owner

zhishu520 commented Nov 16, 2018

cocos2dx 是如何渲染的

先给个,大致的图,然后会详细讲解每个函数。


image

Application::run 底层循环

这个函数是平台相关的,不同平台下有不同的实现,它们所能保证的就是不停的调用Director::mainLoop

Director::mainLoop 主循环

mainloop函数做了三件事

  1. 自身数据创建和销毁
  2. 渲染场景
  3. 自动缓存池对象释放
void Director::mainLoop()
{

    // 游戏结束 销毁对象 Director::getInstance()->end(); 
    if (_purgeDirectorInNextLoop)
    {
        _purgeDirectorInNextLoop = false;
        purgeDirector();
    }
    // 重启整个游戏流程  Director::getInstance()->restart();
    else if (_restartDirectorInNextLoop)
    {
        _restartDirectorInNextLoop = false;
        restartDirector();
    }
    else if (! _invalid)
    {
        // 渲染场景
        drawScene();
     
        // 释放加到缓存池里的对象
        PoolManager::getInstance()->getCurrentPool()->clear();
    }
}

渲染函数 Director::drawScene

void Director::drawScene()
{
    if (_openGLView)
    {
        // glfwPollEvents() 轮询事件
        _openGLView->pollEvents();
    }

    // 清理上一帧渲染数据
    _renderer->clear();
    experimental::FrameBuffer::clearAllFBOs();

    //该节点的转换矩阵入栈
    pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    
    if (_runningScene)
    {
        //clear draw stats
        _renderer->clearDrawStats();
        
        // 添加渲染命令到 Renderer的 RenderQuene中去
        if(_openGLView)
            _openGLView->renderScene(_runningScene, _renderer);
    }
    
    // Renderer 绘制加入的所有 render command
    _renderer->render();

    // 该节点的转换矩阵出栈
    popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);

    // 交换缓冲区
    if (_openGLView)
    {
        _openGLView->swapBuffers();
    }
}

Node::visit 遍历节点

排序子节点,遍历子节点,调用Draw方法

void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags)
{

    if (!_visible)
    {
        return;
    }

    uint32_t flags = processParentFlags(parentTransform, parentFlags);

    _director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    _director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
    
    bool visibleByCamera = isVisitableByVisitingCamera();

    int i = 0;

    if(!_children.empty())
    {
        sortAllChildren();
        // 遍历子节点
        for(auto size = _children.size(); i < size; ++i)
        {
            auto node = _children.at(i);

            if (node && node->_localZOrder < 0)
                node->visit(renderer, _modelViewTransform, flags);
            else
                break;
        }
        // 调用draw方法
        if (visibleByCamera)
            this->draw(renderer, _modelViewTransform, flags);

        for(auto it=_children.cbegin()+i, itCend = _children.cend(); it != itCend; ++it)
            (*it)->visit(renderer, _modelViewTransform, flags);
    }
    else if (visibleByCamera)
    {
        this->draw(renderer, _modelViewTransform, flags);
    }

    _director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}

Sprite::draw 绘画

Spritedraw 函数并不是直接就调用opengl函数开始绘制,
而是创建 RenderCommand 并加入 RenderQuene 然后集中处理,
之所以这样是因为希望用一个独立的线程来处理和GPU的交互。

void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
    if (_texture == nullptr)
    {
        return;
    }
    
    {
        _trianglesCommand.init(_globalZOrder, 
                               _texture,
                               getGLProgramState(),
                               _blendFunc,
                               _polyInfo.triangles,
                               transform,
                               flags);

        renderer->addCommand(&_trianglesCommand);
    }
}
@zhishu520 zhishu520 changed the title cocos2dx 是如何工作的 cocos2dx 是如何渲染的 Nov 16, 2018
@zhishu520 zhishu520 self-assigned this Nov 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant