cocos2d-x渲染架构

        3.0之前是visit后就draw,而draw是真正的OpenGL操作。也就是说,每访问一个对象,先计算节点的渲染数据,然后马上渲染。因为节点是按树形结构组织的,如果两个父节点p1和p2的深度分别是10和20,c1是p1的子节点,其深度是30,c2是p2的子节点,其深度是5。则渲染顺序是p1、c1、c2、p2。

        3.0也是在visit后就draw,但是draw并不进行OpenGL操作。3.0抽象了一个RenderCommand,在draw的时候其实是生成一个渲染命令,渲染命令其实就是对渲染所需要的数据的封装。RenderCommand作为基类,只包含了两个成员,一个是命令类型_type,这个很必要,正是靠这个来获取子类对象的具体类型的,这里没有用运行时类型,应该是考虑到效率;另一个是z深度_globalOrder,这个也很必要,渲染的时候必然要对节点排序,而z序是唯一的依据。

        3.0包含了以下几个RenderCommand的子类:

        1,CustomCommand:

        顾名思义,是客户自定义的。它没有过多的数据,只有一个std::function<>类型成员func,这个是在节点draw创建CustomCommand的时候传入的参数,而在真正渲染的时候调用的正是这个函数。比如Label,它的draw函数体为:

void Label::draw()

{

    _customCommand.init(_globalOrder);

   _customCommand.func=CC_CALLBACK_0(Label::onDraw, this,transform,transformUpdated);

   render->addCommand(&_customCommand);

}

        可见,真正的渲染是在onDraw回调函数中。onDraw的操作和此前版本的draw函数相差不大,都是设置混合方式,使用GLProgram,更新shader的变换矩阵等shader所用到的uniform变量,更新子节点位置(注:因为是批量渲染,这个和此前的CCSpriteBatchNode很相近),调用TextureAtlas::drawQuads();

使用CustomCommand还有Layer,LableAtlas,LabelBMFont,此外还有RenderTexture,这个比较特殊,下面会说。

        注:估计作者是对所有不太好抽象的渲染节点,就干脆做了一个CustomCommand。

        2,QuadCommand:

        和CustomCommand不同,这个类包含了很多属性:纹理_textureID,Program _shader,混合函数_blendType,定点数据_quad,模型视图矩阵_mv,还有一个材质属性_materialID。材质是一种抽象,当且仅当纹理、shader、混合函数都相等的时候,材质才相等。抽象材质的好处是,如果两个对象渲染顺序相邻,且材质相同,就可以使用批量渲染。当然,两个对象必须都使用QuadCommand,因为只有QuadCommand才有材质属性。

        QuadCommand的最终渲染操作放在了Render::drawBatchQuads中,其输入是一个所有QuadCommand的顶点排序后组装成的VBO,一个是这些定点对应的QuadCommand命令数组。查看这个函数也的确是当材质发生变化的时候才进行一次渲染,可见它是把相同材质的放到了一起批量渲染。

        值得一提的是3.0主要是对QuadCommand进行了优化,实际上游戏中也大多数是这种情况。在Render::render()函数中,如果当前是QuadCommand,则顶点和Command放入数组,如果是其它,则先渲染此前的QuadCommand数组,然后再渲染当前命令。

        使用QuadCommand命令的类有Sprite,ParticleSystemQuad,而Sprite应该是游戏中最常用的类,所以3.0的优化还是很有意义的。

        3,BatchCommand:

看名字就知道,BatchCommand是CCSpriteBatchNode的改进,而事实上,也的确是CCSpriteBatchNode和CCPaticleBatchNode使用了BatchCommand。BatchCommand的属性和QuadCommand很相似,不过没有了顶点数据_quad,变成了_textureAtlas,其渲染函数也和此前的差别不大,都是材质三剑客(shader, texutre, blend),然后是更新shader的uniform变量,最后调用_textureAtlas->drawQuads(),和Label的渲染很相似,只不过Label的更新子节点的顶点放在了渲染函数中,而BatchCommdand放在了节点的visit中,具体可参加源代码。

        4,GroupCommand:

        这是一个Command组合,但是GroupCommand只有一个属性_renderQueueID,而GroupCommand的所有子Command其实存放在Render中。GroupCommand像其它Command一样,存放在同一个队列中,遍历的时候,如果是GroupCommand,则获取其_renderQueueID,然后根据_renderQueueID找到指定的RenderCommand队列,进而渲染这个队列。可见,在Render中,可以包含多个Command队列,一些是根节点队列(没有父Command),其它的是指定ID的GroupCommand的子命令队列。

        使用GroupCommand的主要有RenderTexture,因为RenderTexture包含了两次分隔的渲染操作,一次是begin(),一次是end()。

        引擎只提供了四种RenderCommand,用的最广泛的是QuadCommand。这些远远不够,比如没有支持多重纹理。

        如果我想在Sprite上加入一个多重纹理的功能,应该怎么办?是扩展QuadCommand还重新创建一个新的RenderCommand?

 

转载出处:http://blog.csdn.net/zhangshuliai/article/details/25740343

参考:http://blog.csdn.net/bill_man/article/category/1060940

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值