Webgl / add utils for pushing geojson geometries in webgl buffers
For now only point geometries are handled.
This commit is contained in:
@@ -59,6 +59,75 @@ class WebGLLayerRenderer extends LayerRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes vertices and indices in the given buffers using the geometry coordinates and the following properties
|
||||||
|
* from the feature:
|
||||||
|
* - `color`
|
||||||
|
* - `opacity`
|
||||||
|
* - `size` (for points)
|
||||||
|
* - `u0`, `v0`, `u1`, `v1` (for points)
|
||||||
|
* - `rotateWithView` (for points)
|
||||||
|
* - `width` (for lines)
|
||||||
|
* Custom attributes can be designated using the `opt_attributes` argument, otherwise other properties on the
|
||||||
|
* feature will be ignored.
|
||||||
|
* @param {import("../../webgl/Buffer").default} vertexBuffer WebGL buffer in which new vertices will be pushed.
|
||||||
|
* @param {import("../../webgl/Buffer").default} indexBuffer WebGL buffer in which new indices will be pushed.
|
||||||
|
* @param {import("../../format/GeoJSON").GeoJSONFeature} geojsonFeature Feature in geojson format, coordinates
|
||||||
|
* expressed in EPSG:4326.
|
||||||
|
* @param {Array<string>} [opt_attributes] Custom attributes. An array of properties which will be read from the
|
||||||
|
* feature and pushed in the buffer in the given order.
|
||||||
|
*/
|
||||||
|
export function pushFeatureInBuffer(vertexBuffer, indexBuffer, geojsonFeature, opt_attributes) {
|
||||||
|
if (!geojsonFeature.geometry) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch(geojsonFeature.geometry.type) {
|
||||||
|
case "Point":
|
||||||
|
pushPointGeomInBuffer_(vertexBuffer, indexBuffer, geojsonFeature, opt_attributes)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes a quad (two triangles) based on a point geometry
|
||||||
|
* @param vertexBuffer
|
||||||
|
* @param indexBuffer
|
||||||
|
* @param geojsonFeature
|
||||||
|
* @param opt_attributes
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function pushPointGeomInBuffer_(vertexBuffer, indexBuffer, geojsonFeature, opt_attributes) {
|
||||||
|
const stride = 12 + (opt_attributes !== undefined ? opt_attributes.length : 0);
|
||||||
|
|
||||||
|
const x = geojsonFeature.geometry.coordinates[0];
|
||||||
|
const y = geojsonFeature.geometry.coordinates[1];
|
||||||
|
const u0 = geojsonFeature.properties.u0;
|
||||||
|
const v0 = geojsonFeature.properties.v0;
|
||||||
|
const u1 = geojsonFeature.properties.u1;
|
||||||
|
const v1 = geojsonFeature.properties.v1;
|
||||||
|
const size = geojsonFeature.properties.size;
|
||||||
|
const opacity = geojsonFeature.properties.opacity;
|
||||||
|
const rotateWithView = geojsonFeature.properties.rotateWithView;
|
||||||
|
const color = geojsonFeature.properties.color;
|
||||||
|
const red = color[0];
|
||||||
|
const green = color[1];
|
||||||
|
const blue = color[2];
|
||||||
|
const alpha = color[3];
|
||||||
|
const baseIndex = vertexBuffer.getArray().length / stride;
|
||||||
|
|
||||||
|
vertexBuffer.getArray().push(
|
||||||
|
x, y, -size / 2, -size / 2, u0, v0, opacity, rotateWithView, red, green, blue, alpha,
|
||||||
|
x, y, +size / 2, -size / 2, u1, v0, opacity, rotateWithView, red, green, blue, alpha,
|
||||||
|
x, y, +size / 2, +size / 2, u1, v1, opacity, rotateWithView, red, green, blue, alpha,
|
||||||
|
x, y, -size / 2, +size / 2, u0, v1, opacity, rotateWithView, red, green, blue, alpha
|
||||||
|
);
|
||||||
|
indexBuffer.getArray().push(
|
||||||
|
baseIndex, baseIndex + 1, baseIndex + 3,
|
||||||
|
baseIndex + 1, baseIndex + 2, baseIndex + 3
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a texture of 1x1 pixel, white
|
* Returns a texture of 1x1 pixel, white
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import VectorLayer from '../../../../../src/ol/layer/Vector.js';
|
import WebGLLayerRenderer, {getBlankTexture, pushFeatureInBuffer} from '../../../../../src/ol/renderer/webgl/Layer';
|
||||||
import VectorSource from '../../../../../src/ol/source/Vector.js';
|
import WebGLArrayBuffer from '../../../../../src/ol/webgl/Buffer';
|
||||||
import WebGLLayerRenderer, {getBlankTexture} from '../../../../../src/ol/renderer/webgl/Layer';
|
import Layer from '../../../../../src/ol/layer/Layer';
|
||||||
|
|
||||||
|
|
||||||
describe('ol.renderer.webgl.Layer', function() {
|
describe('ol.renderer.webgl.Layer', function() {
|
||||||
@@ -21,15 +21,94 @@ describe('ol.renderer.webgl.Layer', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates a new instance', function () {
|
it('creates a new instance', function () {
|
||||||
const layer = new VectorLayer({
|
const layer = new Layer({});
|
||||||
source: new VectorSource()
|
|
||||||
});
|
|
||||||
const renderer = new WebGLLayerRenderer(layer);
|
const renderer = new WebGLLayerRenderer(layer);
|
||||||
expect(renderer).to.be.a(WebGLLayerRenderer);
|
expect(renderer).to.be.a(WebGLLayerRenderer);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('pushFeatureInBuffer', function() {
|
||||||
|
let vertexBuffer, indexBuffer;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
vertexBuffer = new WebGLArrayBuffer();
|
||||||
|
indexBuffer = new WebGLArrayBuffer();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does nothing if the feature has no geometry', function() {
|
||||||
|
const feature = {
|
||||||
|
type: "Feature",
|
||||||
|
id: "AFG",
|
||||||
|
properties: {
|
||||||
|
color:[0.5, 1, 0.2, 0.7],
|
||||||
|
size: 3
|
||||||
|
},
|
||||||
|
geometry: null
|
||||||
|
};
|
||||||
|
pushFeatureInBuffer(vertexBuffer, indexBuffer, feature);
|
||||||
|
expect(vertexBuffer.getArray().length).to.eql(0);
|
||||||
|
expect(indexBuffer.getArray().length).to.eql(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds two triangles with the correct attributes for a point geometry', function() {
|
||||||
|
const feature = {
|
||||||
|
type: "Feature",
|
||||||
|
id: "AFG",
|
||||||
|
properties: {
|
||||||
|
color:[0.5, 1, 0.2, 0.7],
|
||||||
|
size: 3
|
||||||
|
},
|
||||||
|
geometry: {
|
||||||
|
type: "Point",
|
||||||
|
coordinates: [ -75, 47 ]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const attributePerVertex = 12;
|
||||||
|
pushFeatureInBuffer(vertexBuffer, indexBuffer, feature);
|
||||||
|
expect(vertexBuffer.getArray().length).to.eql(attributePerVertex * 4);
|
||||||
|
expect(indexBuffer.getArray().length).to.eql(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('correctly sets indices & coordinates for several features', function() {
|
||||||
|
const feature = {
|
||||||
|
type: "Feature",
|
||||||
|
id: "AFG",
|
||||||
|
properties: {
|
||||||
|
color:[0.5, 1, 0.2, 0.7],
|
||||||
|
size: 3
|
||||||
|
},
|
||||||
|
geometry: {
|
||||||
|
type: "Point",
|
||||||
|
coordinates: [ -75, 47 ]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const attributePerVertex = 12;
|
||||||
|
pushFeatureInBuffer(vertexBuffer, indexBuffer, feature);
|
||||||
|
pushFeatureInBuffer(vertexBuffer, indexBuffer, feature);
|
||||||
|
expect(vertexBuffer.getArray()[0]).to.eql(-75);
|
||||||
|
expect(vertexBuffer.getArray()[1]).to.eql(47);
|
||||||
|
expect(vertexBuffer.getArray()[0 + attributePerVertex]).to.eql(-75);
|
||||||
|
expect(vertexBuffer.getArray()[1 + attributePerVertex]).to.eql(47);
|
||||||
|
|
||||||
|
// first point
|
||||||
|
expect(indexBuffer.getArray()[0]).to.eql(0);
|
||||||
|
expect(indexBuffer.getArray()[1]).to.eql(1);
|
||||||
|
expect(indexBuffer.getArray()[2]).to.eql(3);
|
||||||
|
expect(indexBuffer.getArray()[3]).to.eql(1);
|
||||||
|
expect(indexBuffer.getArray()[4]).to.eql(2);
|
||||||
|
expect(indexBuffer.getArray()[5]).to.eql(3);
|
||||||
|
|
||||||
|
// second point
|
||||||
|
expect(indexBuffer.getArray()[6]).to.eql(4);
|
||||||
|
expect(indexBuffer.getArray()[7]).to.eql(5);
|
||||||
|
expect(indexBuffer.getArray()[8]).to.eql(7);
|
||||||
|
expect(indexBuffer.getArray()[9]).to.eql(5);
|
||||||
|
expect(indexBuffer.getArray()[10]).to.eql(6);
|
||||||
|
expect(indexBuffer.getArray()[11]).to.eql(7);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('getBlankTexture', function() {
|
describe('getBlankTexture', function() {
|
||||||
it('creates a 1x1 white texture', function() {
|
it('creates a 1x1 white texture', function() {
|
||||||
const texture = getBlankTexture();
|
const texture = getBlankTexture();
|
||||||
|
|||||||
Reference in New Issue
Block a user