[√]MeshBuffer和VertexFormat

简介: [√]MeshBuffer和VertexFormat

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

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);

提交数据

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里面有个非常重要的函数要理解

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是这样子

image.png

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

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

image.png

ArrayBufferr set函数

image.png

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

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

使用语法如下:

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

目录
相关文章
|
8月前
|
算法 C++
[√]ffi zlib
[√]ffi zlib
39 1
|
8月前
|
编译器 Android开发 iOS开发
[√]关于cmake的kits
[√]关于cmake的kits
84 0
|
8月前
|
XML C++ 数据格式
[√]vld的安装和使用
[√]vld的安装和使用
69 0
|
8月前
|
缓存 Linux Android开发
[√]获取Android内存情况
[√]获取Android内存情况
42 0
|
8月前
|
编译器 C++ 开发者
[√]关于 Dynamic atexit destructor for ***
[√]关于 Dynamic atexit destructor for ***
85 0
|
8月前
|
JavaScript 前端开发 索引
[√]正则表达式
[√]正则表达式
27 0
|
8月前
|
iOS开发
[√]xcode无线调试
[√]xcode无线调试
44 0
|
8月前
|
Android开发
[√]android makefile
[√]android makefile
67 0
|
8月前
|
编译器
[√]cmake 编译选项
[√]cmake 编译选项
39 0
|
8月前
|
Shell C++ Windows
[√]尝试使用cmake编译使用vld
[√]尝试使用cmake编译使用vld
66 0