Gen*_*Ptr 2 javascript webgl typed-arrays
我正在尝试使用 WebGL,并希望将一些不同类型混合到一个字节缓冲区中。我知道 TypedArrays 可以达到这个目的,但不清楚我是否可以与它们混合类型(OpenGL 顶点数据通常是与无符号字节或整数混合的浮点数)。
在我的测试中,我想将 2 个浮点数打包到 using 中UInt8Array,set()但它似乎只是将 2 个浮点数放入 的前 2 个元素中UInt8Array。当然,我希望它能填满数组,因为我们有 8 个字节的数据。
无论如何,有没有办法在 JavaScript 中实现这一点,或者我是否需要将所有顶点数据保留为浮点数?
src = new Float32Array(2); // 2 elements = 8 bytes
src[0] = 100;
src[1] = 200;
dest = new UInt8Array(8); // 8 elements = 8 bytes
dest.set(src, 0); // insert src at offset 0
dest = 100,200,0,0,0,0,0,0 (only the first 2 bytes are set)
Run Code Online (Sandbox Code Playgroud)
您可以通过在同一缓冲区上创建不同的视图来混合类型。
const asFloats = new Float32Array(2);
// create a uint8 view to the same buffer as the float32array
const asBytes = new Uint8Array(asFloats.buffer);
console.log(asFloats);
asBytes[3] = 123;
console.log(asFloats);Run Code Online (Sandbox Code Playgroud)
TypeArrays 真正工作的方式是有一个叫做 an 的东西ArrayBuffer,它有一定的字节长度。要查看字节,您需要一个字节ArrayBufferView,其中有各种类型Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array。
您可以从头开始创建ArrayBuffer。
const buffer = new ArrayBuffer(8);
const asFloats = new Float32Array(buffer);
asFloats[0] = 1.23;
asFloats[1] = 4.56;
console.log(asFloats);Run Code Online (Sandbox Code Playgroud)
或者,您可以做更正常的事情,即创建ArrayBufferView特定类型的 ,如果您不将其传递给构造函数,它将创建ArrayBufferView该类型的,并为其创建 。然后,您可以从上面第一个示例中所示的位置访问该缓冲区。ArrayBuffersomeArrayBufferView.buffer
您还可以为视图分配一个偏移量ArrayBuffer和一个长度,以使其小于ArrayBuffer。例子:
// make a 16byte ArrayBuffer and a Uint8Array (ArrayBufferView)
const asUint8 = new Uint8Array(16);
// make a 1 float long view in the same buffer
// that starts at byte 4 in that buffer
const byteOffset = 4;
const length = 1; // 1 float32
const asFloat = new Float32Array(asUint8.buffer, byteOffset, length);
// show the buffer is all 0s
console.log(asUint8);
// set the float
asFloat[0] = 12345.6789
// show the buffer is affected at byte 4
console.log(asUint8);
// set a float out of range of its length
asFloat[1] = -12345.6789; // this is effectively a no-op
// show the buffer is NOT affected at byte 8
console.log(asUint8);Run Code Online (Sandbox Code Playgroud)
因此,如果你想为 WebGL 混合浮动位置和 Uint8 颜色,你可能会这样做
// we're going to have
// X,Y,Z,R,G,B,A, X,Y,Z,R,G,B,A, X,Y,Z,R,G,B,A,
// where X,Y,Z are float32
// and R,G,B,A are uint8
const sizeOfVertex = 3 * 4 + 4 * 1; // 3 float32s + 4 bytes
const numVerts = 3;
const asBytes = new Uint8Array(numVerts * sizeOfVertex);
const asFloats = new Float32Array(asBytes.buffer);
// set the positions and colors
const positions = [
-1, 1, 0,
0, -1, 0,
1, 1, 0,
];
const colors = [
255, 0, 0, 255,
0, 255, 0, 255,
0, 0, 255, 255,
];
{
const numComponents = 3;
const offset = 0; // in float32s
const stride = 4; // in float32s
copyToArray(positions, numComponents, offset, stride, asFloats);
}
{
const numComponents = 4;
const offset = 12; // in bytes
const stride = 16; // in bytes
copyToArray(colors, numComponents, offset, stride, asBytes);
}
console.log(asBytes);
console.log(asFloats);
function copyToArray(src, numComponents, offset, stride, dst) {
const strideDiff = stride - numComponents;
let srcNdx = 0;
let dstNdx = offset;
const numElements = src.length / numComponents;
if (numElements % 1) {
throw new Error("src does not have an even number of elements");
}
for (let elem = 0; elem < numElements; ++elem) {
for(let component = 0; component < numComponents; ++component) {
dst[dstNdx++] = src[srcNdx++];
}
dstNdx += strideDiff;
}
}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
909 次 |
| 最近记录: |