Webgl buffer / now stores data in typed arrays
The `WebGLBuffer` class API was changed in order to allow populating the internal array in different ways.
This commit is contained in:
@@ -228,3 +228,7 @@ Missing or invalid `size`.
|
|||||||
### 61
|
### 61
|
||||||
|
|
||||||
Cannot determine IIIF Image API version from provided image information JSON.
|
Cannot determine IIIF Image API version from provided image information JSON.
|
||||||
|
|
||||||
|
### 62
|
||||||
|
|
||||||
|
A `WebGLArrayBuffer` must either be of type `ELEMENT_ARRAY_BUFFER` or `ARRAY_BUFFER`.
|
||||||
|
|||||||
+80
-10
@@ -2,6 +2,9 @@
|
|||||||
* @module ol/webgl/Buffer
|
* @module ol/webgl/Buffer
|
||||||
*/
|
*/
|
||||||
import {STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW} from '../webgl.js';
|
import {STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW} from '../webgl.js';
|
||||||
|
import {includes} from '../array.js';
|
||||||
|
import {ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, EXTENSIONS as WEBGL_EXTENSIONS} from '../webgl.js';
|
||||||
|
import {assert} from '../asserts.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to describe the intended usage for the data: `STATIC_DRAW`, `STREAM_DRAW`
|
* Used to describe the intended usage for the data: `STATIC_DRAW`, `STREAM_DRAW`
|
||||||
@@ -17,43 +20,110 @@ export const BufferUsage = {
|
|||||||
/**
|
/**
|
||||||
* @classdesc
|
* @classdesc
|
||||||
* Object used to store an array of data as well as usage information for that data.
|
* Object used to store an array of data as well as usage information for that data.
|
||||||
* See the documentation of [WebGLRenderingContext.bufferData](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData) for more info.
|
* Stores typed arrays internally, either Float32Array or Uint16/32Array depending on
|
||||||
|
* the buffer type (ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER) and available extensions.
|
||||||
|
*
|
||||||
|
* To populate the array, you can either use:
|
||||||
|
* * A size using `#ofSize(buffer)`
|
||||||
|
* * An `ArrayBuffer` object using `#fromArrayBuffer(buffer)`
|
||||||
|
* * A plain array using `#fromArray(array)`
|
||||||
|
*
|
||||||
|
* Note:
|
||||||
|
* See the documentation of [WebGLRenderingContext.bufferData](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData)
|
||||||
|
* for more info on buffer usage.
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
class WebGLArrayBuffer {
|
class WebGLArrayBuffer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array<number>=} opt_arr Array.
|
* @param {number} type Buffer type, either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.
|
||||||
* @param {number=} opt_usage Usage, either `STATIC_DRAW`, `STREAM_DRAW` or `DYNAMIC_DRAW`. Default is `DYNAMIC_DRAW`.
|
* @param {number=} opt_usage Intended usage, either `STATIC_DRAW`, `STREAM_DRAW` or `DYNAMIC_DRAW`.
|
||||||
|
* Default is `DYNAMIC_DRAW`.
|
||||||
*/
|
*/
|
||||||
constructor(opt_arr, opt_usage) {
|
constructor(type, opt_usage) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {Array<number>}
|
* @type {Float32Array|Uint32Array|Uint16Array}
|
||||||
*/
|
*/
|
||||||
this.arr_ = opt_arr !== undefined ? opt_arr : [];
|
this.array = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
this.usage_ = opt_usage !== undefined ? opt_usage : BufferUsage.STATIC_DRAW;
|
this.type = type;
|
||||||
|
|
||||||
|
assert(type === ARRAY_BUFFER || type === ELEMENT_ARRAY_BUFFER, 62);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.usage = opt_usage !== undefined ? opt_usage : BufferUsage.STATIC_DRAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {Array<number>} Array.
|
* Populates the buffer with an array of the given size (all values will be zeroes).
|
||||||
|
* @param {number} size Array size
|
||||||
|
*/
|
||||||
|
ofSize(size) {
|
||||||
|
this.array = new (getArrayClassForType(this.type))(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the buffer with an array of the given size (all values will be zeroes).
|
||||||
|
* @param {Array<number>} array Numerical array
|
||||||
|
*/
|
||||||
|
fromArray(array) {
|
||||||
|
this.array = (getArrayClassForType(this.type)).from(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the buffer with a raw binary array buffer.
|
||||||
|
* @param {ArrayBuffer} buffer Raw binary buffer to populate the array with. Note that this buffer must have been
|
||||||
|
* initialized for the same typed array class.
|
||||||
|
*/
|
||||||
|
fromArrayBuffer(buffer) {
|
||||||
|
this.array = new (getArrayClassForType(this.type))(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {number} Buffer type.
|
||||||
|
*/
|
||||||
|
getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Float32Array|Uint32Array|Uint16Array} Array.
|
||||||
*/
|
*/
|
||||||
getArray() {
|
getArray() {
|
||||||
return this.arr_;
|
return this.array;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {number} Usage.
|
* @return {number} Usage.
|
||||||
*/
|
*/
|
||||||
getUsage() {
|
getUsage() {
|
||||||
return this.usage_;
|
return this.usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a typed array constructor based on the given buffer type
|
||||||
|
* @param {number} type Buffer type, either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.
|
||||||
|
* @returns {Float32ArrayConstructor|Uint16ArrayConstructor|Uint32ArrayConstructor} The typed array class to use for this buffer.
|
||||||
|
*/
|
||||||
|
export function getArrayClassForType(type) {
|
||||||
|
switch (type) {
|
||||||
|
case ARRAY_BUFFER:
|
||||||
|
return Float32Array;
|
||||||
|
case ELEMENT_ARRAY_BUFFER:
|
||||||
|
const hasExtension = includes(WEBGL_EXTENSIONS, 'OES_element_index_uint');
|
||||||
|
return hasExtension ? Uint32Array : Uint16Array;
|
||||||
|
default:
|
||||||
|
return Float32Array;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,51 +1,82 @@
|
|||||||
import WebGLArrayBuffer from '../../../../src/ol/webgl/Buffer.js';
|
import WebGLArrayBuffer, {getArrayClassForType} from '../../../../src/ol/webgl/Buffer.js';
|
||||||
|
import {
|
||||||
|
ARRAY_BUFFER,
|
||||||
|
ELEMENT_ARRAY_BUFFER,
|
||||||
|
EXTENSIONS as WEBGL_EXTENSIONS,
|
||||||
|
STATIC_DRAW,
|
||||||
|
STREAM_DRAW
|
||||||
|
} from '../../../../src/ol/webgl.js';
|
||||||
|
|
||||||
|
|
||||||
describe('ol.webgl.Buffer', function() {
|
describe('ol.webgl.Buffer', function() {
|
||||||
|
|
||||||
describe('constructor', function() {
|
describe('constructor', function() {
|
||||||
|
|
||||||
describe('without an argument', function() {
|
it('sets the default usage when not specified', function() {
|
||||||
|
const b = new WebGLArrayBuffer(ARRAY_BUFFER);
|
||||||
let b;
|
expect(b.getUsage()).to.be(STATIC_DRAW);
|
||||||
beforeEach(function() {
|
|
||||||
b = new WebGLArrayBuffer();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('constructs an empty instance', function() {
|
|
||||||
expect(b.getArray()).to.be.empty();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with a single array argument', function() {
|
it('sets the given usage when specified', function() {
|
||||||
|
const b = new WebGLArrayBuffer(ARRAY_BUFFER, STREAM_DRAW);
|
||||||
let b;
|
expect(b.getUsage()).to.be(STREAM_DRAW);
|
||||||
beforeEach(function() {
|
|
||||||
b = new WebGLArrayBuffer([0, 1, 2, 3]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('constructs a populated instance', function() {
|
|
||||||
expect(b.getArray()).to.eql([0, 1, 2, 3]);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('raises an error if an incorrect type is used', function(done) {
|
||||||
|
try {
|
||||||
|
new WebGLArrayBuffer(1234);
|
||||||
|
} catch (e) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
done(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with an empty instance', function() {
|
describe('#getArrayClassForType', function() {
|
||||||
|
it('returns the correct typed array constructor', function() {
|
||||||
|
expect(getArrayClassForType(ARRAY_BUFFER)).to.be(Float32Array);
|
||||||
|
expect(getArrayClassForType(ELEMENT_ARRAY_BUFFER)).to.be(Uint32Array);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the correct typed array constructor (without OES uint extension)', function() {
|
||||||
|
WEBGL_EXTENSIONS.length = 0;
|
||||||
|
expect(getArrayClassForType(ELEMENT_ARRAY_BUFFER)).to.be(Uint16Array);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('populate methods', function() {
|
||||||
|
|
||||||
let b;
|
let b;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
b = new WebGLArrayBuffer();
|
b = new WebGLArrayBuffer(ARRAY_BUFFER);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getArray', function() {
|
it('initializes the array using a size', function() {
|
||||||
|
b.ofSize(12);
|
||||||
|
expect(b.getArray().length).to.be(12);
|
||||||
|
expect(b.getArray()[0]).to.be(0);
|
||||||
|
expect(b.getArray()[11]).to.be(0);
|
||||||
|
});
|
||||||
|
|
||||||
it('returns an empty array', function() {
|
it('initializes the array using an array', function() {
|
||||||
expect(b.getArray()).to.be.empty();
|
b.fromArray([1, 2, 3, 4, 5]);
|
||||||
});
|
expect(b.getArray().length).to.be(5);
|
||||||
|
expect(b.getArray()[0]).to.be(1);
|
||||||
|
expect(b.getArray()[1]).to.be(2);
|
||||||
|
expect(b.getArray()[2]).to.be(3);
|
||||||
|
expect(b.getArray()[3]).to.be(4);
|
||||||
|
expect(b.getArray()[4]).to.be(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('initializes the array using a size', function() {
|
||||||
|
const a = Float32Array.of(1, 2, 3, 4, 5);
|
||||||
|
b.fromArrayBuffer(a.buffer);
|
||||||
|
expect(b.getArray().length).to.be(5);
|
||||||
|
expect(b.getArray()[0]).to.be(1);
|
||||||
|
expect(b.getArray()[1]).to.be(2);
|
||||||
|
expect(b.getArray()[2]).to.be(3);
|
||||||
|
expect(b.getArray()[3]).to.be(4);
|
||||||
|
expect(b.getArray()[4]).to.be(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user