[√]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 程序的内部运行机制,从而诊断和解决内存问题。

相关推荐
m0_748256789 分钟前
SpringBoot 依赖之Spring Web
前端·spring boot·spring
web1350858863537 分钟前
前端node.js
前端·node.js·vim
m0_5127446438 分钟前
极客大挑战2024-web-wp(详细)
android·前端
若川1 小时前
Taro 源码揭秘:10. Taro 到底是怎样转换成小程序文件的?
前端·javascript·react.js
潜意识起点1 小时前
精通 CSS 阴影效果:从基础到高级应用
前端·css
奋斗吧程序媛1 小时前
删除VSCode上 origin/分支名,但GitLab上实际上不存在的分支
前端·vscode
IT女孩儿1 小时前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
m0_748256564 小时前
如何解决前端发送数据到后端为空的问题
前端
请叫我飞哥@4 小时前
HTML5适配手机
前端·html·html5
@解忧杂货铺5 小时前
前端vue如何实现数字框中通过鼠标滚轮上下滚动增减数字
前端·javascript·vue.js