Cocos2dx v3.x渲染管线流程

栏目: IOS · 发布时间: 6年前

内容简介:cocos2dx v3渲染流程做了很大的升级,具体的提升和新的特性大概有以下几点:大概的流程就是当遍历节点的时候,渲染器将当前节点的RenderCommand压入渲染队列,渲染线程基于Key对队列里面的RenderCommand进行排序,调用实际的渲染API,主线程继续进行场景的遍历和非渲染相关的工作。

cocos2dx v3渲染流程做了很大的升级,具体的提升和新的特性大概有以下几点:

  • 场景的遍历和渲染分离开来,在遍历节点的时候会把绘图命令放入一个队列,并不会实际调用OpenGL渲染API;
  • 视锥体几何裁剪,摄像机视野外的对象将会自动从当前帧中移除,并不会进行渲染;
  • 执行OpenGL绘图命令的将会移动到一个独立的线程,更好地利用现在移动平台的多核CPU;
  • 自动合并批次
  • 基于节点的定制化渲染

Cocos2dx v3.x渲染管线流程 Cocos2dx v3.x渲染管线流程 Cocos2dx v3.x渲染管线流程

大概的流程就是当遍历节点的时候,渲染器将当前节点的RenderCommand压入渲染队列,渲染线程基于Key对队列里面的RenderCommand进行排序,调用实际的渲染API,主线程继续进行场景的遍历和非渲染相关的工作。

不过关于RenderCommand的排序,在实际的代码中并没有看到有对应的基于Key的排序,只是简单地根据GlobalOrder进行排序。

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

材质id的生成部分采用了类似OpenSceneGraph的方案,根据贴图id、混合参数以及shader生成Hash值,并且在绘制的时候通过比较这个材质的id进行合并批次的操作。

void TrianglesCommand::generateMaterialID()
{
    // glProgramState is hashed because it contains:
    //  *  uniforms/values
    //  *  glProgram
    //
    // we safely can when the same glProgramState is being used then they share those states
    // if they don't have the same glProgramState, they might still have the same
    // uniforms/values and glProgram, but it would be too expensive to check the uniforms.
    struct {
        GLuint textureId;
        GLenum blendSrc;
        GLenum blendDst;
        void* glProgramState;
    } hashMe;

    hashMe.textureId = _textureID;
    hashMe.blendSrc = _blendType.src;
    hashMe.blendDst = _blendType.dst;
    hashMe.glProgramState = _glProgramState;
    _materialID = XXH32((const void*)&hashMe, sizeof(hashMe), 0);
}

自动合并批次的操作也比较简单,比较两个渲染指令的MaterialID,如果连续两个渲染指令的MaterialID相同,则不重复进行材质的提交,只提交顶点数据。所以如果不连续的话,并不能减少draw call。

const auto& cmd = *it;
auto currentMaterialID = cmd->getMaterialID();
const bool batchable = !cmd->isSkipBatching();

fillVerticesAndIndices(cmd);

// in the same batch ?
if (batchable && (prevMaterialID == currentMaterialID || firstCommand))
{
    CC_ASSERT(firstCommand || _triBatchesToDraw[batchesTotal].cmd->getMaterialID() == cmd->getMaterialID() && "argh... error in logic");
    _triBatchesToDraw[batchesTotal].indicesToDraw += cmd->getIndexCount();
    _triBatchesToDraw[batchesTotal].cmd = cmd;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Masterminds of Programming

Masterminds of Programming

Federico Biancuzzi、Chromatic / O'Reilly Media / 2009-03-27 / USD 39.99

Description Masterminds of Programming features exclusive interviews with the creators of several historic and highly influential programming languages. Think along with Adin D. Falkoff (APL), Jame......一起来看看 《Masterminds of Programming》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具