Merge pull request #10439 from jahow/webgl-add-rotation
WebGL points layer / add support for symbol rotation
This commit is contained in:
@@ -13,6 +13,8 @@ docs: >
|
|||||||
Note: those will be taken from the attributes provided to the renderer
|
Note: those will be taken from the attributes provided to the renderer
|
||||||
* `['var', 'varName']` fetches a value from the style variables, or 0 if undefined
|
* `['var', 'varName']` fetches a value from the style variables, or 0 if undefined
|
||||||
* `['time']` returns the time in seconds since the creation of the layer
|
* `['time']` returns the time in seconds since the creation of the layer
|
||||||
|
* `['zoom']` returns the current zoom level
|
||||||
|
* `['resolution']` returns the current resolution
|
||||||
|
|
||||||
* Math operators:
|
* Math operators:
|
||||||
* `['*', value1, value2]` multiplies `value1` by `value2`
|
* `['*', value1, value2]` multiplies `value1` by `value2`
|
||||||
@@ -57,7 +59,6 @@ docs: >
|
|||||||
* `['color', red, green, blue, alpha]` creates a `color` value from `number` values; the `alpha` parameter is
|
* `['color', red, green, blue, alpha]` creates a `color` value from `number` values; the `alpha` parameter is
|
||||||
optional; if not specified, it will be set to 1.
|
optional; if not specified, it will be set to 1.
|
||||||
Note: `red`, `green` and `blue` components must be values between 0 and 255; `alpha` between 0 and 1.
|
Note: `red`, `green` and `blue` components must be values between 0 and 255; `alpha` between 0 and 1.
|
||||||
|
|
||||||
Values can either be literals or another operator, as they will be evaluated recursively.
|
Values can either be literals or another operator, as they will be evaluated recursively.
|
||||||
Literal values can be of the following types:
|
Literal values can be of the following types:
|
||||||
* `boolean`
|
* `boolean`
|
||||||
@@ -76,6 +77,7 @@ experimental: true
|
|||||||
<option value="triangles-latitude">Triangles, color related to latitude</option>
|
<option value="triangles-latitude">Triangles, color related to latitude</option>
|
||||||
<option value="circles">Circles, size related to population</option>
|
<option value="circles">Circles, size related to population</option>
|
||||||
<option value="circles-zoom">Circles, size related to zoom</option>
|
<option value="circles-zoom">Circles, size related to zoom</option>
|
||||||
|
<option value="rotating-bars">Rotating bars</option>
|
||||||
</select>
|
</select>
|
||||||
<textarea style="width: 100%; height: 20rem; font-family: monospace; font-size: small;" id="style-editor"></textarea>
|
<textarea style="width: 100%; height: 20rem; font-family: monospace; font-size: small;" id="style-editor"></textarea>
|
||||||
<small>
|
<small>
|
||||||
|
|||||||
@@ -95,6 +95,35 @@ const predefinedStyles = {
|
|||||||
offset: [0, 0],
|
offset: [0, 0],
|
||||||
opacity: 0.95
|
opacity: 0.95
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'rotating-bars': {
|
||||||
|
symbol: {
|
||||||
|
symbolType: 'square',
|
||||||
|
rotation: ['*', [
|
||||||
|
'time'
|
||||||
|
], 0.1],
|
||||||
|
size: ['array', 4, [
|
||||||
|
'interpolate',
|
||||||
|
['linear'],
|
||||||
|
['get', 'population'],
|
||||||
|
20000, 4,
|
||||||
|
300000, 28]
|
||||||
|
],
|
||||||
|
color: [
|
||||||
|
'interpolate',
|
||||||
|
['linear'],
|
||||||
|
['get', 'population'],
|
||||||
|
20000, '#ffdc00',
|
||||||
|
300000, '#ff5b19'
|
||||||
|
],
|
||||||
|
offset: ['array', 0, [
|
||||||
|
'interpolate',
|
||||||
|
['linear'],
|
||||||
|
['get', 'population'],
|
||||||
|
20000, 2,
|
||||||
|
300000, 14]
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,3 +196,10 @@ function onSelectChange() {
|
|||||||
}
|
}
|
||||||
onSelectChange();
|
onSelectChange();
|
||||||
select.addEventListener('change', onSelectChange);
|
select.addEventListener('change', onSelectChange);
|
||||||
|
|
||||||
|
// animate the map
|
||||||
|
function animate() {
|
||||||
|
map.render();
|
||||||
|
window.requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
animate();
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export const SymbolType = {
|
|||||||
* @property {string} [src] Path to the image to be used for the symbol. Only required with `symbolType: 'image'`.
|
* @property {string} [src] Path to the image to be used for the symbol. Only required with `symbolType: 'image'`.
|
||||||
* @property {import("../color.js").Color|Array<ExpressionValue>|string} [color='#FFFFFF'] Color used for the representation (either fill, line or symbol).
|
* @property {import("../color.js").Color|Array<ExpressionValue>|string} [color='#FFFFFF'] Color used for the representation (either fill, line or symbol).
|
||||||
* @property {ExpressionValue} [opacity=1] Opacity.
|
* @property {ExpressionValue} [opacity=1] Opacity.
|
||||||
|
* @property {ExpressionValue} [rotation=0] Symbol rotation in radians.
|
||||||
* @property {Array<ExpressionValue, ExpressionValue>} [offset] Offset on X and Y axis for symbols. If not specified, the symbol will be centered.
|
* @property {Array<ExpressionValue, ExpressionValue>} [offset] Offset on X and Y axis for symbols. If not specified, the symbol will be centered.
|
||||||
* @property {Array<ExpressionValue, ExpressionValue, ExpressionValue, ExpressionValue>} [textureCoord] Texture coordinates. If not specified, the whole texture will be used (range for 0 to 1 on both axes).
|
* @property {Array<ExpressionValue, ExpressionValue, ExpressionValue, ExpressionValue>} [textureCoord] Texture coordinates. If not specified, the whole texture will be used (range for 0 to 1 on both axes).
|
||||||
* @property {boolean} [rotateWithView=false] Specify whether the symbol must rotate with the view or stay upwards.
|
* @property {boolean} [rotateWithView=false] Specify whether the symbol must rotate with the view or stay upwards.
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import {asArray, isStringColor} from '../color.js';
|
|||||||
* Note: those will be taken from the attributes provided to the renderer
|
* Note: those will be taken from the attributes provided to the renderer
|
||||||
* * `['var', 'varName']` fetches a value from the style variables, or 0 if undefined
|
* * `['var', 'varName']` fetches a value from the style variables, or 0 if undefined
|
||||||
* * `['time']` returns the time in seconds since the creation of the layer
|
* * `['time']` returns the time in seconds since the creation of the layer
|
||||||
|
* * `['zoom']` returns the current zoom level
|
||||||
|
* * `['resolution']` returns the current resolution
|
||||||
*
|
*
|
||||||
* * Math operators:
|
* * Math operators:
|
||||||
* * `['*', value1, value2]` multiplies `value1` by `value2`
|
* * `['*', value1, value2]` multiplies `value1` by `value2`
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ export class ShaderBuilder {
|
|||||||
*/
|
*/
|
||||||
this.sizeExpression = 'vec2(1.0)';
|
this.sizeExpression = 'vec2(1.0)';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.rotationExpression = '0.0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
* @private
|
* @private
|
||||||
@@ -138,6 +144,18 @@ export class ShaderBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an expression to compute the rotation of the shape.
|
||||||
|
* This expression can use all the uniforms and attributes available
|
||||||
|
* in the vertex shader, and should evaluate to a `float` value in radians.
|
||||||
|
* @param {string} expression Size expression
|
||||||
|
* @return {ShaderBuilder} the builder object
|
||||||
|
*/
|
||||||
|
setRotationExpression(expression) {
|
||||||
|
this.rotationExpression = expression;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an expression to compute the offset of the symbol from the point center.
|
* Sets an expression to compute the offset of the symbol from the point center.
|
||||||
* This expression can use all the uniforms and attributes available
|
* This expression can use all the uniforms and attributes available
|
||||||
@@ -291,10 +309,24 @@ ${varyings.map(function(varying) {
|
|||||||
}).join('\n')}
|
}).join('\n')}
|
||||||
void main(void) {
|
void main(void) {
|
||||||
mat4 offsetMatrix = ${offsetMatrix};
|
mat4 offsetMatrix = ${offsetMatrix};
|
||||||
vec2 size = ${this.sizeExpression};
|
vec2 halfSize = ${this.sizeExpression} * 0.5;
|
||||||
vec2 offset = ${this.offsetExpression};
|
vec2 offset = ${this.offsetExpression};
|
||||||
float offsetX = a_index == 0.0 || a_index == 3.0 ? offset.x - size.x / 2.0 : offset.x + size.x / 2.0;
|
float angle = ${this.rotationExpression};
|
||||||
float offsetY = a_index == 0.0 || a_index == 1.0 ? offset.y - size.y / 2.0 : offset.y + size.y / 2.0;
|
float offsetX;
|
||||||
|
float offsetY;
|
||||||
|
if (a_index == 0.0) {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 1.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 2.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
}
|
||||||
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
||||||
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
||||||
vec4 texCoord = ${this.texCoordExpression};
|
vec4 texCoord = ${this.texCoordExpression};
|
||||||
@@ -381,6 +413,7 @@ export function parseLiteralStyle(style) {
|
|||||||
const texCoord = symbStyle.textureCoord || [0, 0, 1, 1];
|
const texCoord = symbStyle.textureCoord || [0, 0, 1, 1];
|
||||||
const offset = symbStyle.offset || [0, 0];
|
const offset = symbStyle.offset || [0, 0];
|
||||||
const opacity = symbStyle.opacity !== undefined ? symbStyle.opacity : 1;
|
const opacity = symbStyle.opacity !== undefined ? symbStyle.opacity : 1;
|
||||||
|
const rotation = symbStyle.rotation !== undefined ? symbStyle.rotation : 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import("../style/expressions.js").ParsingContext}
|
* @type {import("../style/expressions.js").ParsingContext}
|
||||||
@@ -406,6 +439,7 @@ export function parseLiteralStyle(style) {
|
|||||||
};
|
};
|
||||||
const parsedColor = expressionToGlsl(fragContext, color, ValueTypes.COLOR);
|
const parsedColor = expressionToGlsl(fragContext, color, ValueTypes.COLOR);
|
||||||
const parsedOpacity = expressionToGlsl(fragContext, opacity, ValueTypes.NUMBER);
|
const parsedOpacity = expressionToGlsl(fragContext, opacity, ValueTypes.NUMBER);
|
||||||
|
const parsedRotation = expressionToGlsl(fragContext, rotation, ValueTypes.NUMBER);
|
||||||
|
|
||||||
let opacityFilter = '1.0';
|
let opacityFilter = '1.0';
|
||||||
const visibleSize = `vec2(${expressionToGlsl(fragContext, size, ValueTypes.NUMBER_ARRAY | ValueTypes.NUMBER)}).x`;
|
const visibleSize = `vec2(${expressionToGlsl(fragContext, size, ValueTypes.NUMBER_ARRAY | ValueTypes.NUMBER)}).x`;
|
||||||
@@ -427,6 +461,7 @@ export function parseLiteralStyle(style) {
|
|||||||
|
|
||||||
const builder = new ShaderBuilder()
|
const builder = new ShaderBuilder()
|
||||||
.setSizeExpression(`vec2(${parsedSize})`)
|
.setSizeExpression(`vec2(${parsedSize})`)
|
||||||
|
.setRotationExpression(parsedRotation)
|
||||||
.setSymbolOffsetExpression(parsedOffset)
|
.setSymbolOffsetExpression(parsedOffset)
|
||||||
.setTextureCoordinateExpression(parsedTexCoord)
|
.setTextureCoordinateExpression(parsedTexCoord)
|
||||||
.setSymbolRotateWithView(!!symbStyle.rotateWithView)
|
.setSymbolRotateWithView(!!symbStyle.rotateWithView)
|
||||||
|
|||||||
@@ -30,10 +30,24 @@ varying float v_opacity;
|
|||||||
varying vec3 v_test;
|
varying vec3 v_test;
|
||||||
void main(void) {
|
void main(void) {
|
||||||
mat4 offsetMatrix = u_offsetScaleMatrix;
|
mat4 offsetMatrix = u_offsetScaleMatrix;
|
||||||
vec2 size = vec2(6.0);
|
vec2 halfSize = vec2(6.0) * 0.5;
|
||||||
vec2 offset = vec2(5.0, -7.0);
|
vec2 offset = vec2(5.0, -7.0);
|
||||||
float offsetX = a_index == 0.0 || a_index == 3.0 ? offset.x - size.x / 2.0 : offset.x + size.x / 2.0;
|
float angle = 0.0;
|
||||||
float offsetY = a_index == 0.0 || a_index == 1.0 ? offset.y - size.y / 2.0 : offset.y + size.y / 2.0;
|
float offsetX;
|
||||||
|
float offsetY;
|
||||||
|
if (a_index == 0.0) {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 1.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 2.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
}
|
||||||
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
||||||
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
||||||
vec4 texCoord = vec4(0.0, 0.5, 0.5, 1.0);
|
vec4 texCoord = vec4(0.0, 0.5, 0.5, 1.0);
|
||||||
@@ -72,10 +86,24 @@ varying vec2 v_quadCoord;
|
|||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
mat4 offsetMatrix = u_offsetScaleMatrix;
|
mat4 offsetMatrix = u_offsetScaleMatrix;
|
||||||
vec2 size = vec2(6.0);
|
vec2 halfSize = vec2(6.0) * 0.5;
|
||||||
vec2 offset = vec2(5.0, -7.0);
|
vec2 offset = vec2(5.0, -7.0);
|
||||||
float offsetX = a_index == 0.0 || a_index == 3.0 ? offset.x - size.x / 2.0 : offset.x + size.x / 2.0;
|
float angle = 0.0;
|
||||||
float offsetY = a_index == 0.0 || a_index == 1.0 ? offset.y - size.y / 2.0 : offset.y + size.y / 2.0;
|
float offsetX;
|
||||||
|
float offsetY;
|
||||||
|
if (a_index == 0.0) {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 1.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 2.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
}
|
||||||
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
||||||
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
||||||
vec4 texCoord = vec4(0.0, 0.5, 0.5, 1.0);
|
vec4 texCoord = vec4(0.0, 0.5, 0.5, 1.0);
|
||||||
@@ -112,10 +140,24 @@ varying vec2 v_quadCoord;
|
|||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
mat4 offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;
|
mat4 offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;
|
||||||
vec2 size = vec2(6.0);
|
vec2 halfSize = vec2(6.0) * 0.5;
|
||||||
vec2 offset = vec2(5.0, -7.0);
|
vec2 offset = vec2(5.0, -7.0);
|
||||||
float offsetX = a_index == 0.0 || a_index == 3.0 ? offset.x - size.x / 2.0 : offset.x + size.x / 2.0;
|
float angle = 0.0;
|
||||||
float offsetY = a_index == 0.0 || a_index == 1.0 ? offset.y - size.y / 2.0 : offset.y + size.y / 2.0;
|
float offsetX;
|
||||||
|
float offsetY;
|
||||||
|
if (a_index == 0.0) {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 1.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 2.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
}
|
||||||
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
||||||
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
||||||
vec4 texCoord = vec4(0.0, 0.5, 0.5, 1.0);
|
vec4 texCoord = vec4(0.0, 0.5, 0.5, 1.0);
|
||||||
@@ -147,10 +189,24 @@ varying vec2 v_quadCoord;
|
|||||||
varying vec4 v_hitColor;
|
varying vec4 v_hitColor;
|
||||||
void main(void) {
|
void main(void) {
|
||||||
mat4 offsetMatrix = u_offsetScaleMatrix;
|
mat4 offsetMatrix = u_offsetScaleMatrix;
|
||||||
vec2 size = vec2(1.0);
|
vec2 halfSize = vec2(1.0) * 0.5;
|
||||||
vec2 offset = vec2(0.0);
|
vec2 offset = vec2(0.0);
|
||||||
float offsetX = a_index == 0.0 || a_index == 3.0 ? offset.x - size.x / 2.0 : offset.x + size.x / 2.0;
|
float angle = 0.0;
|
||||||
float offsetY = a_index == 0.0 || a_index == 1.0 ? offset.y - size.y / 2.0 : offset.y + size.y / 2.0;
|
float offsetX;
|
||||||
|
float offsetY;
|
||||||
|
if (a_index == 0.0) {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 1.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 2.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
}
|
||||||
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
||||||
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
||||||
vec4 texCoord = vec4(0.0, 0.0, 1.0, 1.0);
|
vec4 texCoord = vec4(0.0, 0.0, 1.0, 1.0);
|
||||||
@@ -161,6 +217,58 @@ void main(void) {
|
|||||||
v = a_index == 2.0 || a_index == 3.0 ? 0.0 : 1.0;
|
v = a_index == 2.0 || a_index == 3.0 ? 0.0 : 1.0;
|
||||||
v_quadCoord = vec2(u, v);
|
v_quadCoord = vec2(u, v);
|
||||||
v_hitColor = a_hitColor;
|
v_hitColor = a_hitColor;
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
it('generates a symbol vertex shader (with a rotation expression)', function() {
|
||||||
|
const builder = new ShaderBuilder();
|
||||||
|
builder.setSizeExpression(`vec2(${numberToGlsl(6)})`);
|
||||||
|
builder.setSymbolOffsetExpression(arrayToGlsl([5, -7]));
|
||||||
|
builder.setRotationExpression('u_time * 0.2');
|
||||||
|
|
||||||
|
expect(builder.getSymbolVertexShader()).to.eql(`precision mediump float;
|
||||||
|
uniform mat4 u_projectionMatrix;
|
||||||
|
uniform mat4 u_offsetScaleMatrix;
|
||||||
|
uniform mat4 u_offsetRotateMatrix;
|
||||||
|
uniform float u_time;
|
||||||
|
uniform float u_zoom;
|
||||||
|
uniform float u_resolution;
|
||||||
|
|
||||||
|
attribute vec2 a_position;
|
||||||
|
attribute float a_index;
|
||||||
|
|
||||||
|
varying vec2 v_texCoord;
|
||||||
|
varying vec2 v_quadCoord;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
mat4 offsetMatrix = u_offsetScaleMatrix;
|
||||||
|
vec2 halfSize = vec2(6.0) * 0.5;
|
||||||
|
vec2 offset = vec2(5.0, -7.0);
|
||||||
|
float angle = u_time * 0.2;
|
||||||
|
float offsetX;
|
||||||
|
float offsetY;
|
||||||
|
if (a_index == 0.0) {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 1.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else if (a_index == 2.0) {
|
||||||
|
offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);
|
||||||
|
} else {
|
||||||
|
offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);
|
||||||
|
offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);
|
||||||
|
}
|
||||||
|
vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
|
||||||
|
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
|
||||||
|
vec4 texCoord = vec4(0.0, 0.0, 1.0, 1.0);
|
||||||
|
float u = a_index == 0.0 || a_index == 3.0 ? texCoord.s : texCoord.p;
|
||||||
|
float v = a_index == 2.0 || a_index == 3.0 ? texCoord.t : texCoord.q;
|
||||||
|
v_texCoord = vec2(u, v);
|
||||||
|
u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;
|
||||||
|
v = a_index == 2.0 || a_index == 3.0 ? 0.0 : 1.0;
|
||||||
|
v_quadCoord = vec2(u, v);
|
||||||
|
|
||||||
}`);
|
}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user