WebGL / render multiple worlds to wrap X in vector renderer
From https://github.com/jahow/openlayers/pull/1 Adds logic in WebGLVectorLayerRenderer to handle multiple worlds visible at once. Co-authored-by: Tomas Burleigh <t.burleigh@gmail.com> Co-authored-by: Olivier Guyot <olivier.guyot@camptocamp.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
|||||||
create as createTransform,
|
create as createTransform,
|
||||||
makeInverse as makeInverseTransform,
|
makeInverse as makeInverseTransform,
|
||||||
multiply as multiplyTransform,
|
multiply as multiplyTransform,
|
||||||
|
translate as translateTransform,
|
||||||
} from '../../transform.js';
|
} from '../../transform.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,11 +90,12 @@ class AbstractBatchRenderer {
|
|||||||
* @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch
|
* @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch
|
||||||
* @param {import("../../transform.js").Transform} currentTransform Transform
|
* @param {import("../../transform.js").Transform} currentTransform Transform
|
||||||
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
||||||
|
* @param {number} offsetX X offset
|
||||||
*/
|
*/
|
||||||
render(batch, currentTransform, frameState) {
|
render(batch, currentTransform, frameState, offsetX) {
|
||||||
// multiply the current projection transform with the invert of the one used to fill buffers
|
// multiply the current projection transform with the invert of the one used to fill buffers
|
||||||
// FIXME: this should probably be done directly in the layer renderer
|
|
||||||
this.helper_.makeProjectionTransform(frameState, currentTransform);
|
this.helper_.makeProjectionTransform(frameState, currentTransform);
|
||||||
|
translateTransform(currentTransform, offsetX, 0);
|
||||||
multiplyTransform(currentTransform, batch.invertVerticesBufferTransform);
|
multiplyTransform(currentTransform, batch.invertVerticesBufferTransform);
|
||||||
|
|
||||||
// enable program, buffers and attributes
|
// enable program, buffers and attributes
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import VectorEventType from '../../source/VectorEventType.js';
|
|||||||
import ViewHint from '../../ViewHint.js';
|
import ViewHint from '../../ViewHint.js';
|
||||||
import WebGLLayerRenderer from './Layer.js';
|
import WebGLLayerRenderer from './Layer.js';
|
||||||
import {DefaultUniform} from '../../webgl/Helper.js';
|
import {DefaultUniform} from '../../webgl/Helper.js';
|
||||||
import {buffer, createEmpty, equals} from '../../extent.js';
|
import {buffer, createEmpty, equals, getWidth} from '../../extent.js';
|
||||||
import {create as createTransform} from '../../transform.js';
|
import {create as createTransform} from '../../transform.js';
|
||||||
import {create as createWebGLWorker} from '../../worker/webgl.js';
|
import {create as createWebGLWorker} from '../../worker/webgl.js';
|
||||||
import {listen, unlistenByKey} from '../../events.js';
|
import {listen, unlistenByKey} from '../../events.js';
|
||||||
@@ -226,21 +226,42 @@ class WebGLVectorLayerRenderer extends WebGLLayerRenderer {
|
|||||||
renderFrame(frameState) {
|
renderFrame(frameState) {
|
||||||
const gl = this.helper.getGL();
|
const gl = this.helper.getGL();
|
||||||
this.preRender(gl, frameState);
|
this.preRender(gl, frameState);
|
||||||
this.polygonRenderer_.render(
|
|
||||||
this.batch_.polygonBatch,
|
const layer = this.getLayer();
|
||||||
this.currentTransform_,
|
const vectorSource = layer.getSource();
|
||||||
frameState
|
const projection = frameState.viewState.projection;
|
||||||
);
|
const multiWorld = vectorSource.getWrapX() && projection.canWrapX();
|
||||||
this.lineStringRenderer_.render(
|
const projectionExtent = projection.getExtent();
|
||||||
this.batch_.lineStringBatch,
|
const extent = frameState.extent;
|
||||||
this.currentTransform_,
|
const worldWidth = multiWorld ? getWidth(projectionExtent) : null;
|
||||||
frameState
|
const endWorld = multiWorld
|
||||||
);
|
? Math.ceil((extent[2] - projectionExtent[2]) / worldWidth) + 1
|
||||||
this.pointRenderer_.render(
|
: 1;
|
||||||
this.batch_.pointBatch,
|
let world = multiWorld
|
||||||
this.currentTransform_,
|
? Math.floor((extent[0] - projectionExtent[0]) / worldWidth)
|
||||||
frameState
|
: 0;
|
||||||
);
|
|
||||||
|
do {
|
||||||
|
this.polygonRenderer_.render(
|
||||||
|
this.batch_.polygonBatch,
|
||||||
|
this.currentTransform_,
|
||||||
|
frameState,
|
||||||
|
world * worldWidth
|
||||||
|
);
|
||||||
|
this.lineStringRenderer_.render(
|
||||||
|
this.batch_.lineStringBatch,
|
||||||
|
this.currentTransform_,
|
||||||
|
frameState,
|
||||||
|
world * worldWidth
|
||||||
|
);
|
||||||
|
this.pointRenderer_.render(
|
||||||
|
this.batch_.pointBatch,
|
||||||
|
this.currentTransform_,
|
||||||
|
frameState,
|
||||||
|
world * worldWidth
|
||||||
|
);
|
||||||
|
} while (++world < endWorld);
|
||||||
|
|
||||||
this.helper.finalizeDraw(frameState);
|
this.helper.finalizeDraw(frameState);
|
||||||
|
|
||||||
const canvas = this.helper.getCanvas();
|
const canvas = this.helper.getCanvas();
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ import PolygonBatchRenderer from '../../../../../../src/ol/render/webgl/PolygonB
|
|||||||
import WebGLHelper from '../../../../../../src/ol/webgl/Helper.js';
|
import WebGLHelper from '../../../../../../src/ol/webgl/Helper.js';
|
||||||
import {FLOAT} from '../../../../../../src/ol/webgl.js';
|
import {FLOAT} from '../../../../../../src/ol/webgl.js';
|
||||||
import {WebGLWorkerMessageType} from '../../../../../../src/ol/render/webgl/constants.js';
|
import {WebGLWorkerMessageType} from '../../../../../../src/ol/render/webgl/constants.js';
|
||||||
import {create as createTransform} from '../../../../../../src/ol/transform.js';
|
import {
|
||||||
|
create as createTransform,
|
||||||
|
translate as translateTransform,
|
||||||
|
} from '../../../../../../src/ol/transform.js';
|
||||||
import {create as createWebGLWorker} from '../../../../../../src/ol/worker/webgl.js';
|
import {create as createWebGLWorker} from '../../../../../../src/ol/worker/webgl.js';
|
||||||
|
|
||||||
const POINT_VERTEX_SHADER = `precision mediump float;
|
const POINT_VERTEX_SHADER = `precision mediump float;
|
||||||
@@ -133,6 +136,8 @@ describe('Batch renderers', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#render (from parent)', function () {
|
describe('#render (from parent)', function () {
|
||||||
|
let transform;
|
||||||
|
const offsetX = 12;
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
sinon.spy(helper, 'makeProjectionTransform');
|
sinon.spy(helper, 'makeProjectionTransform');
|
||||||
sinon.spy(helper, 'useProgram');
|
sinon.spy(helper, 'useProgram');
|
||||||
@@ -140,16 +145,25 @@ describe('Batch renderers', function () {
|
|||||||
sinon.spy(helper, 'enableAttributes');
|
sinon.spy(helper, 'enableAttributes');
|
||||||
sinon.spy(helper, 'drawElements');
|
sinon.spy(helper, 'drawElements');
|
||||||
|
|
||||||
const transform = createTransform();
|
transform = createTransform();
|
||||||
batchRenderer.render(
|
batchRenderer.render(
|
||||||
mixedBatch.pointBatch,
|
mixedBatch.pointBatch,
|
||||||
transform,
|
transform,
|
||||||
SAMPLE_FRAMESTATE
|
SAMPLE_FRAMESTATE,
|
||||||
|
offsetX
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('computes current transform', function () {
|
it('computes current transform', function () {
|
||||||
expect(helper.makeProjectionTransform.calledOnce).to.be(true);
|
expect(helper.makeProjectionTransform.calledOnce).to.be(true);
|
||||||
});
|
});
|
||||||
|
it('includes the X offset in the transform used for rendering', function () {
|
||||||
|
const expected = helper.makeProjectionTransform(
|
||||||
|
SAMPLE_FRAMESTATE,
|
||||||
|
createTransform()
|
||||||
|
);
|
||||||
|
translateTransform(expected, offsetX, 0);
|
||||||
|
expect(transform).to.eql(expected);
|
||||||
|
});
|
||||||
it('computes sets up render parameters', function () {
|
it('computes sets up render parameters', function () {
|
||||||
expect(helper.useProgram.calledOnce).to.be(true);
|
expect(helper.useProgram.calledOnce).to.be(true);
|
||||||
expect(helper.enableAttributes.calledOnce).to.be(true);
|
expect(helper.enableAttributes.calledOnce).to.be(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user