332 lines
13 KiB
JavaScript
332 lines
13 KiB
JavaScript
|
|
defineSuite([
|
||
|
|
'Renderer/VertexArrayFacade',
|
||
|
|
'Core/ComponentDatatype',
|
||
|
|
'Renderer/BufferUsage',
|
||
|
|
'Specs/createContext'
|
||
|
|
], function(
|
||
|
|
VertexArrayFacade,
|
||
|
|
ComponentDatatype,
|
||
|
|
BufferUsage,
|
||
|
|
createContext) {
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
var context;
|
||
|
|
|
||
|
|
beforeAll(function() {
|
||
|
|
context = createContext();
|
||
|
|
});
|
||
|
|
|
||
|
|
afterAll(function() {
|
||
|
|
context.destroyForSpecs();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('creates a vertex array with static floats', function() {
|
||
|
|
var positionIndex = 0;
|
||
|
|
var vaf = new VertexArrayFacade(context, [{
|
||
|
|
index : positionIndex,
|
||
|
|
componentsPerAttribute : 3,
|
||
|
|
componentDatatype : ComponentDatatype.FLOAT,
|
||
|
|
usage : BufferUsage.STATIC_DRAW
|
||
|
|
}], 1);
|
||
|
|
|
||
|
|
var writer = vaf.writers[positionIndex];
|
||
|
|
expect(writer).toBeDefined();
|
||
|
|
|
||
|
|
writer(0, 1.0, 2.0, 3.0); // Write [1.0, 2.0, 3.0] at index zero.
|
||
|
|
vaf.commit(); // Commit writes
|
||
|
|
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer).toBeDefined();
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.sizeInBytes).toEqual(1 * 3 * 4);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.usage).toEqual(BufferUsage.STATIC_DRAW);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentsPerAttribute).toEqual(3);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentDatatype).toEqual(ComponentDatatype.FLOAT);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).offsetInBytes).toEqual(0);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).strideInBytes).toEqual(3 * 4);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('resizes a vertex array with static floats', function() {
|
||
|
|
var positionIndex = 0;
|
||
|
|
var vaf = new VertexArrayFacade(context, [{
|
||
|
|
index : positionIndex,
|
||
|
|
componentsPerAttribute : 3,
|
||
|
|
componentDatatype : ComponentDatatype.FLOAT,
|
||
|
|
usage : BufferUsage.STATIC_DRAW
|
||
|
|
}], 1);
|
||
|
|
|
||
|
|
var writer = vaf.writers[positionIndex];
|
||
|
|
expect(writer).toBeDefined();
|
||
|
|
|
||
|
|
writer(0, 1.0, 2.0, 3.0); // Write [1.0, 2.0, 3.0] at index zero.
|
||
|
|
|
||
|
|
vaf.resize(2); // Two vertices
|
||
|
|
writer(1, 1.0, 2.0, 3.0); // Write [4.0, 5.0, 6.0] at index one.
|
||
|
|
vaf.commit(); // Commit writes
|
||
|
|
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer).toBeDefined();
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.sizeInBytes).toEqual(2 * 3 * 4);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.usage).toEqual(BufferUsage.STATIC_DRAW);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentsPerAttribute).toEqual(3);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentDatatype).toEqual(ComponentDatatype.FLOAT);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).offsetInBytes).toEqual(0);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).strideInBytes).toEqual(3 * 4);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('creates a vertex array with static floats and unsigned bytes', function() {
|
||
|
|
var positionIndex = 0;
|
||
|
|
var colorIndex = 2;
|
||
|
|
var vaf = new VertexArrayFacade(context, [{
|
||
|
|
index : positionIndex,
|
||
|
|
componentsPerAttribute : 3,
|
||
|
|
componentDatatype : ComponentDatatype.FLOAT,
|
||
|
|
usage : BufferUsage.STATIC_DRAW
|
||
|
|
}, {
|
||
|
|
index : colorIndex,
|
||
|
|
componentsPerAttribute : 4,
|
||
|
|
componentDatatype : ComponentDatatype.UNSIGNED_BYTE,
|
||
|
|
usage : BufferUsage.STATIC_DRAW
|
||
|
|
}], 1);
|
||
|
|
|
||
|
|
var positionWriter = vaf.writers[positionIndex];
|
||
|
|
var colorWriter = vaf.writers[colorIndex];
|
||
|
|
|
||
|
|
expect(positionWriter).toBeDefined();
|
||
|
|
expect(colorWriter).toBeDefined();
|
||
|
|
|
||
|
|
positionWriter(0, 1.0, 2.0, 3.0); // Write position [1.0, 2.0, 3.0] at index zero.
|
||
|
|
colorWriter(0, 0, 255, 0, 255); // Write color [0, 255, 0, 255] at index zero.
|
||
|
|
vaf.commit(); // Commit writes
|
||
|
|
|
||
|
|
// Position attribute
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer).toBeDefined();
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.sizeInBytes).toEqual(1 * ((3 * 4) + (4 * 1)));
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.usage).toEqual(BufferUsage.STATIC_DRAW);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentsPerAttribute).toEqual(3);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentDatatype).toEqual(ComponentDatatype.FLOAT);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).offsetInBytes).toEqual(0);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).strideInBytes).toEqual((3 * 4) + (4 * 1));
|
||
|
|
|
||
|
|
// Color attribute
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).vertexBuffer).toEqual(vaf.va[0].va.getAttribute(0).vertexBuffer);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).componentsPerAttribute).toEqual(4);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).componentDatatype).toEqual(ComponentDatatype.UNSIGNED_BYTE);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).offsetInBytes).toEqual(3 * 4);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).strideInBytes).toEqual(vaf.va[0].va.getAttribute(0).strideInBytes);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('creates a vertex array with static and dynamic attributes', function() {
|
||
|
|
var positionIndex = 0;
|
||
|
|
var txCoordIndex = 2;
|
||
|
|
var vaf = new VertexArrayFacade(context, [{
|
||
|
|
index : positionIndex,
|
||
|
|
componentsPerAttribute : 3,
|
||
|
|
componentDatatype : ComponentDatatype.FLOAT,
|
||
|
|
usage : BufferUsage.STATIC_DRAW
|
||
|
|
}, {
|
||
|
|
index : txCoordIndex,
|
||
|
|
componentsPerAttribute : 2,
|
||
|
|
componentDatatype : ComponentDatatype.UNSIGNED_SHORT,
|
||
|
|
usage : BufferUsage.DYNAMIC_DRAW,
|
||
|
|
normalize : true
|
||
|
|
}], 1);
|
||
|
|
|
||
|
|
var positionWriter = vaf.writers[positionIndex];
|
||
|
|
var txCoordWriter = vaf.writers[txCoordIndex];
|
||
|
|
|
||
|
|
expect(positionWriter).toBeDefined();
|
||
|
|
expect(txCoordWriter).toBeDefined();
|
||
|
|
|
||
|
|
positionWriter(0, 1.0, 2.0, 3.0);
|
||
|
|
txCoordWriter(0, 32 * 1024, 64 * 1024);
|
||
|
|
vaf.commit();
|
||
|
|
|
||
|
|
// Position attribute
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer).toBeDefined();
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.sizeInBytes).toEqual(1 * (3 * 4));
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.usage).toEqual(BufferUsage.STATIC_DRAW);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentsPerAttribute).toEqual(3);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentDatatype).toEqual(ComponentDatatype.FLOAT);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).offsetInBytes).toEqual(0);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).strideInBytes).toEqual(3 * 4);
|
||
|
|
|
||
|
|
// Texture coordinate attribute
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).vertexBuffer).toBeDefined();
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).vertexBuffer.sizeInBytes).toEqual(1 * (2 * 2));
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).vertexBuffer.usage).toEqual(BufferUsage.DYNAMIC_DRAW);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).componentsPerAttribute).toEqual(2);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).componentDatatype).toEqual(ComponentDatatype.UNSIGNED_SHORT);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).offsetInBytes).toEqual(0);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).strideInBytes).toEqual(2 * 2);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('sub-commits', function() {
|
||
|
|
var positionIndex = 0;
|
||
|
|
var temperatureIndex = 2;
|
||
|
|
var vaf = new VertexArrayFacade(context, [{
|
||
|
|
index : positionIndex,
|
||
|
|
componentsPerAttribute : 3,
|
||
|
|
componentDatatype : ComponentDatatype.FLOAT,
|
||
|
|
usage : BufferUsage.STATIC_DRAW
|
||
|
|
}, {
|
||
|
|
index : temperatureIndex,
|
||
|
|
componentsPerAttribute : 1,
|
||
|
|
componentDatatype : ComponentDatatype.FLOAT,
|
||
|
|
usage : BufferUsage.STREAM_DRAW
|
||
|
|
}], 2);
|
||
|
|
|
||
|
|
var positionWriter = vaf.writers[positionIndex];
|
||
|
|
var temperatureWriter = vaf.writers[temperatureIndex];
|
||
|
|
|
||
|
|
expect(positionWriter).toBeDefined();
|
||
|
|
expect(temperatureWriter).toBeDefined();
|
||
|
|
|
||
|
|
positionWriter(0, 1.0, 2.0, 3.0);
|
||
|
|
temperatureWriter(0, 98.6);
|
||
|
|
positionWriter(1, 7.0, 8.0, 9.0);
|
||
|
|
temperatureWriter(1, 32.0);
|
||
|
|
vaf.commit();
|
||
|
|
|
||
|
|
// Rewrite all vertices
|
||
|
|
positionWriter(0, 10.0, 20.0, 30.0);
|
||
|
|
temperatureWriter(0, 37.0);
|
||
|
|
positionWriter(1, 70.0, 80.0, 90.0);
|
||
|
|
temperatureWriter(1, 0.0);
|
||
|
|
vaf.commit();
|
||
|
|
|
||
|
|
// Sub-commit to just one vertex
|
||
|
|
temperatureWriter(1, 212.0);
|
||
|
|
vaf.subCommit(1, 1);
|
||
|
|
vaf.endSubCommits();
|
||
|
|
|
||
|
|
// Position attribute
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).vertexBuffer).toBeDefined();
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).vertexBuffer.sizeInBytes).toEqual(2 * (3 * 4));
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).vertexBuffer.usage).toEqual(BufferUsage.STATIC_DRAW);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).componentsPerAttribute).toEqual(3);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).componentDatatype).toEqual(ComponentDatatype.FLOAT);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).offsetInBytes).toEqual(0);
|
||
|
|
expect(vaf.va[0].va.getAttribute(1).strideInBytes).toEqual(3 * 4);
|
||
|
|
|
||
|
|
// Temperature attribute
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer).toBeDefined();
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.sizeInBytes).toEqual(2 * 4);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer.usage).toEqual(BufferUsage.STREAM_DRAW);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentsPerAttribute).toEqual(1);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).componentDatatype).toEqual(ComponentDatatype.FLOAT);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).offsetInBytes).toEqual(0);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).strideInBytes).toEqual(1 * 4);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('destroys previous vertex buffers when number of vertices grows', function() {
|
||
|
|
var positionIndex = 0;
|
||
|
|
var vaf = new VertexArrayFacade(context, [{
|
||
|
|
index : positionIndex,
|
||
|
|
componentsPerAttribute : 3,
|
||
|
|
componentDatatype : ComponentDatatype.FLOAT,
|
||
|
|
usage : BufferUsage.STATIC_DRAW
|
||
|
|
}], 1);
|
||
|
|
|
||
|
|
var writer = vaf.writers[positionIndex];
|
||
|
|
expect(writer).toBeDefined();
|
||
|
|
|
||
|
|
writer(0, 1.0, 2.0, 3.0); // Write [1.0, 2.0, 3.0] at index zero.
|
||
|
|
vaf.commit(); // Commit writes
|
||
|
|
|
||
|
|
// Grab the vertex buffer
|
||
|
|
var vbBeforeResize = vaf.va[0].va.getAttribute(0).vertexBuffer;
|
||
|
|
|
||
|
|
vaf.resize(2); // Two vertices
|
||
|
|
writer(1, 1.0, 2.0, 3.0); // Write [4.0, 5.0, 6.0] at index one.
|
||
|
|
vaf.commit(); // Commit writes
|
||
|
|
|
||
|
|
expect(vbBeforeResize.isDestroyed()).toBe(true);
|
||
|
|
expect(vaf.va[0].va.getAttribute(0).vertexBuffer).not.toBe(vbBeforeResize);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('is not initially destroyed', function () {
|
||
|
|
var positionIndex = 0;
|
||
|
|
var vaf = new VertexArrayFacade(context, [{
|
||
|
|
index : positionIndex,
|
||
|
|
componentsPerAttribute : 3,
|
||
|
|
componentDatatype : ComponentDatatype.FLOAT,
|
||
|
|
usage : BufferUsage.STATIC_DRAW
|
||
|
|
}], 1);
|
||
|
|
expect(vaf.isDestroyed()).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws when constructed without a context', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new VertexArrayFacade(undefined, undefined, undefined);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws when constructed undefined attributes', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new VertexArrayFacade(context, undefined, undefined);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws when constructed without attributes', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new VertexArrayFacade(context, []);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws when constructed with attributes without componentsPerAttribute', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new VertexArrayFacade(context, [{}]);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws when constructed with attributes with an invalid componentDatatype', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new VertexArrayFacade(context, [{
|
||
|
|
componentsPerAttribute : 1,
|
||
|
|
componentDatatype : 'invalid component datatype'
|
||
|
|
}]);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws when constructed with attributes with an invalid usage', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new VertexArrayFacade(context, [{
|
||
|
|
componentsPerAttribute : 1,
|
||
|
|
usage : 'invalid component usage'
|
||
|
|
}]);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws when constructed with attributes with duplicate indices', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new VertexArrayFacade(context, [{
|
||
|
|
index : 0,
|
||
|
|
componentsPerAttribute : 1
|
||
|
|
}, {
|
||
|
|
index : 0,
|
||
|
|
componentsPerAttribute : 1
|
||
|
|
}]);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('subCommit throws when passed an invalid offsetInVertices', function() {
|
||
|
|
var positionIndex = 0;
|
||
|
|
var vaf = new VertexArrayFacade(context, [{
|
||
|
|
index : positionIndex,
|
||
|
|
componentsPerAttribute : 3,
|
||
|
|
componentDatatype : ComponentDatatype.FLOAT,
|
||
|
|
usage : BufferUsage.STATIC_DRAW
|
||
|
|
}], 10);
|
||
|
|
|
||
|
|
expect(function() {
|
||
|
|
vaf.subCommit(-1, 1);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
|
||
|
|
expect(function() {
|
||
|
|
vaf.subCommit(10, 1);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
|
||
|
|
expect(function() {
|
||
|
|
vaf.subCommit(1, 10);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
}, 'WebGL');
|