From 583dfb8e9d521a381a6ef7299ef60148380358fe Mon Sep 17 00:00:00 2001 From: Olivier Guyot Date: Wed, 14 Nov 2018 18:19:23 +0100 Subject: [PATCH] Actually make the renderer work --- src/ol/renderer/webgl-new/PointsLayer.js | 83 ++++++++++++------------ src/ol/webgl/Context.js | 42 +++++++----- 2 files changed, 67 insertions(+), 58 deletions(-) diff --git a/src/ol/renderer/webgl-new/PointsLayer.js b/src/ol/renderer/webgl-new/PointsLayer.js index 051accba9f..ae3ac814fc 100644 --- a/src/ol/renderer/webgl-new/PointsLayer.js +++ b/src/ol/renderer/webgl-new/PointsLayer.js @@ -13,7 +13,6 @@ const VERTEX_SHADER = ` precision mediump float; attribute vec2 a_position; attribute vec2 a_texCoord; - attribute float a_opacity; attribute float a_rotateWithView; attribute vec2 a_offsets; @@ -22,7 +21,6 @@ const VERTEX_SHADER = ` uniform mat4 u_offsetRotateMatrix; varying vec2 v_texCoord; - varying float v_opacity; void main(void) { mat4 offsetMatrix = u_offsetScaleMatrix; @@ -32,21 +30,17 @@ const VERTEX_SHADER = ` 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 = ` precision mediump float; 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; + gl_FragColor.rgb = vec3(1.0, 1.0, 1.0); + float alpha = u_opacity; if (alpha == 0.0) { discard; } @@ -73,8 +67,6 @@ class WebGLPointsLayerRenderer extends LayerRenderer { this.sourceRevision_ = -1; - this.primitiveCount_ = 0; - this.verticesBuffer_ = new WebGLBuffer([], DYNAMIC_DRAW); this.indicesBuffer_ = new WebGLBuffer([], DYNAMIC_DRAW); @@ -95,9 +87,10 @@ class WebGLPointsLayerRenderer extends LayerRenderer { * @inheritDoc */ composeFrame(frameState) { + this.context_.prepareDraw(); this.context_.applyFrameState(frameState); this.context_.setUniformFloatValue(DefaultUniform.OPACITY, this.getLayer().getOpacity()); - this.context_.drawElements(0, this.primitiveCount_ * 3); + this.context_.drawElements(0, this.indicesBuffer_.getArray().length); } /** @@ -107,38 +100,44 @@ class WebGLPointsLayerRenderer extends LayerRenderer { 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; + if (this.sourceRevision_ < vectorSource.getRevision()) { + this.sourceRevision_ = vectorSource.getRevision(); + + const viewState = frameState.viewState; + const projection = viewState.projection; + const resolution = viewState.resolution; + + // loop on features to fill the buffer + vectorSource.loadFeatures([-Infinity, -Infinity, Infinity, Infinity], resolution, projection); + vectorSource.forEachFeature((feature) => { + if (!feature.getGeometry() || feature.getGeometry().getType() !== GeometryType.POINT) { + return; + } + const geom = /** @type {import("../../geom/Point").default} */ (feature.getGeometry()); + const x = geom.getCoordinates()[0], y = geom.getCoordinates()[1], size = 20; + let stride = 4; + let baseIndex = this.verticesBuffer_.getArray().length / stride; + + this.verticesBuffer_.getArray().push( + x, y, -size / 2, -size / 2, + x, y, +size / 2, -size / 2, + x, y, +size / 2, +size / 2, + x, y, -size / 2, +size / 2, + ); + this.indicesBuffer_.getArray().push( + baseIndex, baseIndex + 1, baseIndex + 3, + baseIndex + 1, baseIndex + 2, baseIndex + 3 + ); + }); + + // write new data + this.context_.bindBuffer(ARRAY_BUFFER, this.verticesBuffer_); + this.context_.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer_); + + let bytesPerFloat = Float32Array.BYTES_PER_ELEMENT; + this.context_.enableAttributeArray(DefaultAttrib.POSITION, 2, FLOAT, bytesPerFloat * 4, 0); + this.context_.enableAttributeArray(DefaultAttrib.OFFSETS, 2, FLOAT, bytesPerFloat * 4, bytesPerFloat * 2); } - this.sourceRevision_ = vectorSource.getRevision(); - - // loop on features to fill the buffer - // vectorSource.loadFeatures(extent, resolution, projection); - vectorSource.forEachFeature((feature) => { - if (!feature.getGeometry() || feature.getGeometry().getType() !== GeometryType.POINT) { - return; - } - const geom = /** @type {import("../../geom/Point").default} */ (feature.getGeometry()); - const x = geom.getCoordinates()[0], y = geom.getCoordinates()[1], size = 1; - let baseIndex = this.verticesBuffer_.getArray().length / 3; - - 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_); - this.context_.enableAttributeArray(DefaultAttrib.POSITION, 2, FLOAT, 0, 0); return true; } diff --git a/src/ol/webgl/Context.js b/src/ol/webgl/Context.js index 53d9b938c1..af9054472a 100644 --- a/src/ol/webgl/Context.js +++ b/src/ol/webgl/Context.js @@ -9,7 +9,7 @@ import {listen, unlistenAll} from '../events.js'; import {clear} from '../obj.js'; import {ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, TEXTURE_2D, TEXTURE_WRAP_S, TEXTURE_WRAP_T} from '../webgl.js'; import ContextEventType from '../webgl/ContextEventType.js'; -import {FLOAT, TRIANGLES, UNSIGNED_INT, UNSIGNED_SHORT} from "../webgl"; +import {COLOR_BUFFER_BIT, FLOAT, TRIANGLES, UNSIGNED_INT, UNSIGNED_SHORT} from "../webgl"; import { create as createTransform, reset as resetTransform, @@ -153,25 +153,23 @@ class WebGLContext extends Disposable { const gl = this.getGL(); const arr = buf.getArray(); const bufferKey = getUid(buf); - if (bufferKey in this.bufferCache_) { - const bufferCacheEntry = this.bufferCache_[bufferKey]; - gl.bindBuffer(target, bufferCacheEntry.buffer); - } else { + let bufferCache = this.bufferCache_[bufferKey]; + if (!bufferCache) { const buffer = gl.createBuffer(); - gl.bindBuffer(target, buffer); - let /** @type {ArrayBufferView} */ arrayBuffer; - if (target == ARRAY_BUFFER) { - arrayBuffer = new Float32Array(arr); - } else if (target == ELEMENT_ARRAY_BUFFER) { - arrayBuffer = this.hasOESElementIndexUint ? - new Uint32Array(arr) : new Uint16Array(arr); - } - gl.bufferData(target, arrayBuffer, buf.getUsage()); - this.bufferCache_[bufferKey] = { + bufferCache = this.bufferCache_[bufferKey] = { buf: buf, buffer: buffer }; } + gl.bindBuffer(target, bufferCache.buffer); + let /** @type {ArrayBufferView} */ arrayBuffer; + if (target == ARRAY_BUFFER) { + arrayBuffer = new Float32Array(arr); + } else if (target == ELEMENT_ARRAY_BUFFER) { + arrayBuffer = this.hasOESElementIndexUint ? + new Uint32Array(arr) : new Uint16Array(arr); + } + gl.bufferData(target, arrayBuffer, buf.getUsage()); } /** @@ -206,6 +204,15 @@ class WebGLContext extends Disposable { } } + /** + * Clear the buffer & set the viewport to draw + */ + prepareDraw() { + this.getGL().clearColor(0.0, 0.0, 0.0, 0.0); + this.getGL().clear(this.getGL().COLOR_BUFFER_BIT); + this.getGL().viewport(0, 0, this.canvas_.width, this.canvas_.height); + } + /** * @protected * @param {number} start Start index. @@ -359,12 +366,13 @@ class WebGLContext extends Disposable { * @param {string} attribName * @param {number} size Number of components per attributes * @param {number} type UNSIGNED_INT, UNSIGNED_BYTE, UNSIGNED_SHORT or FLOAT + * @param {number} stride Stride in bytes (0 means attribs are packed) * @param {number} offset Offset in bytes */ enableAttributeArray(attribName, size, type, stride, offset) { this.getGL().enableVertexAttribArray(this.getAttributeLocation(attribName)); this.getGL().vertexAttribPointer(this.getAttributeLocation(attribName), size, type, - false, 0, offset); + false, stride, offset); } /** @@ -401,6 +409,8 @@ class WebGLContext extends Disposable { return true; } } + + // TODO: shutdown program }