我正在开发一个基于webgl的渲染器,正如标题所说,我需要将4个8位无符号整数打包到32位浮点数, 我写了以下代码:
//pack 4 8-bit integer to a float
function packIntsToFloat(i1, i2, i3, i4) {
//ensure 32-bit allocation
var ints = new Uint32Array(4);
ints[0] = i1;
ints[1] = i2;
ints[2] = i3;
ints[3] = i4;
ints[0] <<= 24;
ints[1] <<= 16;
ints[2] <<= 8;
ints[3] |= ints[0] | ints[1] | ints[2];
//convert to float
var f = new Float32Array(1);
f[0] = ints[3];
return f[0];
}
//unpack 4 8-bit integer from a float
function unPackIntsFromFloat(f) {
var i = new Uint32Array(4);
i[3] = f;
var mask_7_to_0 = 255;
var mask_15_to_8 = mask_7_to_0 << 8;
var mask_23_to_16 = mask_15_to_8 << 8;
var mask_31_to_24 = mask_23_to_16 << 8;
i[0] = (i[3] & mask_31_to_24 ) >>> 24;
i[1] = (i[3] & mask_23_to_16 ) >>> 16;
i[2] = (i[3] & mask_15_to_8 ) >>> 8;
i[3] = (i[3] & mask_7_to_0);
return new Uint8Array(i);
}
但除非跳过我需要的内容,否则它将无效:
//convert to float
var f = new Float32Array(1);
f[0] = ints[3];
我知道IEEE标准,但不应该对位进行任何更改,只能将它们的解释作为值。 提前谢谢。
答案 0 :(得分:3)
所有TypedArray
只是关于类型不可知ArrayBuffer
的视图,因此您只需使用它:
<强>包装:强>
new Float32Array((new Uint8Array([i1,i2,i3,i4])).buffer)[0];
<强>启封:强>
new Uint8Array((new Float32Array([f])).buffer);
有关详细信息,请参阅ArrayBufferView
的文档。
答案 1 :(得分:1)
你准备做什么?
例如,您是否尝试将浮点位置和无符号字节颜色放在同一个缓冲区中?在这种情况下,将2个视图写入同一个缓冲区。例如:
var numVerts = 10;
var bytesPerPosition = 3 * 4; // x,y,z * 4 bytes per float
var bytesPerColor = 4; // r,g,b,a 1 byte each
var bytesPerVertex = bytesPerPosition * bytesPerColor;
var sizeOfBuffer = numVertex * bytesPerVertex;
var offsetOfPositions = 0;
var offsetOfColor = bytesPerPosition;
// now make the buffer.
var asUint8 = new Uint8Array(sizeOfBuffer);
var asFloat = new FloatArray(asUint8.buffer);
您现在有2个视图到同一个缓冲区。例如,设置一个有效的位置
var strideInFloats = bytesPerVertex / 4;
function setPosition(index, x, y, z) {
var offset = strideInFloats * index;
asFloat[offset ] = x;
asFloat[offset + 1] = y;
asFloat[offset + 2] = z;
}
有效设置颜色
function setColor(index, r, g, b, a) {
var offset = strideInBytes * index + offsetToColor;
asUint8[offset ] = r;
asUint8[offset + 1] = g;
asUint8[offset + 2] = b;
asUint8[offset + 3] = a;
}
设置属性时,您可以执行类似
的操作gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, bytesPerVertex,
offsetOfPosition);
gl.vertexAttribPointer(colorLoc, 4, gl.UNSIGNED_BYTE, true, bytesPerVertex,
offsetOfColor);