Shader Builder / adapt logic & test to the new expression types
Also fixes a sneaky bug where the two last texture coordinates were inverted.
This commit is contained in:
@@ -192,7 +192,7 @@ export function stringToGlsl(context, string) {
|
|||||||
* will be read and modified during the parsing operation.
|
* will be read and modified during the parsing operation.
|
||||||
* @param {ParsingContext} context Parsing context
|
* @param {ParsingContext} context Parsing context
|
||||||
* @param {ExpressionValue} value Value
|
* @param {ExpressionValue} value Value
|
||||||
* @param {ValueTypes} [typeHint] Hint for the expected final type
|
* @param {ValueTypes|number} [typeHint] Hint for the expected final type (can be several types combined)
|
||||||
* @returns {string} GLSL-compatible output
|
* @returns {string} GLSL-compatible output
|
||||||
*/
|
*/
|
||||||
export function expressionToGlsl(context, value, typeHint) {
|
export function expressionToGlsl(context, value, typeHint) {
|
||||||
|
|||||||
@@ -282,8 +282,8 @@ void main(void) {
|
|||||||
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};
|
||||||
float u = a_index == 0.0 || a_index == 3.0 ? texCoord.s : texCoord.q;
|
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.p;
|
float v = a_index == 2.0 || a_index == 3.0 ? texCoord.t : texCoord.q;
|
||||||
v_texCoord = vec2(u, v);
|
v_texCoord = vec2(u, v);
|
||||||
u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;
|
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 = a_index == 2.0 || a_index == 3.0 ? 0.0 : 1.0;
|
||||||
@@ -342,37 +342,39 @@ void main(void) {
|
|||||||
*/
|
*/
|
||||||
export function parseLiteralStyle(style) {
|
export function parseLiteralStyle(style) {
|
||||||
const symbStyle = style.symbol;
|
const symbStyle = style.symbol;
|
||||||
const size = Array.isArray(symbStyle.size) && typeof symbStyle.size[0] == 'number' ?
|
const size = symbStyle.size !== undefined ? symbStyle.size : 1;
|
||||||
symbStyle.size : [symbStyle.size, symbStyle.size];
|
|
||||||
const color = symbStyle.color || 'white';
|
const color = symbStyle.color || 'white';
|
||||||
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import("../style/expressions.js").ParsingContext}
|
||||||
|
*/
|
||||||
const vertContext = {
|
const vertContext = {
|
||||||
inFragmentShader: false,
|
inFragmentShader: false,
|
||||||
variables: [],
|
variables: [],
|
||||||
attributes: []
|
attributes: [],
|
||||||
|
stringLiteralsMap: {}
|
||||||
};
|
};
|
||||||
const parseSizeX = expressionToGlsl(vertContext, size[0], ValueTypes.NUMBER);
|
const parsedSize = expressionToGlsl(vertContext, size, ValueTypes.NUMBER_ARRAY | ValueTypes.NUMBER);
|
||||||
const parseSizeY = expressionToGlsl(vertContext, size[1], ValueTypes.NUMBER);
|
const parsedOffset = expressionToGlsl(vertContext, offset, ValueTypes.NUMBER_ARRAY);
|
||||||
const parsedOffsetX = expressionToGlsl(vertContext, offset[0], ValueTypes.NUMBER);
|
const parsedTexCoord = expressionToGlsl(vertContext, texCoord, ValueTypes.NUMBER_ARRAY);
|
||||||
const parsedOffsetY = expressionToGlsl(vertContext, offset[1], ValueTypes.NUMBER);
|
|
||||||
const parsedTexCoordU1 = expressionToGlsl(vertContext, texCoord[0], ValueTypes.NUMBER);
|
|
||||||
const parsedTexCoordV1 = expressionToGlsl(vertContext, texCoord[1], ValueTypes.NUMBER);
|
|
||||||
const parsedTexCoordU2 = expressionToGlsl(vertContext, texCoord[2], ValueTypes.NUMBER);
|
|
||||||
const parsedTexCoordV2 = expressionToGlsl(vertContext, texCoord[3], ValueTypes.NUMBER);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import("../style/expressions.js").ParsingContext}
|
||||||
|
*/
|
||||||
const fragContext = {
|
const fragContext = {
|
||||||
inFragmentShader: true,
|
inFragmentShader: true,
|
||||||
variables: vertContext.variables,
|
variables: vertContext.variables,
|
||||||
attributes: []
|
attributes: [],
|
||||||
|
stringLiteralsMap: vertContext.stringLiteralsMap
|
||||||
};
|
};
|
||||||
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);
|
||||||
|
|
||||||
let opacityFilter = '1.0';
|
let opacityFilter = '1.0';
|
||||||
const visibleSize = expressionToGlsl(fragContext, size[0], ValueTypes.NUMBER);
|
const visibleSize = `vec2(${expressionToGlsl(fragContext, size, ValueTypes.NUMBER_ARRAY | ValueTypes.NUMBER)}).x`;
|
||||||
switch (symbStyle.symbolType) {
|
switch (symbStyle.symbolType) {
|
||||||
case 'square': break;
|
case 'square': break;
|
||||||
case 'image': break;
|
case 'image': break;
|
||||||
@@ -390,10 +392,9 @@ export function parseLiteralStyle(style) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const builder = new ShaderBuilder()
|
const builder = new ShaderBuilder()
|
||||||
.setSizeExpression(`vec2(${parseSizeX}, ${parseSizeY})`)
|
.setSizeExpression(`vec2(${parsedSize})`)
|
||||||
.setSymbolOffsetExpression(`vec2(${parsedOffsetX}, ${parsedOffsetY})`)
|
.setSymbolOffsetExpression(parsedOffset)
|
||||||
.setTextureCoordinateExpression(
|
.setTextureCoordinateExpression(parsedTexCoord)
|
||||||
`vec4(${parsedTexCoordU1}, ${parsedTexCoordV1}, ${parsedTexCoordU2}, ${parsedTexCoordV2})`)
|
|
||||||
.setSymbolRotateWithView(!!symbStyle.rotateWithView)
|
.setSymbolRotateWithView(!!symbStyle.rotateWithView)
|
||||||
.setColorExpression(
|
.setColorExpression(
|
||||||
`vec4(${parsedColor}.rgb, ${parsedColor}.a * ${parsedOpacity} * ${opacityFilter})`);
|
`vec4(${parsedColor}.rgb, ${parsedColor}.a * ${parsedOpacity} * ${opacityFilter})`);
|
||||||
@@ -444,7 +445,11 @@ export function parseLiteralStyle(style) {
|
|||||||
return {
|
return {
|
||||||
name: attributeName,
|
name: attributeName,
|
||||||
callback: function(feature) {
|
callback: function(feature) {
|
||||||
return feature.get(attributeName) || 0;
|
let value = feature.get(attributeName);
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
value = vertContext.stringLiteralsMap[value];
|
||||||
|
}
|
||||||
|
return value !== undefined ? value : -9999999; // to avoid matching with the first string literal
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ void main(void) {
|
|||||||
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);
|
||||||
float u = a_index == 0.0 || a_index == 3.0 ? texCoord.s : texCoord.q;
|
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.p;
|
float v = a_index == 2.0 || a_index == 3.0 ? texCoord.t : texCoord.q;
|
||||||
v_texCoord = vec2(u, v);
|
v_texCoord = vec2(u, v);
|
||||||
u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;
|
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 = a_index == 2.0 || a_index == 3.0 ? 0.0 : 1.0;
|
||||||
@@ -75,8 +75,8 @@ void main(void) {
|
|||||||
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);
|
||||||
float u = a_index == 0.0 || a_index == 3.0 ? texCoord.s : texCoord.q;
|
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.p;
|
float v = a_index == 2.0 || a_index == 3.0 ? texCoord.t : texCoord.q;
|
||||||
v_texCoord = vec2(u, v);
|
v_texCoord = vec2(u, v);
|
||||||
u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;
|
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 = a_index == 2.0 || a_index == 3.0 ? 0.0 : 1.0;
|
||||||
@@ -113,8 +113,8 @@ void main(void) {
|
|||||||
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);
|
||||||
float u = a_index == 0.0 || a_index == 3.0 ? texCoord.s : texCoord.q;
|
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.p;
|
float v = a_index == 2.0 || a_index == 3.0 ? texCoord.t : texCoord.q;
|
||||||
v_texCoord = vec2(u, v);
|
v_texCoord = vec2(u, v);
|
||||||
u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;
|
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 = a_index == 2.0 || a_index == 3.0 ? 0.0 : 1.0;
|
||||||
@@ -188,7 +188,7 @@ void main(void) {
|
|||||||
expect(result.builder.varyings).to.eql([]);
|
expect(result.builder.varyings).to.eql([]);
|
||||||
expect(result.builder.colorExpression).to.eql(
|
expect(result.builder.colorExpression).to.eql(
|
||||||
'vec4(vec4(1.0, 0.0, 0.0, 1.0).rgb, vec4(1.0, 0.0, 0.0, 1.0).a * 1.0 * 1.0)');
|
'vec4(vec4(1.0, 0.0, 0.0, 1.0).rgb, vec4(1.0, 0.0, 0.0, 1.0).a * 1.0 * 1.0)');
|
||||||
expect(result.builder.sizeExpression).to.eql('vec2(4.0, 8.0)');
|
expect(result.builder.sizeExpression).to.eql('vec2(vec2(4.0, 8.0))');
|
||||||
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
||||||
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
||||||
expect(result.builder.rotateWithView).to.eql(true);
|
expect(result.builder.rotateWithView).to.eql(true);
|
||||||
@@ -203,7 +203,7 @@ void main(void) {
|
|||||||
size: ['get', 'attr1'],
|
size: ['get', 'attr1'],
|
||||||
color: [255, 127.5, 63.75, 0.25],
|
color: [255, 127.5, 63.75, 0.25],
|
||||||
textureCoord: [0.5, 0.5, 0.5, 1],
|
textureCoord: [0.5, 0.5, 0.5, 1],
|
||||||
offset: [3, ['get', 'attr3']]
|
offset: ['match', ['get', 'attr3'], 'red', [6, 0], 'green', [3, 0], [0, 0]]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -217,8 +217,8 @@ void main(void) {
|
|||||||
expect(result.builder.colorExpression).to.eql(
|
expect(result.builder.colorExpression).to.eql(
|
||||||
'vec4(vec4(1.0, 0.5, 0.25, 0.25).rgb, vec4(1.0, 0.5, 0.25, 0.25).a * 1.0 * 1.0)'
|
'vec4(vec4(1.0, 0.5, 0.25, 0.25).rgb, vec4(1.0, 0.5, 0.25, 0.25).a * 1.0 * 1.0)'
|
||||||
);
|
);
|
||||||
expect(result.builder.sizeExpression).to.eql('vec2(a_attr1, a_attr1)');
|
expect(result.builder.sizeExpression).to.eql('vec2(a_attr1)');
|
||||||
expect(result.builder.offsetExpression).to.eql('vec2(3.0, a_attr3)');
|
expect(result.builder.offsetExpression).to.eql('(a_attr3 == 1.0 ? vec2(6.0, 0.0) : (a_attr3 == 0.0 ? vec2(3.0, 0.0) : vec2(0.0, 0.0)))');
|
||||||
expect(result.builder.texCoordExpression).to.eql('vec4(0.5, 0.5, 0.5, 1.0)');
|
expect(result.builder.texCoordExpression).to.eql('vec4(0.5, 0.5, 0.5, 1.0)');
|
||||||
expect(result.builder.rotateWithView).to.eql(false);
|
expect(result.builder.rotateWithView).to.eql(false);
|
||||||
expect(result.attributes.length).to.eql(2);
|
expect(result.attributes.length).to.eql(2);
|
||||||
@@ -244,7 +244,7 @@ void main(void) {
|
|||||||
expect(result.builder.colorExpression).to.eql(
|
expect(result.builder.colorExpression).to.eql(
|
||||||
'vec4(vec4(0.2, 0.4, 0.6, 1.0).rgb, vec4(0.2, 0.4, 0.6, 1.0).a * 0.5 * 1.0) * texture2D(u_texture, v_texCoord)'
|
'vec4(vec4(0.2, 0.4, 0.6, 1.0).rgb, vec4(0.2, 0.4, 0.6, 1.0).a * 0.5 * 1.0) * texture2D(u_texture, v_texCoord)'
|
||||||
);
|
);
|
||||||
expect(result.builder.sizeExpression).to.eql('vec2(6.0, 6.0)');
|
expect(result.builder.sizeExpression).to.eql('vec2(6.0)');
|
||||||
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
||||||
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
||||||
expect(result.builder.rotateWithView).to.eql(false);
|
expect(result.builder.rotateWithView).to.eql(false);
|
||||||
@@ -277,7 +277,7 @@ void main(void) {
|
|||||||
'vec4(vec4(0.2, 0.4, 0.6, 1.0).rgb, vec4(0.2, 0.4, 0.6, 1.0).a * 0.5 * 1.0)'
|
'vec4(vec4(0.2, 0.4, 0.6, 1.0).rgb, vec4(0.2, 0.4, 0.6, 1.0).a * 0.5 * 1.0)'
|
||||||
);
|
);
|
||||||
expect(result.builder.sizeExpression).to.eql(
|
expect(result.builder.sizeExpression).to.eql(
|
||||||
'vec2(((clamp(a_population, u_lower, u_higher) - u_lower) * ((8.0 - 4.0) / (u_higher - u_lower)) + 4.0), ((clamp(a_population, u_lower, u_higher) - u_lower) * ((8.0 - 4.0) / (u_higher - u_lower)) + 4.0))'
|
'vec2(((clamp(a_population, u_lower, u_higher) - u_lower) * ((8.0 - 4.0) / (u_higher - u_lower)) + 4.0))'
|
||||||
);
|
);
|
||||||
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
||||||
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
||||||
@@ -307,10 +307,10 @@ void main(void) {
|
|||||||
expect(result.builder.colorExpression).to.eql(
|
expect(result.builder.colorExpression).to.eql(
|
||||||
'vec4(vec4(0.2, 0.4, 0.6, 1.0).rgb, vec4(0.2, 0.4, 0.6, 1.0).a * 1.0 * 1.0)'
|
'vec4(vec4(0.2, 0.4, 0.6, 1.0).rgb, vec4(0.2, 0.4, 0.6, 1.0).a * 1.0 * 1.0)'
|
||||||
);
|
);
|
||||||
expect(result.builder.sizeExpression).to.eql('vec2(6.0, 6.0)');
|
expect(result.builder.sizeExpression).to.eql('vec2(6.0)');
|
||||||
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
||||||
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
||||||
expect(result.builder.discardExpression).to.eql('(v_attr0 >= 0.0 && v_attr0 <= 10.0)');
|
expect(result.builder.discardExpression).to.eql('!(v_attr0 >= 0.0 && v_attr0 <= 10.0)');
|
||||||
expect(result.builder.rotateWithView).to.eql(false);
|
expect(result.builder.rotateWithView).to.eql(false);
|
||||||
expect(result.attributes.length).to.eql(1);
|
expect(result.attributes.length).to.eql(1);
|
||||||
expect(result.attributes[0].name).to.eql('attr0');
|
expect(result.attributes[0].name).to.eql('attr0');
|
||||||
@@ -330,7 +330,7 @@ void main(void) {
|
|||||||
expect(result.builder.colorExpression).to.eql(
|
expect(result.builder.colorExpression).to.eql(
|
||||||
'vec4(mix(vec4(1.0, 1.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), u_ratio).rgb, mix(vec4(1.0, 1.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), u_ratio).a * 1.0 * 1.0)'
|
'vec4(mix(vec4(1.0, 1.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), u_ratio).rgb, mix(vec4(1.0, 1.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), u_ratio).a * 1.0 * 1.0)'
|
||||||
);
|
);
|
||||||
expect(result.builder.sizeExpression).to.eql('vec2(6.0, 6.0)');
|
expect(result.builder.sizeExpression).to.eql('vec2(6.0)');
|
||||||
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
expect(result.builder.offsetExpression).to.eql('vec2(0.0, 0.0)');
|
||||||
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
expect(result.builder.texCoordExpression).to.eql('vec4(0.0, 0.0, 1.0, 1.0)');
|
||||||
expect(result.builder.rotateWithView).to.eql(false);
|
expect(result.builder.rotateWithView).to.eql(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user