Files
openlayers/src/ol/renderer/webgl-new/PointsLayer.js
2018-11-16 14:01:20 +01:00

140 lines
3.9 KiB
JavaScript

/**
* @module ol/renderer/webgl-new/PointsLayer
*/
import LayerRenderer from '../Layer';
import WebGLBuffer from '../../webgl/Buffer';
import {DYNAMIC_DRAW, ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER} from '../../webgl';
import WebGLContext, {DefaultUniform} from '../../webgl/Context';
import WebGLVertex from "../../webgl/Vertex";
import WebGLFragment from "../../webgl/Fragment";
const VERTEX_SHADER = `
attribute vec2 a_position;
attribute vec2 a_texCoord;
attribute float a_opacity;
attribute float a_rotateWithView;
uniform mat4 u_projectionMatrix;
uniform mat4 u_offsetScaleMatrix;
uniform mat4 u_offsetRotateMatrix;
varying vec2 v_texCoord;
varying float v_opacity;
void main(void) {
mat4 offsetMatrix = u_offsetScaleMatrix;
if (a_rotateWithView == 1.0) {
offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;
}
vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
v_texCoord = a_texCoord;
v_opacity = a_opacity;
}`;
const FRAGMENT_SHADER = `
uniform float u_opacity;
uniform sampler2D u_image;
varying vec2 v_texCoord;
varying float v_opacity;
void main(void) {
vec4 texColor = texture2D(u_image, v_texCoord);
gl_FragColor.rgb = texColor.rgb;
float alpha = texColor.a * v_opacity * u_opacity;
if (alpha == 0.0) {
discard;
}
gl_FragColor.a = alpha;
}`;
/**
* @classdesc
* Webgl vector renderer optimized for points.
* All features will be rendered as points.
* @api
*/
class WebGLPointsLayerRenderer extends LayerRenderer {
/**
* @param {import("../../layer/Vector.js").default} vectorLayer Vector layer.
*/
constructor(vectorLayer) {
super(vectorLayer);
this.element_ = document.createElement('canvas');
this.context_ = new WebGLContext(this.element_);
this.sourceRevision_ = -1;
this.primitiveCount_ = 0;
this.verticesBuffer_ = new WebGLBuffer([], DYNAMIC_DRAW);
this.indicesBuffer_ = new WebGLBuffer([], DYNAMIC_DRAW);
const vertexShader = new WebGLVertex(VERTEX_SHADER);
const fragmentShader = new WebGLFragment(FRAGMENT_SHADER);
const program = this.context_.getProgram(fragmentShader, vertexShader);
this.context_.useProgram(program);
}
/**
* @inheritDoc
*/
disposeInternal() {
super.disposeInternal();
}
/**
* @inheritDoc
*/
composeFrame(frameState) {
this.context_.applyFrameState(frameState);
this.context_.setUniformFloatValue(DefaultUniform.OPACITY, this.getLayer().getOpacity());
this.context_.drawElements(0, this.primitiveCount_ * 3);
}
/**
* @inheritDoc
*/
prepareFrame(frameState) {
const vectorLayer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
const vectorSource = /** @type {import("../../source/Vector.js").default} */ (vectorLayer.getSource());
if (this.sourceRevision_ >= vectorSource.getRevision()) {
return false;
}
this.sourceRevision_ = vectorSource.getRevision();
// loop on features to fill the buffer
// vectorSource.loadFeatures(extent, resolution, projection);
vectorSource.forEachFeature((feature) => {
let x = 0, y = 0, size = 0;
let baseIndex = this.verticesBuffer_.getArray().length / 3;
// todo: put data in buffer
this.verticesBuffer_.getArray().push(
x - size / 2, y - size / 2,
x + size / 2, y - size / 2,
x + size / 2, y + size / 2,
x - size / 2, y + size / 2,
);
this.indicesBuffer_.getArray().push(
baseIndex, baseIndex + 1, baseIndex + 3,
baseIndex + 1, baseIndex + 2, baseIndex + 3
);
this.primitiveCount_++;
});
// write new data
this.context_.bindBuffer(ARRAY_BUFFER, this.verticesBuffer_);
this.context_.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer_);
return true;
}
}
export default WebGLPointsLayerRenderer;