Webgl / add a simple Layer renderer for common logic
This will eventually provides utilities for manipulating & rendering data
This commit is contained in:
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* @module ol/renderer/webgl/Layer
|
||||||
|
*/
|
||||||
|
import LayerRenderer from '../Layer.js';
|
||||||
|
import WebGLHelper from '../../webgl/Helper';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} PostProcessesOptions
|
||||||
|
* @property {number} [scaleRatio] Scale ratio; if < 1, the post process will render to a texture smaller than
|
||||||
|
* the main canvas that will then be sampled up (useful for saving resource on blur steps).
|
||||||
|
* @property {string} [vertexShader] Vertex shader source
|
||||||
|
* @property {string} [fragmentShader] Fragment shader source
|
||||||
|
* @property {Object.<string,import("../../webgl/Helper").UniformValue>} [uniforms] Uniform definitions for the post process step
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Options
|
||||||
|
* @property {Object.<string,import("../../webgl/Helper").UniformValue>} [uniforms] Uniform definitions for the post process steps
|
||||||
|
* @property {Array<PostProcessesOptions>} [postProcesses] Post-processes definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc
|
||||||
|
* Base WebGL renderer class.
|
||||||
|
* Holds all logic related to data manipulation & some common rendering logic
|
||||||
|
*/
|
||||||
|
class WebGLLayerRenderer extends LayerRenderer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import("../../layer/Layer.js").default} layer Layer.
|
||||||
|
* @param {Options=} [opt_options] Options.
|
||||||
|
*/
|
||||||
|
constructor(layer, opt_options) {
|
||||||
|
super(layer);
|
||||||
|
|
||||||
|
const options = opt_options || {};
|
||||||
|
|
||||||
|
this.helper_ = new WebGLHelper({
|
||||||
|
postProcesses: options.postProcesses,
|
||||||
|
uniforms: options.uniforms
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
disposeInternal() {
|
||||||
|
super.disposeInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will return the last shader compilation errors. If no error happened, will return null;
|
||||||
|
* @return {string|null} Errors, or null if last compilation was successful
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
getShaderCompileErrors() {
|
||||||
|
return this.helper_.getShaderCompileErrors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a texture of 1x1 pixel, white
|
||||||
|
* @private
|
||||||
|
* @return {ImageData} Image data.
|
||||||
|
*/
|
||||||
|
export function getBlankTexture() {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const image = canvas.getContext('2d').createImageData(1, 1);
|
||||||
|
image.data[0] = image.data[1] = image.data[2] = image.data[3] = 255;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WebGLLayerRenderer;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* @module ol/renderer/webgl/PointsLayer
|
* @module ol/renderer/webgl/PointsLayer
|
||||||
*/
|
*/
|
||||||
import LayerRenderer from '../Layer';
|
|
||||||
import WebGLArrayBuffer from '../../webgl/Buffer';
|
import WebGLArrayBuffer from '../../webgl/Buffer';
|
||||||
import {DYNAMIC_DRAW, ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, FLOAT} from '../../webgl';
|
import {DYNAMIC_DRAW, ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, FLOAT} from '../../webgl';
|
||||||
import WebGLHelper, {DefaultAttrib} from '../../webgl/Helper';
|
import {DefaultAttrib} from '../../webgl/Helper';
|
||||||
import GeometryType from '../../geom/GeometryType';
|
import GeometryType from '../../geom/GeometryType';
|
||||||
|
import WebGLLayerRenderer, {getBlankTexture} from './Layer';
|
||||||
|
|
||||||
const VERTEX_SHADER = `
|
const VERTEX_SHADER = `
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
@@ -55,15 +55,6 @@ const FRAGMENT_SHADER = `
|
|||||||
gl_FragColor.rgb *= gl_FragColor.a;
|
gl_FragColor.rgb *= gl_FragColor.a;
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} PostProcessesOptions
|
|
||||||
* @property {number} [scaleRatio] Scale ratio; if < 1, the post process will render to a texture smaller than
|
|
||||||
* the main canvas that will then be sampled up (useful for saving resource on blur steps).
|
|
||||||
* @property {string} [vertexShader] Vertex shader source
|
|
||||||
* @property {string} [fragmentShader] Fragment shader source
|
|
||||||
* @property {Object.<string,import("../../webgl/Helper").UniformValue>} [uniforms] Uniform definitions for the post process step
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} Options
|
* @typedef {Object} Options
|
||||||
* @property {function(import("../../Feature").default):number} [sizeCallback] Will be called on every feature in the
|
* @property {function(import("../../Feature").default):number} [sizeCallback] Will be called on every feature in the
|
||||||
@@ -91,7 +82,7 @@ const FRAGMENT_SHADER = `
|
|||||||
* @property {string} [fragmentShader] Fragment shader source
|
* @property {string} [fragmentShader] Fragment shader source
|
||||||
* @property {Object.<string,import("../../webgl/Helper").UniformValue>} [uniforms] Uniform definitions for the post process steps
|
* @property {Object.<string,import("../../webgl/Helper").UniformValue>} [uniforms] Uniform definitions for the post process steps
|
||||||
* Please note that `u_texture` is reserved for the main texture slot.
|
* Please note that `u_texture` is reserved for the main texture slot.
|
||||||
* @property {Array<PostProcessesOptions>} [postProcesses] Post-processes definitions
|
* @property {Array<import("./Layer").PostProcessesOptions>} [postProcesses] Post-processes definitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,22 +177,22 @@ const FRAGMENT_SHADER = `
|
|||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
class WebGLPointsLayerRenderer extends LayerRenderer {
|
class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("../../layer/Vector.js").default} vectorLayer Vector layer.
|
* @param {import("../../layer/Vector.js").default} vectorLayer Vector layer.
|
||||||
* @param {Options=} [opt_options] Options.
|
* @param {Options=} [opt_options] Options.
|
||||||
*/
|
*/
|
||||||
constructor(vectorLayer, opt_options) {
|
constructor(vectorLayer, opt_options) {
|
||||||
super(vectorLayer);
|
|
||||||
|
|
||||||
const options = opt_options || {};
|
const options = opt_options || {};
|
||||||
|
|
||||||
|
// assign the `texture` uniform if not specified in the options
|
||||||
const uniforms = options.uniforms || {};
|
const uniforms = options.uniforms || {};
|
||||||
uniforms.u_texture = options.texture || this.getDefaultTexture();
|
uniforms.u_texture = options.texture || getBlankTexture();
|
||||||
this.helper_ = new WebGLHelper({
|
|
||||||
postProcesses: options.postProcesses,
|
super(vectorLayer, {
|
||||||
uniforms: uniforms
|
uniforms: uniforms,
|
||||||
|
postProcesses: options.postProcesses
|
||||||
});
|
});
|
||||||
|
|
||||||
this.sourceRevision_ = -1;
|
this.sourceRevision_ = -1;
|
||||||
@@ -335,27 +326,6 @@ class WebGLPointsLayerRenderer extends LayerRenderer {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Will return the last shader compilation errors. If no error happened, will return null;
|
|
||||||
* @return {string|null} Errors, or null if last compilation was successful
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
getShaderCompileErrors() {
|
|
||||||
return this.helper_.getShaderCompileErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a texture of 1x1 pixel, white
|
|
||||||
* @private
|
|
||||||
* @return {ImageData} Image data.
|
|
||||||
*/
|
|
||||||
getDefaultTexture() {
|
|
||||||
const canvas = document.createElement('canvas');
|
|
||||||
const image = canvas.getContext('2d').createImageData(1, 1);
|
|
||||||
image.data[0] = image.data[1] = image.data[2] = image.data[3] = 255;
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WebGLPointsLayerRenderer;
|
export default WebGLPointsLayerRenderer;
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import VectorLayer from '../../../../../src/ol/layer/Vector.js';
|
||||||
|
import VectorSource from '../../../../../src/ol/source/Vector.js';
|
||||||
|
import WebGLLayerRenderer, {getBlankTexture} from '../../../../../src/ol/renderer/webgl/Layer';
|
||||||
|
|
||||||
|
|
||||||
|
describe('ol.renderer.webgl.Layer', function() {
|
||||||
|
|
||||||
|
describe('constructor', function() {
|
||||||
|
|
||||||
|
let target;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
target = document.createElement('div');
|
||||||
|
target.style.width = '256px';
|
||||||
|
target.style.height = '256px';
|
||||||
|
document.body.appendChild(target);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
document.body.removeChild(target);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('creates a new instance', function () {
|
||||||
|
const layer = new VectorLayer({
|
||||||
|
source: new VectorSource()
|
||||||
|
});
|
||||||
|
const renderer = new WebGLLayerRenderer(layer);
|
||||||
|
expect(renderer).to.be.a(WebGLLayerRenderer);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getBlankTexture', function() {
|
||||||
|
it('creates a 1x1 white texture', function() {
|
||||||
|
const texture = getBlankTexture();
|
||||||
|
expect(texture.height).to.eql(1);
|
||||||
|
expect(texture.width).to.eql(1);
|
||||||
|
expect(texture.data[0]).to.eql(255);
|
||||||
|
expect(texture.data[1]).to.eql(255);
|
||||||
|
expect(texture.data[2]).to.eql(255);
|
||||||
|
expect(texture.data[3]).to.eql(255);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user