120 lines
3.8 KiB
JavaScript
120 lines
3.8 KiB
JavaScript
/**
|
|
* @module ol/render/webgl/LineStringBatchRenderer
|
|
*/
|
|
import AbstractBatchRenderer from './BatchRenderer.js';
|
|
import {AttributeType} from '../../webgl/Helper.js';
|
|
import {transform2D} from '../../geom/flat/transform.js';
|
|
|
|
/**
|
|
* Names of attributes made available to the vertex shader.
|
|
* Please note: changing these *will* break custom shaders!
|
|
* @enum {string}
|
|
*/
|
|
export const Attributes = {
|
|
SEGMENT_START: 'a_segmentStart',
|
|
SEGMENT_END: 'a_segmentEnd',
|
|
PARAMETERS: 'a_parameters',
|
|
};
|
|
|
|
class LineStringBatchRenderer extends AbstractBatchRenderer {
|
|
/**
|
|
* @param {import("../../webgl/Helper.js").default} helper WebGL helper instance
|
|
* @param {Worker} worker WebGL worker instance
|
|
* @param {string} vertexShader Vertex shader
|
|
* @param {string} fragmentShader Fragment shader
|
|
* @param {Array<import('./BatchRenderer.js').CustomAttribute>} customAttributes List of custom attributes
|
|
*/
|
|
constructor(helper, worker, vertexShader, fragmentShader, customAttributes) {
|
|
super(helper, worker, vertexShader, fragmentShader, customAttributes);
|
|
|
|
// vertices for lines must hold both a position (x,y) and an offset (dx,dy)
|
|
this.attributes = [
|
|
{
|
|
name: Attributes.SEGMENT_START,
|
|
size: 2,
|
|
type: AttributeType.FLOAT,
|
|
},
|
|
{
|
|
name: Attributes.SEGMENT_END,
|
|
size: 2,
|
|
type: AttributeType.FLOAT,
|
|
},
|
|
{
|
|
name: Attributes.PARAMETERS,
|
|
size: 1,
|
|
type: AttributeType.FLOAT,
|
|
},
|
|
].concat(
|
|
customAttributes.map(function (attribute) {
|
|
return {
|
|
name: 'a_' + attribute.name,
|
|
size: 1,
|
|
type: AttributeType.FLOAT,
|
|
};
|
|
})
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Render instructions for lines are structured like so:
|
|
* [ customAttr0, ... , customAttrN, numberOfVertices0, x0, y0, ... , xN, yN, numberOfVertices1, ... ]
|
|
* @param {import("./MixedGeometryBatch.js").LineStringGeometryBatch} batch Linestring geometry batch
|
|
* @override
|
|
*/
|
|
generateRenderInstructions(batch) {
|
|
// here we anticipate the amount of render instructions for lines:
|
|
// 2 instructions per vertex for position (x and y)
|
|
// + 1 instruction per line per custom attributes
|
|
// + 1 instruction per line (for vertices count)
|
|
const totalInstructionsCount =
|
|
2 * batch.verticesCount +
|
|
(1 + this.customAttributes.length) * batch.geometriesCount;
|
|
if (
|
|
!batch.renderInstructions ||
|
|
batch.renderInstructions.length !== totalInstructionsCount
|
|
) {
|
|
batch.renderInstructions = new Float32Array(totalInstructionsCount);
|
|
}
|
|
|
|
// loop on features to fill the render instructions
|
|
let batchEntry;
|
|
const flatCoords = [];
|
|
let renderIndex = 0;
|
|
let value;
|
|
for (const featureUid in batch.entries) {
|
|
batchEntry = batch.entries[featureUid];
|
|
for (let i = 0, ii = batchEntry.flatCoordss.length; i < ii; i++) {
|
|
flatCoords.length = batchEntry.flatCoordss[i].length;
|
|
transform2D(
|
|
batchEntry.flatCoordss[i],
|
|
0,
|
|
flatCoords.length,
|
|
2,
|
|
batch.renderInstructionsTransform,
|
|
flatCoords
|
|
);
|
|
|
|
// custom attributes
|
|
for (let k = 0, kk = this.customAttributes.length; k < kk; k++) {
|
|
value = this.customAttributes[k].callback(
|
|
batchEntry.feature,
|
|
batchEntry.properties
|
|
);
|
|
batch.renderInstructions[renderIndex++] = value;
|
|
}
|
|
|
|
// vertices count
|
|
batch.renderInstructions[renderIndex++] = flatCoords.length / 2;
|
|
|
|
// looping on points for positions
|
|
for (let j = 0, jj = flatCoords.length; j < jj; j += 2) {
|
|
batch.renderInstructions[renderIndex++] = flatCoords[j];
|
|
batch.renderInstructions[renderIndex++] = flatCoords[j + 1];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export default LineStringBatchRenderer;
|