WebGL
webgl 是针对 canvas 的 3D上下文,与其它Web技术不同,WebGL并非是W3C制定的标准,而是由 Khronos Group 制定的。
类型化数组
WebGL所涉及的复杂运算需要提前知道数值的精度,但是标准的 JS 无法支持这一诉求。
因此WebGL引入了类型化数组这一概念,类型化数组也是数组,与一般的数组没有什么区别,只不过这种数组中所有元素的值都被指定为某一特定类型。
类型化数组的核心在于 ArrayBuffer 这一数据类型,每个 ArrayBuffer 对象表示内存中的指定字节数,相当于分配一个指定大小的内存供你使用。
通过 ArrayBuffer 的 byteLength 属性可以获取该对象的字节数。
然而要操作 ArrayBuffer 则需要使用 DataView(视图)。
DataView
视图是一个可以从 ArrayBuffer
对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的字节序问题。(摘自MDN)
创建视图可以使用以下方式:
// 基于整个 ArrayBuffer 创建视图
let view = new DataView(buffer); // 创建一个从 ArrayBuffer 第九个字节开始的视图
let view = new DataView(buffer, 9); // 创建一个 ArrayBuffer 9~18字节的视图
let view = new DataView(buffer, 9, 10);
实例化的 DataView 会将字节偏移量以及字节长度信息分别保存在 byteOffset、byteLength 属性中。
通过 buffer 属性则可以获得原本的 ArrayBuffer。
数据类型 | getter | setter |
有符号8位整数 | getInt8(byteOffset) | setInt8(byteOffset,value) |
无符号8位整数 | getUint8(byteOffset) | setUint8(byteOffset,value) |
有符号16位整数 | getInt16(byteOffset,littleEndian) | setInt16(byteOffset,value,littleEndian) |
无符号16位整数 | getUint16(byteOffset,littleEndian) | setUint16(byteOffset,value,littleEndian) |
有符号32位整数 | getInt32(byteOffset,littleEndian) | setInt32(byteOffset,value,littleEndian) |
无符号32位整数 | getUint32(byteOffset,littleEndian) | setUint32(byteOffset,value,littleEndian) |
32位浮点数 | getFloat32(byteOffset,littleEndian) | setFloat32(byteOffset,value,littleEndian) |
64位浮点数 | getFloat64(byteOffset,littleEndian) | setFloat64(byteOffset,value,littleEndian) |
上方表格中的方法函数的第一个参数都是字节的偏移量,表示从哪一个字节开始读取或者写入.
代码如下:
let buffer = new ArrayBuffer(20),
view = new DataView(buffer),
value; view.setUint16(0,25);
view.setUint16(2,50);// 不能从字节1 开始,因为16位整数需要使用两个字节
value = view.getInt16(0);
所以在使用DataView时需要自己把握这些细节
如果不注意就很容易出现错误,如下所示
let buffer = new ArrayBuffer(20),
view = new DataView(buffer),
value; view.setUint16(0,25);
alert(view.getUint8(0));// 0 因为16位表示的25前8位全为0
此外用于读写16位或更大数值的方法都有一个参数 littleEndian 该参数是一个布尔值
用于表示数值读写时是否采用小端字节序(即数据最低有效位保存在低字节位的地址中)
默认是 大端字节序,即该值为 false