cocos2dx源码分析:渲染指令收集
来源:互联网 发布:淘宝垃圾客服 编辑:程序博客网 时间:2024/05/16 17:38
cocos2dx中渲染分两步进行,第一步收集渲染指令,第二步完成渲染
渲染起始于场景的render函数
void Scene::render(Renderer* renderer){ auto director = Director::getInstance(); Camera* defaultCamera = nullptr; const auto& transform = getNodeToParentTransform(); /*对于场景中的每一个相机都要走一遍渲染流程*/ for (const auto& camera : getCameras()) { if (!camera->isVisible()) continue; Camera::_visitingCamera = camera; if (Camera::_visitingCamera->getCameraFlag() == CameraFlag::DEFAULT) { defaultCamera = Camera::_visitingCamera; } /*使相机生效*/ director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, Camera::_visitingCamera->getViewProjectionMatrix()); camera->apply(); //clear background with max depth camera->clearBackground(); //visit the scene /*遍历场景树,收集渲染指令*/ visit(renderer, transform, 0);#if CC_USE_NAVMESH if (_navMesh && _navMeshDebugCamera == camera) { _navMesh->debugDraw(renderer); }#endif /*渲染*/ renderer->render(); director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); }#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION if (_physics3DWorld && _physics3DWorld->isDebugDrawEnabled()) { director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, _physics3dDebugCamera != nullptr ? _physics3dDebugCamera->getViewProjectionMatrix() : defaultCamera->getViewProjectionMatrix()); _physics3DWorld->debugDraw(renderer); renderer->render(); director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); }#endif Camera::_visitingCamera = nullptr; experimental::FrameBuffer::applyDefaultFBO();}
遍历场景树,收集渲染指令的过程是一个递归的过程
void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags){ /*如果物体不可见,就不需要渲染,直接返回*/ // quick return if not visible. children won't be drawn. if (!_visible) { return; } uint32_t flags = processParentFlags(parentTransform, parentFlags); // IMPORTANT: // To ease the migration to v3.0, we still support the Mat4 stack, // but it is deprecated and your code should not rely on it /*入栈变换矩阵,相机矩阵已经入栈,这里只需入栈mv矩阵*/ _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()) { /*使用zorder排序孩子节点*/ sortAllChildren(); /*先收集zorder<0的孩子节点的渲染指令*/ // draw children zOrder < 0 for( ; i < _children.size(); i++ ) { auto node = _children.at(i); if (node && node->_localZOrder < 0) node->visit(renderer, _modelViewTransform, flags); else break; } // self draw /*收集自己的渲染指令*/ if (visibleByCamera) this->draw(renderer, _modelViewTransform, flags); /*收集zorder>0的孩子节点的渲染指令*/ for(auto it=_children.cbegin()+i; it != _children.cend(); ++it) (*it)->visit(renderer, _modelViewTransform, flags); } else if (visibleByCamera) { /*如果没有孩子节点,则只收集自己的渲染指令*/ this->draw(renderer, _modelViewTransform, flags); } /*恢复变换矩阵*/ _director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); // FIX ME: Why need to set _orderOfArrival to 0?? // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920 // reset for next frame // _orderOfArrival = 0;}
Node中使用draw收集自己的渲染指令,一个继承自Node的对象如果可渲染就需要重写这个函数,下面是Sprite的draw实现
void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags){ /*sprite必须有texture才能可渲染*/ if (_texture == nullptr) { return; }#if CC_USE_CULLING /*可见性剔除*/ // Don't do calculate the culling if the transform was not updated auto visitingCamera = Camera::getVisitingCamera(); auto defaultCamera = Camera::getDefaultCamera(); if (visitingCamera == defaultCamera) { _insideBounds = ((flags & FLAGS_TRANSFORM_DIRTY)|| visitingCamera->isViewProjectionUpdated()) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds; } else { _insideBounds = renderer->checkVisibility(transform, _contentSize); } if(_insideBounds)#endif { /*创建自己的渲染指令,并发送到渲染器中。cocos2dx中有多种渲染指令,sprite使用的渲染指令是TrianglesCommand*/ _trianglesCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, _polyInfo.triangles, transform, flags); renderer->addCommand(&_trianglesCommand);#if CC_SPRITE_DEBUG_DRAW _debugDrawNode->clear(); auto count = _polyInfo.triangles.indexCount/3; auto indices = _polyInfo.triangles.indices; auto verts = _polyInfo.triangles.verts; for(ssize_t i = 0; i < count; i++) { //draw 3 lines Vec3 from =verts[indices[i*3]].vertices; Vec3 to = verts[indices[i*3+1]].vertices; _debugDrawNode->drawLine(Vec2(from.x, from.y), Vec2(to.x,to.y), Color4F::WHITE); from =verts[indices[i*3+1]].vertices; to = verts[indices[i*3+2]].vertices; _debugDrawNode->drawLine(Vec2(from.x, from.y), Vec2(to.x,to.y), Color4F::WHITE); from =verts[indices[i*3+2]].vertices; to = verts[indices[i*3]].vertices; _debugDrawNode->drawLine(Vec2(from.x, from.y), Vec2(to.x,to.y), Color4F::WHITE); }#endif //CC_SPRITE_DEBUG_DRAW }}
至此渲染指令收集完毕,下一步就是执行renderer->render(),完成渲染
0 0
- cocos2dx源码分析:渲染指令收集
- cocos2dx源码分析:渲染指令RenderCommand
- cocos2dx源码分析:组渲染指令GroupCommand
- cocos2dx源码分析:渲染指令TrianglesCommand
- cocos2dx源码分析:渲染指令BatchCommand
- cocos2dx源码分析:渲染队列RenderQueue
- cocos2dx源码分析:TrianglesCommand的合并渲染
- cocos2dx渲染指令CustomCommand的使用
- cocos2dx CCScrollView 源码分析
- cocos2dx-CCControlButton源码分析
- cocos2dx源码分析:ActionManager
- cocos2dx的渲染流程(源码走读)
- cocos2dx 3.0 研究(4)渲染分析
- cocos2dx 2.x 每帧渲染分析
- vue源码分析:渲染篇
- LayoutInflate渲染view源码分析
- [cocos2dx]TestCpp框架源码分析
- cocos2dx 源码分析之 CCPoolManager
- 295. Find Median from Data Stream
- 第139课: Spark面试经典系列之数据倾斜解决之对于两个RDD数据量都很大且倾斜的Key特别多如何解决?
- hdu 1212 Big Number(大数取模)
- [git] warning: LF will be replaced by CRLF | fatal: CRLF would be replaced by LF
- 记一下要学的内容
- cocos2dx源码分析:渲染指令收集
- BindService() 绑定方式开启服务
- [莫比乌斯反演] BZOJ 2820 YY的GCD
- Activity中的Intent对象
- pread,pwrite,read,write区别
- 酷酷头像技术支持
- 腾讯课堂的学习开始了!
- linux指令查看tomcat日志
- Android Loader解析