diff --git a/src/ol/style/expressions.js b/src/ol/style/expressions.js index b3d2961bb0..40b9774195 100644 --- a/src/ol/style/expressions.js +++ b/src/ol/style/expressions.js @@ -115,7 +115,9 @@ export function getValueType(value) { /** * Context available during the parsing of an expression. * @typedef {Object} ParsingContext - * @property {boolean} inFragmentShader If false, means the expression output should be made for a vertex shader + * @property {boolean} [inFragmentShader] If false, means the expression output should be made for a vertex shader + * @property {Array} variables List of variables used in the expression; contains **unprefixed names** + * @property {Array} attributes List of attributes used in the expression; contains **unprefixed names** */ /** @@ -239,10 +241,14 @@ export const Operators = { return ValueTypes.ANY; }, toGlsl: function(context, args) { - const prefix = context.inFragmentShader ? 'v_' : 'a_'; assertArgsCount(args, 1); assertString(args[0]); - return prefix + expressionToGlsl(context, args[0]); + const value = expressionToGlsl(context, args[0]); + if (context.attributes.indexOf(value) === -1) { + context.attributes.push(value); + } + const prefix = context.inFragmentShader ? 'v_' : 'a_'; + return prefix + value; } }, 'var': { @@ -252,7 +258,11 @@ export const Operators = { toGlsl: function(context, args) { assertArgsCount(args, 1); assertString(args[0]); - return `u_${expressionToGlsl(context, args[0])}`; + const value = expressionToGlsl(context, args[0]); + if (context.variables.indexOf(value) === -1) { + context.variables.push(value); + } + return `u_${value}`; } }, 'time': { diff --git a/test/spec/ol/style/expressions.test.js b/test/spec/ol/style/expressions.test.js index 1c430d307f..03eb49a896 100644 --- a/test/spec/ol/style/expressions.test.js +++ b/test/spec/ol/style/expressions.test.js @@ -114,7 +114,10 @@ describe('ol.style.expressions', function() { let context; beforeEach(function() { - context = {}; + context = { + variables: [], + attributes: [] + }; }); it('correctly converts expressions to GLSL', function() { @@ -137,6 +140,21 @@ describe('ol.style.expressions', function() { 'mix(vec4(1.0, 1.0, 1.0, 1.0), vec4(0.0, 0.0, 0.0, 0.0), a_attr4)'); }); + it('correctly adapts output for fragment shaders', function() { + context.inFragmentShader = true; + expect(expressionToGlsl(context, ['get', 'myAttr'])).to.eql('v_myAttr'); + }); + + it('correctly adapts output for fragment shaders', function() { + expressionToGlsl(context, ['get', 'myAttr']); + expressionToGlsl(context, ['var', 'myVar']); + expressionToGlsl(context, ['clamp', ['get', 'attr2'], ['get', 'attr2'], ['get', 'myAttr']]); + expressionToGlsl(context, ['*', ['get', 'attr2'], ['var', 'myVar']]); + expressionToGlsl(context, ['*', ['get', 'attr3'], ['var', 'myVar2']]); + expect(context.attributes).to.eql(['myAttr', 'attr2', 'attr3']); + expect(context.variables).to.eql(['myVar', 'myVar2']); + }); + }); });