cocos creator-Assembler2D

fillBuffers 方法解读

/**
 * Assembler 意为装配器
 * 
 * fillBuffer()是简单的字节流拷贝,只关心数据长度,不关心数据内容
 *
 * fillBuffer()每帧都会被调用,是热点代码,需要关注效率。但是_renderData顶点数据不是每一帧都会更新
 */
fillBuffers (comp, renderer) {
        // 如果节点的世界坐标发生变化,重新从当前节点的世界坐标计算一次顶点数据
        if (renderer.worldMatDirty) {
            this.updateWorldVerts(comp);
        }

        // 获取准备好的顶点数据
        let renderData = this._renderData;

        // vData包含pos、uv、color数据
        // vData的类型是 Float32Array
        // 一张simple图片,vData数值如下(其实Label也是一样的,会作为一个图片来渲染,所以顶点信息也一样),长度为20(4个顶点数据,每个顶点数据包含posX,posY,uvX,uvY,color 共5个值,数组长度为 4*5 = 20)
        // 数组内容:   [10.180180549621582, 270, 0.0009765625, 0.001953125, NaN, 110.18018341064453, 270, 0.001953125, 0.001953125, NaN, 10.180180549621582, 370, 0.0009765625, 0.0009765625, NaN, 110.18018341064453, 370, 0.001953125, 0.0009765625, NaN]
        // 每个值的含义:posX                posY uvX           uvY         color
        // 4个顶点数据的顺序是 : 左下 -> 右下 ->左上 ->右上 四个点
        // 对于posX,posY 的值,是确确实实的该点在 cocos全局坐标系下的值。也就是 左下角为(0,0)
        // 我们可以posX 和posY 的值进行修改,那么就会得到了扭曲的变形的图片。那么我们其实可以通过定义顶点填充,来展示不同的效果。
        // 如果我们设置为slice type九宫格, 那么顶点数为 4*4  = 16个顶点。vData 的长度就是 16 * 5 = 80
        let vData = renderData.vDatas[0];
        
        // iData包含三角剖分后的顶点索引数据
        // iData类型为 Uint16Array
        // 测试一张图片的数值如下,一个图片,也就是一个四边形(有四个顶点)。需要拆分为两个三角形。那么需要六个索引号。
        // [0, 1, 2, 1, 3, 2]
        // 我们可以做如下测试,比如将[0, 1, 2, 1, 3, 2] 顶点索引改掉,那么会显示不同的裁剪结果显示出来。
        // 如果我们设置为slice type九宫格, 一个四边形为6的索引,那么9个四边形 顶点索引数为 9 * 6 = 54 
        let iData = renderData.iDatas[0];

        // 获取顶点缓存
        let buffer = this.getBuffer(renderer);
      
        // 获取当前节点的顶点数据对应最终buffer的偏移量
        // 可以简单理解为当前节点和其他同格式节点的数据,都将按顺序追加到这个大buffer里
        // 一张simple图片,verticesCount 就为 4 ,代表顶点数量。 indicesCount 就为6,代表顶点索引数量。
        // 如果我们设置为slice type九宫格的一张图片, verticesCount 就为 16 ,代表顶点数量。 indicesCount 54;
        // 目前还没搞懂tiled的顶点数量怎么计算的,就是特别多。
        let offsetInfo = buffer.request(this.verticesCount, this.indicesCount);

        // 填充顶点信息 fill vertices
        // vbuf 是最终产出的 顶点数据集合(多个图片)
        // vbuf 是一个5120长度的 Float32Array,默认里面全部值都是0。若是普通的图片,那么每20个长度,就刚好保存一个完整的四边形pos,uv,color数据
        // 比如我们有两个图片,那么vbuf index 0~19 表示第一个图的顶点数据。20~39表示第二个图的顶点数据
        // 这里是每个图片,获取到的自己在数组中的偏移量,然后偏移量开始将新的顶点数据填进去(刷新或填入数据)
        let vertexOffset = offsetInfo.byteOffset >> 2,
        vbuf = buffer._vData;
        
        // 将准备好的vData拷贝到vbuf:VetexBuffer里。
        if (vData.length + vertexOffset > vbuf.length) {
            // 这里会判断如果buffer装不下了,vData会被截断一部分。
            // 通常不会出现装不下这种情况,因为buffer.request中会分配足够大的空间;如果出现,则当前组件只能被渲染一部分
            vbuf.set(vData.subarray(0, vbuf.length - vertexOffset), vertexOffset);
        } else {
            // 直接拷覆盖进去,vertexOffset为偏移值(可以认为是数组的index,填充长度当然就是 vData的长度)。
            vbuf.set(vData, vertexOffset);
        }

        // 将准备好的iData拷贝到IndiceBuffer里
        // ibuf 是最终产出的 顶点数据索引集合
        // ibuf 是一个1536长度的 Uint16Array,默认里面全部值都是0。若是普通的图片,那么每6个长度,就刚好保存一个完整的四边形顶点索引数据
        // 比如我们有两个图片,那么ibuf index 0~5 表示第一个图的顶点索引数据。6~11表示第二个图的顶点索引数据
        // 注意存储的值有一点不一样。比如每张图的顶点索引肯定是 0 1 2 3 ,但是最终填入ibuf的时候,是做了处理的:
        // 第一个图的索引为 0~ 3  ,第二个图的索引为 4 ~ 7 。按此规律做偏移的。
        let ibuf = buffer._iData,
            indiceOffset = offsetInfo.indiceOffset,
            vertexId = offsetInfo.vertexOffset;
        for (let i = 0, l = iData.length; i < l; i++) {
            ibuf[indiceOffset++] = vertexId + iData[i];
        }
    }

顶点数据格式

    var vfmtPosUvColor = new gfx.VertexFormat([
        // 节点的世界坐标,占2个float32
        { name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
      
        // 节点的纹理uv坐标,占2个float32
        // 如果节点使用了独立的纹理(未合图),这里的uv值通常是0或1
        // 合图后的纹理,这里的uv对应其在图集里的相对位置,取值范围在[0,1)内
        { name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
      
        // 节点颜色值,cc.Sprite组件上可以设置。占4个uint8 = 1个float32
        { name: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_UINT8, num: 4, normalize: true },
    ]);

参考

GT大佬   https://forum.cocos.org/t/demo/95087
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值