注意:
@H_502_5@
为了流程更加清晰,以下代码片段都是删除了其他无关的代码,只保留了与流程相关的函数调用。1 main 中调用 run:
int main() { AppDelegate app; return Application::getInstance()->run(); }
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); }