cocos渲染时如何自动合并DrawCall

降低drawcall对于游戏性能至关重要,尤其是在移动设备上,它能带来更低的发热和更高帧率。cocos2d-x的渲染机制通过RenderCommand和RenderQueue来管理显示对象,虽然支持drawcall合并,但默认并未启用。渲染流程中,RenderQueue的排序仅针对部分对象,并在processRenderCommand中执行。关键的DrawCall合并发生在drawBatchedTriangles函数,当检测到不同纹理时才会触发渲染,以此实现DrawCall的合并。
摘要由CSDN通过智能技术生成

减少drawcall是游戏开发过程中的重要优化手段,在移动设备上更低的drawcall意味着更低的发热和更高的系统流畅度。

cocos显示对象把渲染数据放在RenderCommand中,然后在Renderer类render函数中统一进行渲染。这么设计是为了对渲染进行统一的管理,包括可以进行合并drawcall,还可以用独立的线程来进行渲染,但是cocos目前并没有这么做。

cocos渲染数据的组织结构是,显示元素->RenderCommand->RenderQueue->_renderGroups。cocos默认使用RenderGrop[0]进行渲染,一些需要独立渲染的对象会开启新的RenderGroup,例如ClippingNode。

void Renderer::render()
{
    _isRendering = true;
    if (_glViewAssigned)
    {
        //对所有randerqueue进行排序
        for (auto &renderqueue : _renderGroups)
        {
            renderqueue.sort();
        }
        //默认渲染RenderGrop[0]
        visitRenderQueue(_renderGroups[0]);
    }
    //清空所有渲染数据
    clean();
    _isRendering = false;
}

RanderQueue的排序过程非常简单,只对GlobalZOrder不为0的和透明的3D对象才进行渲染排序。

void RenderQueue::sort()
{
    // Don't sort _queue0, it already comes sorted
    std::sort(std::begin(_commands[QUEUE_GROUP::TRANSPARENT_3D]), std::end(_commands[QUEUE_GROUP::TRANSPARENT_3D]), compare3DCommand);
    std::sort(std::begin(_commands[QUEUE_GROUP::GLOBALZ_NEG]), std::end(_commands[QUEUE_GROUP::GLOBALZ_NEG]), compareRenderCommand);
    std::sort(std::begin(_commands[QUEUE_GROUP::GLOBALZ_POS]), std::end(_commands[QUEUE_GROUP::GLOBALZ_POS]), compareRenderCommand);
}

visitRenderQueue函数按照指定的顺序对各种RenderQueue中的各个RenderCommand统一进行渲染,渲染单个RenderCommand的函数是processRenderCommand。

void Renderer::visitRenderQueue(RenderQueue& queue)
{
    //保存渲染前的opengl状态
    queue.saveRenderState();
    
    //渲染GlobalZ小于0的RenderQueque
    const auto& zNegQueue = queue.getSubQueue(RenderQueue::QUEUE_GROUP::GLOBALZ_NEG);
    if (zNegQueue.size() > 0)
    {
        //设置opengl状态
        ......
        
        for (auto it = zNegQueue.cbegin(); it != zNegQueue.cend(); ++it)
        {
            processRenderCommand(*it);
        }
        flush();
    }
    
    //渲染不透明的3D对象的RenderQueque
    const auto& opaqueQueue = queue.getSubQueue(RenderQueue::QUEUE_GROUP::OPAQU
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值