luma.gl/modules/webgl/test/classes/buffer.spec.js

284 lines
8.6 KiB
JavaScript

import GL from '@luma.gl/constants';
import {isWebGL} from '@luma.gl/gltools';
import {Buffer} from '@luma.gl/webgl';
import test from 'tape-catch';
import {fixture} from 'test/setup';
test('Buffer#constructor/delete', t => {
const {gl} = fixture;
t.ok(isWebGL(gl), 'Created gl context');
t.throws(() => new Buffer(), /.*WebGLRenderingContext.*/, 'Buffer throws on missing gl context');
const buffer = new Buffer(gl, {target: GL.ARRAY_BUFFER});
t.ok(buffer instanceof Buffer, 'Buffer construction successful');
buffer.delete();
t.ok(buffer instanceof Buffer, 'Buffer delete successful');
buffer.delete();
t.ok(buffer instanceof Buffer, 'Buffer repeated delete successful');
t.end();
});
test('Buffer#constructor offset and size', t => {
const {gl2} = fixture;
if (!gl2) {
t.comment('WebGL2 not available, skipping tests');
t.end();
return;
}
const data = new Float32Array([1, 2, 3]);
let buffer = new Buffer(gl2, {data, offset: 8});
let receivedData = buffer.getData();
let expectedData = new Float32Array([0, 0, 1, 2, 3]);
t.deepEqual(receivedData, expectedData, 'Buffer constructor offsets data');
t.equal(buffer.byteLength, expectedData.byteLength, 'Buffer byteLength set properly');
t.equal(buffer.bytesUsed, expectedData.byteLength, 'Buffer byteLength set properly');
buffer = new Buffer(gl2, {data, byteLength: data.byteLength + 12});
receivedData = buffer.getData();
expectedData = new Float32Array([1, 2, 3, 0, 0, 0]);
t.deepEqual(receivedData, expectedData, 'Buffer constructor sets buffer byteLength');
t.equal(buffer.byteLength, expectedData.byteLength, 'Buffer byteLength set properly');
t.equal(buffer.bytesUsed, expectedData.byteLength, 'Buffer byteLength set properly');
buffer = new Buffer(gl2, {data, offset: 8, byteLength: data.byteLength + 12});
receivedData = buffer.getData();
expectedData = new Float32Array([0, 0, 1, 2, 3, 0]);
t.deepEqual(
receivedData,
expectedData,
'Buffer constructor sets buffer byteLength and offsets data'
);
t.equal(buffer.byteLength, expectedData.byteLength, 'Buffer byteLength set properly');
t.equal(buffer.bytesUsed, expectedData.byteLength, 'Buffer byteLength set properly');
t.end();
});
test('Buffer#bind/unbind', t => {
const {gl} = fixture;
const buffer = new Buffer(gl, {target: GL.ARRAY_BUFFER})
.bind()
.unbind()
.delete();
t.ok(buffer instanceof Buffer, 'Buffer bind/unbind successful');
t.end();
});
test('Buffer#bind/unbind with index', t => {
const {gl2} = fixture;
if (!gl2) {
t.comment('WebGL2 not available, skipping tests');
t.end();
return;
}
const buffer = new Buffer(gl2, {target: GL.UNIFORM_BUFFER, index: 0})
.bind()
.unbind()
.delete();
t.ok(buffer instanceof Buffer, 'Buffer bind/unbind with index successful');
t.end();
});
test('Buffer#construction', t => {
const {gl} = fixture;
let buffer;
buffer = new Buffer(gl, {target: GL.ARRAY_BUFFER, data: new Float32Array([1, 2, 3])})
.bind()
.unbind()
.delete();
t.ok(buffer instanceof Buffer, 'Buffer(ARRAY_BUFFER) successful');
// TODO - buffer could check for integer ELEMENT_ARRAY_BUFFER types
buffer = new Buffer(gl, {
target: GL.ELEMENT_ARRAY_BUFFER,
data: new Float32Array([1, 2, 3])
})
.bind()
.unbind()
.delete();
t.ok(buffer instanceof Buffer, 'Buffer(ELEMENT_ARRAY_BUFFER) successful');
t.end();
});
test('Buffer#initialize/subData', t => {
const {gl} = fixture;
let buffer;
buffer = new Buffer(gl, {target: GL.ARRAY_BUFFER})
.initialize({data: new Float32Array([1, 2, 3])})
.bind()
.unbind()
.delete();
t.ok(buffer instanceof Buffer, 'Buffer.subData(ARRAY_BUFFER) successful');
buffer = new Buffer(gl, {target: GL.ARRAY_BUFFER, data: new Float32Array([1, 2, 3])})
.initialize({data: new Float32Array([1, 2, 3])})
.bind()
.unbind()
.delete();
t.ok(buffer instanceof Buffer, 'Buffer.subData(ARRAY_BUFFER) successful');
buffer = new Buffer(gl, {target: GL.ELEMENT_ARRAY_BUFFER})
.initialize({data: new Float32Array([1, 2, 3])})
.bind()
.unbind()
.delete();
t.ok(buffer instanceof Buffer, 'buffer.initialize(ELEMENT_ARRAY_BUFFER) successful');
buffer = new Buffer(gl, {target: GL.ELEMENT_ARRAY_BUFFER})
.initialize({data: new Float32Array([1, 2, 3])})
.subData({data: new Float32Array([1, 1, 1])})
.bind()
.unbind()
.delete();
t.ok(buffer instanceof Buffer, 'Buffer.subData(ARRAY_ELEMENT_BUFFER) successful');
t.end();
});
test('Buffer#copyData', t => {
const {gl2} = fixture;
if (!gl2) {
t.comment('WebGL2 not available, skipping tests');
t.end();
return;
}
const sourceData = new Float32Array([1, 2, 3]);
const sourceBuffer = new Buffer(gl2, {data: sourceData});
const destinationData = new Float32Array([4, 5, 6]);
const destinationBuffer = new Buffer(gl2, {data: destinationData});
let receivedData = destinationBuffer.getData();
let expectedData = new Float32Array([4, 5, 6]);
t.deepEqual(receivedData, expectedData, 'Buffer.getData: default parameters successful');
destinationBuffer.copyData({sourceBuffer, size: 2 * Float32Array.BYTES_PER_ELEMENT});
receivedData = destinationBuffer.getData();
expectedData = new Float32Array([1, 2, 6]);
t.deepEqual(receivedData, expectedData, 'Buffer.copyData: with size successful');
destinationBuffer.copyData({
sourceBuffer,
readOffset: Float32Array.BYTES_PER_ELEMENT,
writeOffset: 2 * Float32Array.BYTES_PER_ELEMENT,
size: Float32Array.BYTES_PER_ELEMENT
});
receivedData = destinationBuffer.getData();
expectedData = new Float32Array([1, 2, 2]);
t.deepEqual(receivedData, expectedData, 'Buffer.copyData: with size and offsets successful');
t.end();
});
test('Buffer#getData', t => {
const {gl2} = fixture;
if (!gl2) {
t.comment('WebGL2 not available, skipping tests');
t.end();
return;
}
let data = new Float32Array([1, 2, 3]);
let buffer = new Buffer(gl2, {data});
let receivedData = buffer.getData();
let expectedData = new Float32Array([1, 2, 3]);
t.deepEqual(data, receivedData, 'Buffer.getData: default parameters successful');
receivedData = buffer.getData({
dstData: new Float32Array(2),
srcByteOffset: Float32Array.BYTES_PER_ELEMENT
});
expectedData = new Float32Array([2, 3]);
t.deepEqual(expectedData, receivedData, "Buffer.getData: with 'dstData' parameter successful");
receivedData = buffer.getData({
srcByteOffset: Float32Array.BYTES_PER_ELEMENT,
dstOffset: 2
});
expectedData = new Float32Array([0, 0, 2, 3]);
t.deepEqual(expectedData, receivedData, 'Buffer.getData: with src/dst offsets successful');
// NOTE: when source and dst offsets are specified, 'length' needs to be set so that
// source buffer access is not outof bounds, otherwise 'getBufferSubData' will throw exception.
receivedData = buffer.getData({
srcByteOffset: Float32Array.BYTES_PER_ELEMENT * 2,
dstOffset: 1,
length: 1
});
expectedData = new Float32Array([0, 3]);
t.deepEqual(
expectedData,
receivedData,
'Buffer.getData: with src/dst offsets and length successful'
);
data = new Uint8Array([128, 255, 1]);
buffer = new Buffer(gl2, {data});
receivedData = buffer.getData();
t.deepEqual(data, receivedData, 'Buffer.getData: Uint8Array + default parameters successful');
t.end();
});
test('Buffer#getElementCount', t => {
const {gl} = fixture;
let vertexCount;
const buffer1 = new Buffer(gl, {data: new Float32Array([1, 2, 3])});
vertexCount = buffer1.getElementCount();
t.equal(vertexCount, 3, 'Vertex count should match');
let buffer2 = new Buffer(gl, {data: new Int32Array([1, 2, 3, 4]), acessor: {divisor: 1}});
vertexCount = buffer2.getElementCount();
t.equal(vertexCount, 4, 'Vertex count should match');
const {byteLength, usage, accessor} = buffer1;
buffer2 = new Buffer(gl, {byteLength, usage, accessor});
vertexCount = buffer2.getElementCount();
t.equal(vertexCount, 3, 'Vertex count should match');
t.end();
});
test('Buffer#reallocate', t => {
const {gl} = fixture;
const buffer = new Buffer(gl, {byteLength: 100});
t.equal(buffer.byteLength, 100, 'byteLength should match');
t.equal(buffer.bytesUsed, 100, 'bytesUsed should match');
let didRealloc = buffer.reallocate(90);
t.equal(didRealloc, false, 'Should not reallocate');
t.equal(buffer.byteLength, 100, 'byteLength should be unchanged');
t.equal(buffer.bytesUsed, 90, 'bytesUsed should have changed');
didRealloc = buffer.reallocate(110);
t.equal(didRealloc, true, 'Should reallocate');
t.equal(buffer.byteLength, 110, 'byteLength should have changed');
t.equal(buffer.byteLength, 110, 'bytesUsed should have changed');
t.end();
});