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