From 46aa577510c33d4fc3372a0317327be4521fb227 Mon Sep 17 00:00:00 2001 From: kikuchan Date: Sun, 4 May 2025 13:46:18 +0900 Subject: [PATCH 1/3] Update the test for WebGLVector layer with useGeographic --- .../webgl-vector-geographic/expected.png | Bin 4730 -> 4494 bytes .../cases/webgl-vector-geographic/main.js | 41 ++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/test/rendering/cases/webgl-vector-geographic/expected.png b/test/rendering/cases/webgl-vector-geographic/expected.png index 58092a5ad096e52ab12993a1494c68f517203fee..df3c04d9c4ef936004363e1f02a43322aac448fa 100644 GIT binary patch literal 4494 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 literal 4730 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 diff --git a/test/rendering/cases/webgl-vector-geographic/main.js b/test/rendering/cases/webgl-vector-geographic/main.js index 086add0f90f..fb93e5a0fa8 100644 --- a/test/rendering/cases/webgl-vector-geographic/main.js +++ b/test/rendering/cases/webgl-vector-geographic/main.js @@ -1,6 +1,7 @@ import Map from '../../../../src/ol/Map.js'; import View from '../../../../src/ol/View.js'; import GeoJSON from '../../../../src/ol/format/GeoJSON.js'; +import Polygon from '../../../../src/ol/geom/Polygon.js'; import WebGLVectorLayer from '../../../../src/ol/layer/WebGLVector.js'; import {useGeographic} from '../../../../src/ol/proj.js'; import VectorSource from '../../../../src/ol/source/Vector.js'; @@ -12,6 +13,23 @@ const features = format.readFeatures({ type: 'FeatureCollection', features: [ { + // for case 1: initially placed geometries should be transformed properly + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [0, -65], + [100, 0], + [0, 65], + [-100, 0], + [0, -65], + ], + ], + }, + }, + { + // for case 2: geometries changed after initial rendering should be transformed properly too type: 'Feature', geometry: { type: 'Polygon', @@ -40,7 +58,7 @@ const vector = new WebGLVectorLayer({ }, }); -new Map({ +const map = new Map({ layers: [vector], target: 'map', view: new View({ @@ -49,7 +67,22 @@ new Map({ }), }); -render({ - message: - 'Geometries using geographic coordinates are transformed before rendering', +map.once('rendercomplete', function () { + // case2: update geometry after initial rendering + features[1].setGeometry( + new Polygon([ + [ + [-100, 65], + [0, 65], + [-100, 0], + [-100, 65], + ], + ]), + ); + map.renderSync(); + + render({ + message: + 'Geometries using geographic coordinates are always transformed properly', + }); }); From 382bf3f7a48e102c0a7de6d051007b3a7fd35636 Mon Sep 17 00:00:00 2001 From: kikuchan Date: Sun, 4 May 2025 13:30:28 +0900 Subject: [PATCH 2/3] Fix CHANGEFEATURE event handler in WebGLVectorLayerRenderer for useGeographic This also adds missing projectionTransform to changeFeature in MixedGeometryBatch along with tests. --- src/ol/render/webgl/MixedGeometryBatch.js | 9 ++++-- src/ol/renderer/webgl/VectorLayer.js | 7 +++-- .../render/webgl/MixedGeometryBatch.test.js | 31 +++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/ol/render/webgl/MixedGeometryBatch.js b/src/ol/render/webgl/MixedGeometryBatch.js index 02e6894865a..51f8cc0c862 100644 --- a/src/ol/render/webgl/MixedGeometryBatch.js +++ b/src/ol/render/webgl/MixedGeometryBatch.js @@ -519,17 +519,22 @@ class MixedGeometryBatch { /** * @param {Feature|RenderFeature} feature Feature + * @param {import("../../proj.js").TransformFunction} [projectionTransform] Projection transform. */ - changeFeature(feature) { + changeFeature(feature, projectionTransform) { // the feature is not present in the batch; do not add it to avoid unexpected behaviors if (!this.uidToRef_.get(getUid(feature))) { return; } this.removeFeature(feature); - const geometry = feature.getGeometry(); + let geometry = feature.getGeometry(); if (!geometry) { return; } + if (projectionTransform) { + geometry = geometry.clone(); + geometry.applyTransform(projectionTransform); + } this.addGeometry_(geometry, feature); } diff --git a/src/ol/renderer/webgl/VectorLayer.js b/src/ol/renderer/webgl/VectorLayer.js index d968a5a30d6..09d91195831 100644 --- a/src/ol/renderer/webgl/VectorLayer.js +++ b/src/ol/renderer/webgl/VectorLayer.js @@ -211,7 +211,7 @@ class WebGLVectorLayerRenderer extends WebGLLayerRenderer { listen( source, VectorEventType.CHANGEFEATURE, - this.handleSourceFeatureChanged_, + this.handleSourceFeatureChanged_.bind(this, projectionTransform), this, ), listen( @@ -295,12 +295,13 @@ class WebGLVectorLayerRenderer extends WebGLLayerRenderer { } /** + * @param {import("../../proj.js").TransformFunction} projectionTransform Transform function. * @param {import("../../source/Vector.js").VectorSourceEvent} event Event. * @private */ - handleSourceFeatureChanged_(event) { + handleSourceFeatureChanged_(projectionTransform, event) { const feature = event.feature; - this.batch_.changeFeature(feature); + this.batch_.changeFeature(feature, projectionTransform); } /** diff --git a/test/browser/spec/ol/render/webgl/MixedGeometryBatch.test.js b/test/browser/spec/ol/render/webgl/MixedGeometryBatch.test.js index fbeea68208b..2cf1dd2f313 100644 --- a/test/browser/spec/ol/render/webgl/MixedGeometryBatch.test.js +++ b/test/browser/spec/ol/render/webgl/MixedGeometryBatch.test.js @@ -8,6 +8,7 @@ import MultiPoint from '../../../../../../src/ol/geom/MultiPoint.js'; import MultiPolygon from '../../../../../../src/ol/geom/MultiPolygon.js'; import Point from '../../../../../../src/ol/geom/Point.js'; import Polygon from '../../../../../../src/ol/geom/Polygon.js'; +import {getTransform} from '../../../../../../src/ol/proj.js'; import RenderFeature from '../../../../../../src/ol/render/Feature.js'; import MixedGeometryBatch from '../../../../../../src/ol/render/webgl/MixedGeometryBatch.js'; import {getUid} from '../../../../../../src/ol/util.js'; @@ -1229,6 +1230,36 @@ describe('MixedGeometryBatch', function () { }); }); + describe('with projectionTransform', () => { + let geometry1, feature1, uid1, projectionTransform, transformedFlatCoordss; + + beforeEach(() => { + projectionTransform = getTransform('EPSG:4326', 'EPSG:3857'); + + geometry1 = new Point([135, 35]); + feature1 = new Feature({ + geometry: geometry1, + }); + + uid1 = getUid(feature1); + transformedFlatCoordss = [projectionTransform([135, 35])]; + + mixedBatch.addFeature(feature1, projectionTransform); + }); + + it('has the transformed flatCoords', () => { + expect(mixedBatch.pointBatch.entries[uid1].flatCoordss).to.eql( + transformedFlatCoordss, + ); + }); + it('has the same transformed flatCoords after changeFeature', () => { + mixedBatch.changeFeature(feature1, projectionTransform); + expect(mixedBatch.pointBatch.entries[uid1].flatCoordss).to.eql( + transformedFlatCoordss, + ); + }); + }); + describe('#clear', () => { beforeEach(() => { const feature1 = new Feature( From eb4c5c2d24fa5b9a5c8da85c7ad42997d283c428 Mon Sep 17 00:00:00 2001 From: Olivia Guyot Date: Wed, 7 May 2025 15:46:46 +0200 Subject: [PATCH 3/3] WebGL / disable all attributes when using a shader program --- src/ol/webgl/Helper.js | 19 +++++++++++++++++++ test/browser/spec/ol/webgl/helper.test.js | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/ol/webgl/Helper.js b/src/ol/webgl/Helper.js index 8614c7e2d71..f8168a62406 100644 --- a/src/ol/webgl/Helper.js +++ b/src/ol/webgl/Helper.js @@ -446,6 +446,14 @@ class WebGLHelper extends Disposable { * @private */ this.startTime_ = Date.now(); + + /** + * @type {number} + * @private + */ + this.maxAttributeCount_ = this.gl_.getParameter( + this.gl_.MAX_VERTEX_ATTRIBS, + ); } /** @@ -894,6 +902,7 @@ class WebGLHelper extends Disposable { * @param {import("../Map.js").FrameState} [frameState] Frame state. */ useProgram(program, frameState) { + this.disableAllAttributes_(); const gl = this.gl_; gl.useProgram(program); this.currentProgram_ = program; @@ -1065,6 +1074,16 @@ class WebGLHelper extends Disposable { this.gl_.uniformMatrix4fv(this.getUniformLocation(uniform), false, value); } + /** + * Disable all vertex attributes. + * @private + */ + disableAllAttributes_() { + for (let i = 0; i < this.maxAttributeCount_; i++) { + this.gl_.disableVertexAttribArray(i); + } + } + /** * Will set the currently bound buffer to an attribute of the shader program. Used by `#enableAttributes` * internally. diff --git a/test/browser/spec/ol/webgl/helper.test.js b/test/browser/spec/ol/webgl/helper.test.js index 365ec9c70f8..cd2a10788f7 100644 --- a/test/browser/spec/ol/webgl/helper.test.js +++ b/test/browser/spec/ol/webgl/helper.test.js @@ -479,4 +479,22 @@ describe('ol/webgl/WebGLHelper', function () { ]); }); }); + + describe('attributes disabling', () => { + let disableAttribSpy; + beforeEach(() => { + h = new WebGLHelper(); + disableAttribSpy = sinonSpy(h.getGL(), 'disableVertexAttribArray'); + const program = h.getProgram(FRAGMENT_SHADER, VERTEX_SHADER); + h.useProgram(program, SAMPLE_FRAMESTATE); + }); + it('all active attributes are disabled when enabling programs, disregarding of previous state', () => { + const gl = h.getGL(); + const max = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); + expect(disableAttribSpy.getCalls().length).to.eql(max); // each possible attribute is disabled + for (let i = 0; i < max; i++) { + expect(disableAttribSpy.getCall(i).args[0]).to.eql(i); + } + }); + }); });