* A worker that does cpu-heavy tasks related to webgl rendering.
* @module ol/worker/webgl
*/
import {
writeLineSegmentToBuffers,
writePointFeatureToBuffers,
writePolygonTrianglesToBuffers,
} from '../render/webgl/bufferUtil.js';
import {WebGLWorkerMessageType} from '../render/webgl/constants.js';
import {
create as createTransform,
makeInverse as makeInverseTransform,
} from '../transform.js';
const worker = self;
worker.onmessage = (event) => {
const received = event.data;
switch (received.type) {
case WebGLWorkerMessageType.GENERATE_POINT_BUFFERS: {
const baseIndicesAttrsCount = 2;
const baseInstructionsCount = 2;
const customAttrsCount = received.customAttributesSize;
const instructionsCount = baseInstructionsCount + customAttrsCount;
const renderInstructions = new Float32Array(received.renderInstructions);
const elementsCount = renderInstructions.length / instructionsCount;
const instanceAttributesCount =
elementsCount * (baseIndicesAttrsCount + customAttrsCount);
const indicesBuffer = Uint32Array.from([0, 1, 3, 1, 2, 3]);
const vertexAttributesBuffer = Float32Array.from([
-1, -1, 1, -1, 1, 1, -1, 1,
]);
const instanceAttributesBuffer = new Float32Array(
instanceAttributesCount,
);
let bufferPositions;
for (let i = 0; i < renderInstructions.length; i += instructionsCount) {
bufferPositions = writePointFeatureToBuffers(
renderInstructions,
i,
instanceAttributesBuffer,
customAttrsCount,
bufferPositions,
);
}
const message = Object.assign(
{
indicesBuffer: indicesBuffer.buffer,
vertexAttributesBuffer: vertexAttributesBuffer.buffer,
instanceAttributesBuffer: instanceAttributesBuffer.buffer,
renderInstructions: renderInstructions.buffer,
},
received,
);
worker.postMessage(message, [
vertexAttributesBuffer.buffer,
instanceAttributesBuffer.buffer,
indicesBuffer.buffer,
renderInstructions.buffer,
]);
break;
}
case WebGLWorkerMessageType.GENERATE_LINE_STRING_BUFFERS: {
const instanceAttributes = [];
const customAttrsCount = received.customAttributesSize;
const instructionsPerVertex = 3;
const renderInstructions = new Float32Array(received.renderInstructions);
let currentInstructionsIndex = 0;
const transform = received.renderInstructionsTransform;
const invertTransform = createTransform();
makeInverseTransform(invertTransform, transform);
let verticesCount, customAttributes;
while (currentInstructionsIndex < renderInstructions.length) {
customAttributes = Array.from(
renderInstructions.slice(
currentInstructionsIndex,
currentInstructionsIndex + customAttrsCount,
),
);
currentInstructionsIndex += customAttrsCount;
verticesCount = renderInstructions[currentInstructionsIndex++];
const firstInstructionsIndex = currentInstructionsIndex;
const lastInstructionsIndex =
currentInstructionsIndex +
(verticesCount - 1) * instructionsPerVertex;
const isLoop =
renderInstructions[firstInstructionsIndex] ===
renderInstructions[lastInstructionsIndex] &&
renderInstructions[firstInstructionsIndex + 1] ===
renderInstructions[lastInstructionsIndex + 1];
let currentLength = 0;
let currentAngleTangentSum = 0;
for (let i = 0; i < verticesCount - 1; i++) {
let beforeIndex = null;
if (i > 0) {
beforeIndex =
currentInstructionsIndex + (i - 1) * instructionsPerVertex;
} else if (isLoop) {
beforeIndex = lastInstructionsIndex - instructionsPerVertex;
}
let afterIndex = null;
if (i < verticesCount - 2) {
afterIndex =
currentInstructionsIndex + (i + 2) * instructionsPerVertex;
} else if (isLoop) {
afterIndex = firstInstructionsIndex + instructionsPerVertex;
}
const measures = writeLineSegmentToBuffers(
renderInstructions,
currentInstructionsIndex + i * instructionsPerVertex,
currentInstructionsIndex + (i + 1) * instructionsPerVertex,
beforeIndex,
afterIndex,
instanceAttributes,
customAttributes,
invertTransform,
currentLength,
currentAngleTangentSum,
);
currentLength = measures.length;
currentAngleTangentSum = measures.angle;
}
currentInstructionsIndex += verticesCount * instructionsPerVertex;
}
const indicesBuffer = Uint32Array.from([0, 1, 3, 1, 2, 3]);
const vertexAttributesBuffer = Float32Array.from([
-1, -1, 1, -1, 1, 1, -1, 1,
]);
const instanceAttributesBuffer = Float32Array.from(instanceAttributes);
const message = Object.assign(
{
indicesBuffer: indicesBuffer.buffer,
vertexAttributesBuffer: vertexAttributesBuffer.buffer,
instanceAttributesBuffer: instanceAttributesBuffer.buffer,
renderInstructions: renderInstructions.buffer,
},
received,
);
worker.postMessage(message, [
vertexAttributesBuffer.buffer,
instanceAttributesBuffer.buffer,
indicesBuffer.buffer,
renderInstructions.buffer,
]);
break;
}
case WebGLWorkerMessageType.GENERATE_POLYGON_BUFFERS: {
const vertices = [];
const indices = [];
const customAttrsCount = received.customAttributesSize;
const renderInstructions = new Float32Array(received.renderInstructions);
let currentInstructionsIndex = 0;
while (currentInstructionsIndex < renderInstructions.length) {
currentInstructionsIndex = writePolygonTrianglesToBuffers(
renderInstructions,
currentInstructionsIndex,
vertices,
indices,
customAttrsCount,
);
}
const indicesBuffer = Uint32Array.from(indices);
const vertexAttributesBuffer = Float32Array.from(vertices);
const instanceAttributesBuffer = Float32Array.from([]);
const message = Object.assign(
{
indicesBuffer: indicesBuffer.buffer,
vertexAttributesBuffer: vertexAttributesBuffer.buffer,
instanceAttributesBuffer: instanceAttributesBuffer.buffer,
renderInstructions: renderInstructions.buffer,
},
received,
);
worker.postMessage(message, [
vertexAttributesBuffer.buffer,
instanceAttributesBuffer.buffer,
indicesBuffer.buffer,
renderInstructions.buffer,
]);
break;
}
default:
}
};
export let create;