[√]MeshBuffer和VertexFormat

本文章简单分析了cocos creator的组装提交渲染数据。

js 复制代码
var vfmtPosUvColor = new gfx.VertexFormat([
    { name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
    { name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
    { name: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_UINT8, num: 4, normalize: true },
]);
this._meshBuffer = this.getBuffer('mesh', vfmtPosUvColor);

提交数据

js 复制代码
function _commitVertexBuffers(device, gl, cur, next) {
    let vb = next.vertexBuffers[i];// 来自setVertexBuffer
    let el = vb._format.element(attr.name); // 从VertexFormat中取

    gl.vertexAttribPointer(
          attr.location,
          el.num,// 几个这样的数据类型
          el.type,// 对应format里面的type
          el.normalize,// 是否归一化
          el.stride, // VertexForamt会自动计算步进
          el.offset + vbOffset * el.stride // el.offset VertexFormat也会自动计算
        );

}

所以数据的填充必须按照VertexFormat的数据格式要求,按照顺序填充,一共是20byte

| position | | uv | | color | |
|----------|-------|-------|-------|-------|-------|-------|-------|
| x | y | u | v | r | g | b | a |
| 4byte | 4byte | 4byte | 4byte | 1byte | 1byte | 1byte | 1byte |

meshbuffer里面有个非常重要的函数要理解

js 复制代码
requestStatic (vertexCount, indiceCount) {

    this.checkAndSwitchBuffer(vertexCount);
    // 新的偏移 = 当前偏移 + 顶点数量 * 顶点大小,申请的内存空间追加到了末尾
    let byteOffset = this.byteOffset + vertexCount * this._vertexBytes;
    let indiceOffset = this.indiceOffset + indiceCount;

    // 如果不足,就会扩容
    let byteLength = this._vData.byteLength;
    let indiceLength = this._iData.length;
    if (byteOffset > byteLength || indiceOffset > indiceLength) {
        while (byteLength < byteOffset || indiceLength < indiceOffset) {
            this._initVDataCount *= 2;
            this._initIDataCount *= 2;

            byteLength = this._initVDataCount * 4;
            indiceLength = this._initIDataCount;
        }

        this._reallocBuffer();
    }
    this._updateOffset(vertexCount, indiceCount, byteOffset);
},

很明显可以看到就是大家的顶点都是放在一个Buffer里面,

我的场景是有一个Sprite,所以现在的meshbuffer是这样子

  • byteOffset: 当前一共有80byte,因为有4个顶点,每个顶点20byte
  • indiceOffset:顶点索引的游标为6
  • indiceStart:
  • vertexOffset:顶点的游标在4

使用chrome的memory inspector可以非常方便观察变量

ArrayBufferr set函数

在 JavaScript 中,ArrayBuffer 是一种特殊的对象,用于表示一段固定大小的原始二进制数据缓冲区。它可以用来存储和操作二进制数据,而无需关心具体的数据类型和编码。

ArrayBuffer 的 set() 方法用于将一个 ArrayBuffer 或一个可索引对象(如 TypedArray 或 DataView)的数据复制到另一个 ArrayBuffer 中。它可以用来合并或拷贝数据。

使用语法如下:

bash 复制代码
javascriptCopy Code
targetArrayBuffer.set(source[, offset]);

其中,targetArrayBuffer 是目标 ArrayBuffer,source 是要复制的数据源,offset 是可选参数,表示在目标 ArrayBuffer 中开始复制的位置,默认为 0。

Memory Inspector

Chrome 的 Memory Inspector 是 Chrome DevTools 中的一个工具,用于分析和调试 JavaScript 程序的内存使用情况。

Memory Inspector 可以帮助开发者了解 JavaScript 对象的生命周期、内存占用情况和泄漏情况。通过 Memory Inspector,开发者可以观察堆快照中的内存分配情况、跟踪应用程序中各种对象的引用关系、标记垃圾数据等。

在使用 Memory Inspector 时,首先需要打开 Chrome DevTools,并进入 Memory 面板。在这个面板中,可以通过捕获堆快照来获取 JavaScript 对象的内存占用情况,并对其中的对象进行逐一检查和分析。

另外,Memory Inspector 还提供了几个辅助功能,如 Allocation Timeline(内存分配时间轴)和 Retaining Tree(对象引用关系树)等。这些工具可以帮助开发者更清晰地了解 JavaScript 程序的内部运行机制,从而诊断和解决内存问题。

相关推荐
掘金安东尼7 分钟前
用 WebGL + Solid.js 构建混合材质 Shader
前端·webgl
恋猫de小郭11 分钟前
Flutter 小技巧之有趣的 UI 骨架屏框架 skeletonizer
android·前端·flutter
江城开朗的豌豆11 分钟前
玩转React Hooks
前端·javascript·react.js
阿酷tony16 分钟前
教育场景下禁用html5播放器拖动进度条的例子
前端·html·html5·在线教育场景·禁止播放器拖动
前端小巷子37 分钟前
Vue3 响应式革命
前端·vue.js·面试
一狐九1 小时前
Flutter如何通过GlobalKey调用组件内的方法
前端·flutter
wyzqhhhh1 小时前
前端如何处理首屏优化问题
前端
杨荧1 小时前
基于Python的反诈知识科普平台 Python+Django+Vue.js
大数据·前端·vue.js·python·数据分析
22jimmy2 小时前
JavaWeb(二)CSS
java·开发语言·前端·css·入门·基础
m0_738120725 小时前
CTFshow系列——命令执行web38-40
前端·windows·安全·web安全