Open zhishu520 opened 6 years ago
先给个,大致的图,然后会详细讲解每个函数。
这个函数是平台相关的,不同平台下有不同的实现,它们所能保证的就是不停的调用Director::mainLoop
Director::mainLoop
mainloop函数做了三件事
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(); } }
排序子节点,遍历子节点,调用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 函数并不是直接就调用opengl函数开始绘制, 而是创建 RenderCommand 并加入 RenderQuene 然后集中处理, 之所以这样是因为希望用一个独立的线程来处理和GPU的交互。
Sprite
draw
RenderCommand
RenderQuene
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); } }
cocos2dx 是如何渲染的
先给个,大致的图,然后会详细讲解每个函数。
Application::run 底层循环
这个函数是平台相关的,不同平台下有不同的实现,它们所能保证的就是不停的调用
Director::mainLoop
Director::mainLoop 主循环
mainloop函数做了三件事
渲染函数
Director::drawScene
Node::visit 遍历节点
排序子节点,遍历子节点,调用Draw方法
Sprite::draw 绘画
Sprite
的draw
函数并不是直接就调用opengl函数开始绘制, 而是创建RenderCommand
并加入RenderQuene
然后集中处理, 之所以这样是因为希望用一个独立的线程来处理和GPU的交互。