8.【cocos2d-x 源码分析】:渲染部分的详细分析(下)

对应源码位置:cocos2d-x-3.3\cocos\render*

从 RenderQueue说起
//渲染 队列
class RenderQueue {
   
public:
    void push_back(RenderCommand* command);
    ssize_t size() const;
    //按照 z值进行排序
    void sort();
    RenderCommand* operator[](ssize_t index) const;
    void clear();

protected:
	//用于存储 渲染命令的 三个队列
    std::vector<RenderCommand*> _queueNegZ;
    std::vector<RenderCommand*> _queue0;
    std::vector<RenderCommand*> _queuePosZ;
};
//用于存储 渲染有透明性质的对象命令 
//render queue for transparency object, NOTE that the _globalOrder of RenderCommand is the distance to the camera when added to the transparent queue
class TransparentRenderQueue {
   
public:
    void push_back(RenderCommand* command);
    ssize_t size() const
    {
   
        return _queueCmd.size();
    }
    void sort();
    RenderCommand* operator[](ssize_t index) const;
    void clear();
    
protected:
    std::vector<RenderCommand*> _queueCmd;
};
//整个渲染队列作为 一个元素
struct RenderStackElement
{
   
    int renderQueueID;
    ssize_t currentIndex;
};
详细分析 Renderer类

下面是 Renderer的主要数据部分,后面详细介绍它的函数及实现。

class CC_DLL Renderer
{
   
public:
	//VBO的属性数量
    static const int VBO_SIZE = 65536;
    //索引buffer数据量
    static const int INDEX_VBO_SIZE = VBO_SIZE * 6 / 4;
    
    static const int BATCH_QUADCOMMAND_RESEVER_SIZE = 64;
    static const int MATERIAL_ID_DO_NOT_BATCH = 0;
    
    Renderer();
    ~Renderer();
     //保存 各个GroupId的堆栈 注意是 栈的数据结构
    std::stack<int> _commandGroupStack;
    //渲染队列的队列
    std::vector<RenderQueue> _renderGroups;
    //透明对象渲染的处理队列
    TransparentRenderQueue   _transparentRenderGroups; //transparency objects
	//最近一次 使用的 材质的ID
    uint32_t _lastMaterialID;

    MeshCommand*  _lastBatchedMeshCommand;
    //批次 处理的 三角形 和 四边形绘制命令
    std::vector<TrianglesCommand*> _batchedCommands;
    std::vector<QuadCommand*> _batchQuadCommands;
    
    //for TrianglesCommand
    V3F_C4B_T2F _verts[VBO_SIZE];
    GLushort _indices[INDEX_VBO_SIZE];
    GLuint _buffersVAO;
    GLuint _buffersVBO[2]; //0: vertex  1: indices
	//这一次 填充的数据 数目
	//分别是 顶点数 以及 索引数目
    int _filledVertex;
    int _filledIndex;
    
    //for QuadCommand
    V3F_C4B_T2F _quadVerts[VBO_SIZE];
    GLushort _quadIndices[INDEX_VBO_SIZE];
    GLuint _quadVAO;
    GLuint _quadbuffersVBO[2]; //0: vertex  1: indices
    //四边形 数目
    int _numberQuads;
    
    bool _glViewAssigned;

    // stats
    ssize_t _drawnBatches;
    ssize_t _drawnVertices;
    //the flag for checking whether renderer is rendering
    bool _isRendering;
    
    GroupCommandManager* _groupCommandManager; 
};

下面开始具体函数的 分析。

//构造函数
Renderer::Renderer()
:_lastMaterialID(0)
,_lastBatchedMeshCommand(nullptr)
,_filledVertex(0)
,_filledIndex(0)
,_numberQuads(0)
,_glViewAssigned(false)
,_isRendering(false)
#if CC_ENABLE_CACHE_TEXTURE_DATA
,_cacheTextureListener(nullptr)
#endif
{
   	
	//GroupCommandManager这个类 主要是为 GroupCommand类 分配和管理 RenderQueue
    _groupCommandManager = new (std::nothrow) GroupCommandManager();  
    //先将 默认渲染队列 入栈  
    _commandGroupStack.push(DEFAULT_RENDER_QUEUE);
    RenderQueue defaultRenderQueue;
    //默认的渲染队列 位于首部
    _renderGroups.push_back(defaultRenderQueue);
    _batchedCommands.reserve(BATCH_QUADCOMMAND_RESEVER_SIZE);
}
void Renderer::initGLView()
{
   
#if CC_ENABLE_CACHE_TEXTURE_DATA
    _cacheTextureListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom* event){
   
        /** listen the event that renderer was recreated on Android/WP8 */
        this->setupBuffer();
    });
    Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_cacheTextureListener, -1);
#endif
    
    //setup index data for quads
	//很容易 理解 一个四边形 其实就是 就是由两个三角形
	//逆时针 编号为 0 1 3 2 
	//那么 可以到的 0 1 2   3 2 1这样的索引顺序
    for( int i=0; i < VBO_SIZE/4; i++)
    {
   
        _quadIndices[i*6+0] = (GLushort) (i*4+0);
        _quadIndices[i*6+1] = (GLushort) (i*4+1);
        _quadIndices[i*6+2] = (GLushort) (i*4+2);
        _quadIndices[i*6+3] = (GLushort) (i*4+3);
        _quadIndices[i*6+4] = (GLushort) (i*4+2);
        _quadIndices[i*6+5] = (GLushort) (i*4+1);
    }
    //见下面 具体分析 这里是建立buffer对象
    setupBuffer();
    _glViewAssigned = true;
}

void Renderer::setupBuffer()
{
   
	//看是否支持 VAO
    if(Configuration::getInstance()->supportsShareableVAO())
    {
   
        setupVBOAndVAO();
    }
    else
    {
   
        setupVBO();
    }
}

void Renderer::setupVBOAndVAO()
{
   
    //generate vbo and vao for trianglesCommand
    //先生成 三角形的VAO
    glGenVertexArrays(1, &_buffersVAO);
    GL::bindVAO(_buffersVAO);
	//生成两个buffer 对象 分别为 VBO IBO
    glGenBuffers(2, &_buffersVBO[0]);
	//传输 整个数据块
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(_verts[0]) * VBO_SIZE, _verts, GL_DYNAMIC_DRAW);

    // vertices 配置 顶点数据的位置
    glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid*) offsetof( V3F_C4B_T2F, vertices));

    // colors 配置 颜色数据的位置
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值