WebGL points / Added a color attribute

This commit is contained in:
Olivier Guyot
2018-12-27 21:39:00 +01:00
parent 435ef3070c
commit 0acfd7ab59
2 changed files with 48 additions and 16 deletions

View File

@@ -14,6 +14,7 @@ const VERTEX_SHADER = `
attribute float a_rotateWithView;
attribute vec2 a_offsets;
attribute float a_opacity;
attribute vec4 a_color;
uniform mat4 u_projectionMatrix;
uniform mat4 u_offsetScaleMatrix;
@@ -21,6 +22,7 @@ const VERTEX_SHADER = `
varying vec2 v_texCoord;
varying float v_opacity;
varying vec4 v_color;
void main(void) {
mat4 offsetMatrix = u_offsetScaleMatrix;
@@ -31,6 +33,7 @@ const VERTEX_SHADER = `
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
v_texCoord = a_texCoord;
v_opacity = a_opacity;
v_color = a_color;
}`;
const FRAGMENT_SHADER = `
@@ -38,14 +41,15 @@ const FRAGMENT_SHADER = `
varying vec2 v_texCoord;
varying float v_opacity;
varying vec4 v_color;
void main(void) {
gl_FragColor.rgb = vec3(1.0, 1.0, 1.0);
float alpha = v_opacity;
if (alpha == 0.0) {
if (v_opacity == 0.0) {
discard;
}
gl_FragColor.a = alpha;
gl_FragColor = v_color;
gl_FragColor.a *= v_opacity;
gl_FragColor.rgb *= gl_FragColor.a;
}`;
/**
@@ -66,9 +70,15 @@ const FRAGMENT_SHADER = `
* The second argument is 0 for `x` component and 1 for `y`.
* @property {function(import("../../Feature").default, number):number} [texCoordCallback] Will be called on every feature in the
* source to compute the texture coordinates of each corner of the quad. This is only done on source change.
* The second argument is 0 for `u0` component, 1 or `v0`, 2 for `u1`, and 3 for `v1`.
* The second argument is 0 for `u0` component, 1 for `v0`, 2 for `u1`, and 3 for `v1`.
* @property {function(import("../../Feature").default, number, number):number} [colorCallback] Will be called on every feature in the
* source to compute the color of each corner of the quad. This is only done on source change.
* The second argument is 0 for bottom left, 1 for bottom right, 2 for top right and 3 for top left
* The third argument is 0 for red, 1 for green, 2 for blue and 3 for alpha
* The return value should be between 0 and 1.
* @property {function(import("../../Feature").default):number} [opacityCallback] Will be called on every feature in the
* source to compute the opacity of the quad on screen (from 0 to 1). This is only done on source change.
* Note: this is multiplied with the color of the point which can also have an alpha value < 1.
* @property {function(import("../../Feature").default):boolean} [rotateWithViewCallback] Will be called on every feature in the
* source to compute whether the quad on screen must stay upwards (`false`) or follow the view rotation (`true`).
* This is only done on source change.
@@ -183,6 +193,9 @@ class WebGLPointsLayerRenderer extends LayerRenderer {
this.texCoordCallback_ = options.texCoordCallback || function(feature, index) {
return index < 2 ? 0 : 1;
};
this.colorCallback_ = options.colorCallback || function(feature, index, component) {
return 1;
};
this.rotateWithViewCallback_ = options.rotateWithViewCallback || function() {
return false;
};
@@ -218,6 +231,8 @@ class WebGLPointsLayerRenderer extends LayerRenderer {
const vectorLayer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
const vectorSource = /** @type {import("../../source/Vector.js").default} */ (vectorLayer.getSource());
const stride = 12;
this.helper_.prepareDraw(frameState);
if (this.sourceRevision_ < vectorSource.getRevision()) {
@@ -242,14 +257,29 @@ class WebGLPointsLayerRenderer extends LayerRenderer {
const size = this.sizeCallback_(feature);
const opacity = this.opacityCallback_(feature);
const rotateWithView = this.rotateWithViewCallback_(feature) ? 1 : 0;
const stride = 8;
const v0_r = this.colorCallback_(feature, 0, 0);
const v0_g = this.colorCallback_(feature, 0, 1);
const v0_b = this.colorCallback_(feature, 0, 2);
const v0_a = this.colorCallback_(feature, 0, 3);
const v1_r = this.colorCallback_(feature, 1, 0);
const v1_g = this.colorCallback_(feature, 1, 1);
const v1_b = this.colorCallback_(feature, 1, 2);
const v1_a = this.colorCallback_(feature, 1, 3);
const v2_r = this.colorCallback_(feature, 2, 0);
const v2_g = this.colorCallback_(feature, 2, 1);
const v2_b = this.colorCallback_(feature, 2, 2);
const v2_a = this.colorCallback_(feature, 2, 3);
const v3_r = this.colorCallback_(feature, 3, 0);
const v3_g = this.colorCallback_(feature, 3, 1);
const v3_b = this.colorCallback_(feature, 3, 2);
const v3_a = this.colorCallback_(feature, 3, 3);
const baseIndex = this.verticesBuffer_.getArray().length / stride;
this.verticesBuffer_.getArray().push(
x, y, -size / 2, -size / 2, u0, v0, opacity, rotateWithView,
x, y, +size / 2, -size / 2, u1, v0, opacity, rotateWithView,
x, y, +size / 2, +size / 2, u1, v1, opacity, rotateWithView,
x, y, -size / 2, +size / 2, u0, v1, opacity, rotateWithView
x, y, -size / 2, -size / 2, u0, v0, opacity, rotateWithView, v0_r, v0_g, v0_b, v0_a,
x, y, +size / 2, -size / 2, u1, v0, opacity, rotateWithView, v1_r, v1_g, v1_b, v1_a,
x, y, +size / 2, +size / 2, u1, v1, opacity, rotateWithView, v2_r, v2_g, v2_b, v2_a,
x, y, -size / 2, +size / 2, u0, v1, opacity, rotateWithView, v3_r, v3_g, v3_b, v3_a
);
this.indicesBuffer_.getArray().push(
baseIndex, baseIndex + 1, baseIndex + 3,
@@ -263,11 +293,12 @@ class WebGLPointsLayerRenderer extends LayerRenderer {
this.helper_.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer_);
const bytesPerFloat = Float32Array.BYTES_PER_ELEMENT;
this.helper_.enableAttributeArray(DefaultAttrib.POSITION, 2, FLOAT, bytesPerFloat * 8, 0);
this.helper_.enableAttributeArray(DefaultAttrib.OFFSETS, 2, FLOAT, bytesPerFloat * 8, bytesPerFloat * 2);
this.helper_.enableAttributeArray(DefaultAttrib.TEX_COORD, 2, FLOAT, bytesPerFloat * 8, bytesPerFloat * 4);
this.helper_.enableAttributeArray(DefaultAttrib.OPACITY, 1, FLOAT, bytesPerFloat * 8, bytesPerFloat * 6);
this.helper_.enableAttributeArray(DefaultAttrib.ROTATE_WITH_VIEW, 1, FLOAT, bytesPerFloat * 8, bytesPerFloat * 7);
this.helper_.enableAttributeArray(DefaultAttrib.POSITION, 2, FLOAT, bytesPerFloat * stride, 0);
this.helper_.enableAttributeArray(DefaultAttrib.OFFSETS, 2, FLOAT, bytesPerFloat * stride, bytesPerFloat * 2);
this.helper_.enableAttributeArray(DefaultAttrib.TEX_COORD, 2, FLOAT, bytesPerFloat * stride, bytesPerFloat * 4);
this.helper_.enableAttributeArray(DefaultAttrib.OPACITY, 1, FLOAT, bytesPerFloat * stride, bytesPerFloat * 6);
this.helper_.enableAttributeArray(DefaultAttrib.ROTATE_WITH_VIEW, 1, FLOAT, bytesPerFloat * stride, bytesPerFloat * 7);
this.helper_.enableAttributeArray(DefaultAttrib.COLOR, 4, FLOAT, bytesPerFloat * stride, bytesPerFloat * 8);
return true;
}

View File

@@ -56,7 +56,8 @@ export const DefaultAttrib = {
TEX_COORD: 'a_texCoord',
OPACITY: 'a_opacity',
ROTATE_WITH_VIEW: 'a_rotateWithView',
OFFSETS: 'a_offsets'
OFFSETS: 'a_offsets',
COLOR: 'a_color'
};
/**