cocos2dx的渲染流程(源码走读)

前端之家收集整理的这篇文章主要介绍了cocos2dx的渲染流程(源码走读)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

注意:
为了流程更加清晰,以下代码片段都是删除了其他无关的代码,只保留了与流程相关的函数调用

1 main 中调用 run:

int main() {
    AppDelegate app;
    return Application::getInstance()->run();
}
@H_301_14@2 Application 中调用 mainLoop :
int Application::run(){
    director->mainLoop();
}

3 mainLoop 中调用 drawScene :

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

mainLoop 主循环, 在Application中是个纯虚函数,在子类 DisplayLinkDirector 中实现。

4 drawScene 中调用 render 和 visit :

void Director::drawScene() {
    _runningScene->render(_renderer);
    _notificationNode->visit(_renderer,Mat4::IDENTITY,0);
}

drawScene 是绘制函数

5 render 和 visit :

5.1 render

void Scene::render(Renderer* renderer) {
    renderer->render();
}

void Renderer::render() {
    //1. Sort render commands based on ID
    for (auto &renderqueue : _renderGroups) {
        renderqueue.sort();
    }
    visitRenderQueue(_renderGroups[0]);
}

render 中调用 visitRenderQueue 根据不同的渲染队列类型,进行渲染。

void Renderer::visitRenderQueue(const RenderQueue& queue) {
    const auto& zNegQueue = queue.getSubQueue(RenderQueue::QUEUE_GROUP::GLOBALZ_NEG);
    if (zNegQueue.size() > 0) {
        for (auto it = zNegQueue.cbegin(); it != zNegQueue.cend(); ++it) {
            processRenderCommand(*it);
        }
    }
}

除了 GLOBALZ_NEG 外还有 OPAQUE_3D, TRANSPARENT_3D, GLOBALZ_ZERO, GLOBALZ_POS 共五类,流程类似。

void Renderer::processRenderCommand(RenderCommand* command) {
    auto commandType = command->getType();
    if( RenderCommand::Type::TRIANGLES_COMMAND == commandType) {
        drawBatchedTriangles();
    } else if ( RenderCommand::Type::QUAD_COMMAND == commandType ) {
        drawBatchedQuads();
    } else if (RenderCommand::Type::MESH_COMMAND == commandType) {
        auto cmd = static_cast<MeshCommand*>(command);
        cmd->execute();
        cmd->batchDraw();
    } else if(RenderCommand::Type::GROUP_COMMAND == commandType) {
        visitRenderQueue(_renderGroups[renderQueueID]);
    } else if(RenderCommand::Type::CUSTOM_COMMAND == commandType) {
        auto cmd = static_cast<CustomCommand*>(command);
        cmd->execute();
    } else if(RenderCommand::Type::BATCH_COMMAND == commandType) {
        auto cmd = static_cast<BatchCommand*>(command);
        cmd->execute();
    } else if(RenderCommand::Type::PRIMITIVE_COMMAND == commandType) {
        auto cmd = static_cast<PrimitiveCommand*>(command);
        cmd->execute();
    } else {
        CCLOGERROR("Unknown commands in renderQueue");
    }
}

5.2 visit

void Node::visit(Renderer* renderer,const Mat4 &parentTransform,uint32_t parentFlags) {
    this->draw(renderer,_modelViewTransform,flags);
}

在 visit 中会调用各个节点 draw 函数,draw 由 Node 的子类实现,如:

void DrawNode::draw(Renderer *renderer,const Mat4 &transform,uint32_t flags) {
    renderer->addCommand(&_customCommand);
}

void Sprite::draw(Renderer *renderer,uint32_t flags) {
    renderer->addCommand(&_trianglesCommand);
}

void Label::draw(Renderer *renderer,uint32_t flags) {
    renderer->addCommand(&_customCommand);
}

draw 函数向 RenderQueue 中添加 RenderCommand。

void Renderer::addCommand(RenderCommand* command) {
    int renderQueue =_commandGroupStack.top();
    addCommand(command,renderQueue);
}

void Renderer::addCommand(RenderCommand* command,int renderQueue) {
    _renderGroups[renderQueue].push_back(command);
}

猜你在找的Cocos2d-x相关文章