cocos2dx源码分析:渲染指令RenderCommand

来源:互联网 发布:python mysql 回滚 编辑:程序博客网 时间:2024/05/16 14:15

cocos2dx中,每一个可渲染的节点都可以产生一个渲染指令RenderCommand,一共存在7中类型的渲染指令

    /**Enum the type of render command. */    enum class Type    {        /** Reserved type.*/        UNKNOWN_COMMAND,        /** Quad command, used for draw quad.*/        /**这个渲染指令已经废弃了?在代码中转换成TRIANGLES_COMMAND了*/        QUAD_COMMAND,        /**Custom command, used for calling callback for rendering.*/        CUSTOM_COMMAND,        /**Batch command, used for draw batches in texture atlas.*/        BATCH_COMMAND,        /**Group command, which can group command in a tree hierarchy.*/        GROUP_COMMAND,        /**Mesh command, used to draw 3D meshes.*/        MESH_COMMAND,        /**Primitive command, used to draw primitives such as lines, points and triangles.*/        PRIMITIVE_COMMAND,        /**Triangles command, used to draw triangles.*/        TRIANGLES_COMMAND    };

当从渲染队列中取出渲染指令后,就开始处理渲染指令,根据指令不同,处理方式也不同,指令处理的过程也就是渲染的过程

void Renderer::processRenderCommand(RenderCommand* command){    /*获取指令类型*/    auto commandType = command->getType();    /*根据指令类型不同,做不同的处理。这里为什么不用switch case?*/    if( RenderCommand::Type::TRIANGLES_COMMAND == commandType)    {        /*TRIANGLES_COMMAND渲染类型的指令可以进行合并,但是不能和3D类型渲染指令进行合并,所以如果有未完成的3d渲染指令,则先渲染3d指令*/        // flush other queues        flush3D();        auto cmd = static_cast<TrianglesCommand*>(command);        /*如果超过了可合并的最大限制,则先渲染一次*/        // flush own queue when buffer is full        if(_filledVertex + cmd->getVertexCount() > VBO_SIZE || _filledIndex + cmd->getIndexCount() > INDEX_VBO_SIZE)        {            CCASSERT(cmd->getVertexCount()>= 0 && cmd->getVertexCount() < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command");            CCASSERT(cmd->getIndexCount()>= 0 && cmd->getIndexCount() < INDEX_VBO_SIZE, "VBO for index is not big enough, please break the data down or use customized render command");            drawBatchedTriangles();        }        /*先不进行渲染,将渲染指令进行合并,这是性能优化处理*/        // queue it        _queuedTriangleCommands.push_back(cmd);        _filledIndex += cmd->getIndexCount();        _filledVertex += cmd->getVertexCount();    }    else if (RenderCommand::Type::MESH_COMMAND == commandType)    {        /*MESH_COMMAND渲染指令也可以进行一定的优化,但是肯定不能和2d渲染指令合并,所以如果有2d指令则先渲染完2d指令*/        flush2D();        auto cmd = static_cast<MeshCommand*>(command);        /*判断是否可以进行batchDraw,没有材质时才能进行共享vao的方式优化*/        if (cmd->isSkipBatching() || _lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID())        {            flush3D();            if(cmd->isSkipBatching())            {                // XXX: execute() will call bind() and unbind()                // but unbind() shouldn't be call if the next command is a MESH_COMMAND with Material.                // Once most of cocos2d-x moves to Pass/StateBlock, only bind() should be used.                cmd->execute();            }            else            {                cmd->preBatchDraw();                cmd->batchDraw();                _lastBatchedMeshCommand = cmd;            }        }        else        {            cmd->batchDraw();        }    }    else if(RenderCommand::Type::GROUP_COMMAND == commandType)    {        /*渲染组,也拥有一个渲染队列_renderGroups[renderQueueID],递归进行渲染*/        flush();        int renderQueueID = ((GroupCommand*) command)->getRenderQueueID();        visitRenderQueue(_renderGroups[renderQueueID]);    }    else if(RenderCommand::Type::CUSTOM_COMMAND == commandType)    {        /*自定义渲染指令*/        flush();        auto cmd = static_cast<CustomCommand*>(command);        cmd->execute();    }    else if(RenderCommand::Type::BATCH_COMMAND == commandType)    {        /*批次渲染*/        flush();        auto cmd = static_cast<BatchCommand*>(command);        cmd->execute();    }    else if(RenderCommand::Type::PRIMITIVE_COMMAND == commandType)    {        /*基本图元渲染*/        flush();        auto cmd = static_cast<PrimitiveCommand*>(command);        cmd->execute();    }    else    {        CCLOGERROR("Unknown commands in renderQueue");    }}
0 0