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

相关推荐
OpenTiny社区16 分钟前
Node.js技术原理分析系列——Node.js的perf_hooks模块作用和用法
前端·node.js
菲力蒲LY19 分钟前
输入搜索、分组展示选项、下拉选取,全局跳转页,el-select 实现 —— 后端数据处理代码,抛砖引玉展思路
java·前端·mybatis
MickeyCV2 小时前
Nginx学习笔记:常用命令&端口占用报错解决&Nginx核心配置文件解读
前端·nginx
祈澈菇凉2 小时前
webpack和grunt以及gulp有什么不同?
前端·webpack·gulp
zy0101012 小时前
HTML列表,表格和表单
前端·html
初辰ge2 小时前
【p-camera-h5】 一款开箱即用的H5相机插件,支持拍照、录像、动态水印与样式高度定制化。
前端·相机
HugeYLH2 小时前
解决npm问题:错误的代理设置
前端·npm·node.js
六个点3 小时前
DNS与获取页面白屏时间
前端·面试·dns
道不尽世间的沧桑3 小时前
第9篇:插槽(Slots)的使用
前端·javascript·vue.js
bin91533 小时前
DeepSeek 助力 Vue 开发:打造丝滑的滑块(Slider)
前端·javascript·vue.js·前端框架·ecmascript·deepseek