ShaderBuilder / formatColor/Array utilities now output vecX(...)
This commit is contained in:
@@ -18,23 +18,32 @@ export function formatNumber(v) {
|
|||||||
/**
|
/**
|
||||||
* Will return the number array as a float with a dot separator, concatenated with ', '.
|
* Will return the number array as a float with a dot separator, concatenated with ', '.
|
||||||
* @param {Array<number>} array Numerical values array.
|
* @param {Array<number>} array Numerical values array.
|
||||||
* @returns {string} The array as string, e. g.: `1.0, 2.0, 3.0`.
|
* @returns {string} The array as a vector, e. g.: `vec3(1.0, 2.0, 3.0)`.
|
||||||
*/
|
*/
|
||||||
export function formatArray(array) {
|
export function formatArray(array) {
|
||||||
return array.map(formatNumber).join(', ');
|
if (array.length < 2 || array.length > 4) {
|
||||||
|
throw new Error('`formatArray` can only output `vec2`, `vec3` or `vec4` arrays.');
|
||||||
|
}
|
||||||
|
return `vec${array.length}(${array.map(formatNumber).join(', ')})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will normalize and converts to string a color array compatible with GLSL.
|
* Will normalize and converts to string a `vec4` color array compatible with GLSL.
|
||||||
* @param {string|import("../color.js").Color} color Color either in string format or [r, g, b, a] array format,
|
* @param {string|import("../color.js").Color} color Color either in string format or [r, g, b, a] array format,
|
||||||
* with RGB components in the 0..255 range and the alpha component in the 0..1 range. Note that if the A component is
|
* with RGB components in the 0..255 range and the alpha component in the 0..1 range.
|
||||||
* missing, only 3 values will be output.
|
* Note that the final array will always have 4 components.
|
||||||
* @returns {string} The color components concatenated in `1.0, 1.0, 1.0, 1.0` form.
|
* @returns {string} The color expressed in the `vec4(1.0, 1.0, 1.0, 1.0)` form.
|
||||||
*/
|
*/
|
||||||
export function formatColor(color) {
|
export function formatColor(color) {
|
||||||
return asArray(color).map(function(c, i) {
|
const array = asArray(color).slice();
|
||||||
|
if (array.length < 4) {
|
||||||
|
array.push(1);
|
||||||
|
}
|
||||||
|
return formatArray(
|
||||||
|
array.map(function(c, i) {
|
||||||
return i < 3 ? c / 255 : c;
|
return i < 3 ? c / 255 : c;
|
||||||
}).map(formatNumber).join(', ');
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,18 +25,35 @@ describe('ol.webgl.ShaderBuilder', function() {
|
|||||||
|
|
||||||
describe('formatArray', function() {
|
describe('formatArray', function() {
|
||||||
it('outputs numbers with dot separators', function() {
|
it('outputs numbers with dot separators', function() {
|
||||||
expect(formatArray([1, 0, 3.45, 0.8888])).to.eql('1.0, 0.0, 3.45, 0.8888');
|
expect(formatArray([1, 0, 3.45, 0.8888])).to.eql('vec4(1.0, 0.0, 3.45, 0.8888)');
|
||||||
|
expect(formatArray([3, 4])).to.eql('vec2(3.0, 4.0)');
|
||||||
|
});
|
||||||
|
it('throws on invalid lengths', function() {
|
||||||
|
let thrown = false;
|
||||||
|
try {
|
||||||
|
formatArray([3]);
|
||||||
|
} catch (e) {
|
||||||
|
thrown = true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
formatArray([3, 2, 1, 0, -1]);
|
||||||
|
} catch (e) {
|
||||||
|
thrown = true;
|
||||||
|
}
|
||||||
|
expect(thrown).to.be(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('formatColor', function() {
|
describe('formatColor', function() {
|
||||||
it('normalizes color and outputs numbers with dot separators', function() {
|
it('normalizes color and outputs numbers with dot separators', function() {
|
||||||
expect(formatColor([100, 0, 255, 1])).to.eql('0.39215686274509803, 0.0, 1.0, 1.0');
|
expect(formatColor([100, 0, 255])).to.eql('vec4(0.39215686274509803, 0.0, 1.0, 1.0)');
|
||||||
|
expect(formatColor([100, 0, 255, 1])).to.eql('vec4(0.39215686274509803, 0.0, 1.0, 1.0)');
|
||||||
});
|
});
|
||||||
it('handles colors in string format', function() {
|
it('handles colors in string format', function() {
|
||||||
expect(formatColor('red')).to.eql('1.0, 0.0, 0.0, 1.0');
|
expect(formatColor('red')).to.eql('vec4(1.0, 0.0, 0.0, 1.0)');
|
||||||
expect(formatColor('rgb(100, 0, 255)')).to.eql('0.39215686274509803, 0.0, 1.0, 1.0');
|
expect(formatColor('#00ff99')).to.eql('vec4(0.0, 1.0, 0.6, 1.0)');
|
||||||
expect(formatColor('rgba(100, 0, 255, 0.3)')).to.eql('0.39215686274509803, 0.0, 1.0, 0.3');
|
expect(formatColor('rgb(100, 0, 255)')).to.eql('vec4(0.39215686274509803, 0.0, 1.0, 1.0)');
|
||||||
|
expect(formatColor('rgba(100, 0, 255, 0.3)')).to.eql('vec4(0.39215686274509803, 0.0, 1.0, 0.3)');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -84,11 +101,11 @@ describe('ol.webgl.ShaderBuilder', function() {
|
|||||||
it('generates a symbol vertex shader (with varying)', function() {
|
it('generates a symbol vertex shader (with varying)', function() {
|
||||||
const builder = new ShaderBuilder();
|
const builder = new ShaderBuilder();
|
||||||
builder.addVarying('v_opacity', 'float', formatNumber(0.4));
|
builder.addVarying('v_opacity', 'float', formatNumber(0.4));
|
||||||
builder.addVarying('v_test', 'vec3', 'vec3(' + formatArray([1, 2, 3]) + ')');
|
builder.addVarying('v_test', 'vec3', formatArray([1, 2, 3]));
|
||||||
builder.setSizeExpression('vec2(' + formatNumber(6) + ')');
|
builder.setSizeExpression(`vec2(${formatNumber(6)})`);
|
||||||
builder.setSymbolOffsetExpression('vec2(' + formatArray([5, -7]) + ')');
|
builder.setSymbolOffsetExpression(formatArray([5, -7]));
|
||||||
builder.setColorExpression('vec4(' + formatColor([80, 0, 255, 1]) + ')');
|
builder.setColorExpression(formatColor([80, 0, 255, 1]));
|
||||||
builder.setTextureCoordinateExpression('vec4(' + formatArray([0, 0.5, 0.5, 1]) + ')');
|
builder.setTextureCoordinateExpression(formatArray([0, 0.5, 0.5, 1]));
|
||||||
|
|
||||||
expect(builder.getSymbolVertexShader()).to.eql(`precision mediump float;
|
expect(builder.getSymbolVertexShader()).to.eql(`precision mediump float;
|
||||||
uniform mat4 u_projectionMatrix;
|
uniform mat4 u_projectionMatrix;
|
||||||
@@ -126,10 +143,10 @@ void main(void) {
|
|||||||
const builder = new ShaderBuilder();
|
const builder = new ShaderBuilder();
|
||||||
builder.addUniform('float u_myUniform');
|
builder.addUniform('float u_myUniform');
|
||||||
builder.addAttribute('vec2 a_myAttr');
|
builder.addAttribute('vec2 a_myAttr');
|
||||||
builder.setSizeExpression('vec2(' + formatNumber(6) + ')');
|
builder.setSizeExpression(`vec2(${formatNumber(6)})`);
|
||||||
builder.setSymbolOffsetExpression('vec2(' + formatArray([5, -7]) + ')');
|
builder.setSymbolOffsetExpression(formatArray([5, -7]));
|
||||||
builder.setColorExpression('vec4(' + formatColor([80, 0, 255, 1]) + ')');
|
builder.setColorExpression(formatColor([80, 0, 255, 1]));
|
||||||
builder.setTextureCoordinateExpression('vec4(' + formatArray([0, 0.5, 0.5, 1]) + ')');
|
builder.setTextureCoordinateExpression(formatArray([0, 0.5, 0.5, 1]));
|
||||||
|
|
||||||
expect(builder.getSymbolVertexShader()).to.eql(`precision mediump float;
|
expect(builder.getSymbolVertexShader()).to.eql(`precision mediump float;
|
||||||
uniform mat4 u_projectionMatrix;
|
uniform mat4 u_projectionMatrix;
|
||||||
@@ -163,10 +180,10 @@ void main(void) {
|
|||||||
});
|
});
|
||||||
it('generates a symbol vertex shader (with rotateWithView)', function() {
|
it('generates a symbol vertex shader (with rotateWithView)', function() {
|
||||||
const builder = new ShaderBuilder();
|
const builder = new ShaderBuilder();
|
||||||
builder.setSizeExpression('vec2(' + formatNumber(6) + ')');
|
builder.setSizeExpression(`vec2(${formatNumber(6)})`);
|
||||||
builder.setSymbolOffsetExpression('vec2(' + formatArray([5, -7]) + ')');
|
builder.setSymbolOffsetExpression(formatArray([5, -7]));
|
||||||
builder.setColorExpression('vec4(' + formatColor([80, 0, 255, 1]) + ')');
|
builder.setColorExpression(formatColor([80, 0, 255, 1]));
|
||||||
builder.setTextureCoordinateExpression('vec4(' + formatArray([0, 0.5, 0.5, 1]) + ')');
|
builder.setTextureCoordinateExpression(formatArray([0, 0.5, 0.5, 1]));
|
||||||
builder.setSymbolRotateWithView(true);
|
builder.setSymbolRotateWithView(true);
|
||||||
|
|
||||||
expect(builder.getSymbolVertexShader()).to.eql(`precision mediump float;
|
expect(builder.getSymbolVertexShader()).to.eql(`precision mediump float;
|
||||||
@@ -205,11 +222,11 @@ void main(void) {
|
|||||||
it('generates a symbol fragment shader (with varying)', function() {
|
it('generates a symbol fragment shader (with varying)', function() {
|
||||||
const builder = new ShaderBuilder();
|
const builder = new ShaderBuilder();
|
||||||
builder.addVarying('v_opacity', 'float', formatNumber(0.4));
|
builder.addVarying('v_opacity', 'float', formatNumber(0.4));
|
||||||
builder.addVarying('v_test', 'vec3', 'vec3(' + formatArray([1, 2, 3]) + ')');
|
builder.addVarying('v_test', 'vec3', formatArray([1, 2, 3]));
|
||||||
builder.setSizeExpression('vec2(' + formatNumber(6) + ')');
|
builder.setSizeExpression(`vec2(${formatNumber(6)})`);
|
||||||
builder.setSymbolOffsetExpression('vec2(' + formatArray([5, -7]) + ')');
|
builder.setSymbolOffsetExpression(formatArray([5, -7]));
|
||||||
builder.setColorExpression('vec4(' + formatColor([80, 0, 255]) + ', v_opacity)');
|
builder.setColorExpression(formatColor([80, 0, 255]));
|
||||||
builder.setTextureCoordinateExpression('vec4(' + formatArray([0, 0.5, 0.5, 1]) + ')');
|
builder.setTextureCoordinateExpression(formatArray([0, 0.5, 0.5, 1]));
|
||||||
|
|
||||||
expect(builder.getSymbolFragmentShader()).to.eql(`precision mediump float;
|
expect(builder.getSymbolFragmentShader()).to.eql(`precision mediump float;
|
||||||
uniform float u_time;
|
uniform float u_time;
|
||||||
@@ -220,7 +237,7 @@ varying float v_opacity;
|
|||||||
varying vec3 v_test;
|
varying vec3 v_test;
|
||||||
void main(void) {
|
void main(void) {
|
||||||
if (false) { discard; }
|
if (false) { discard; }
|
||||||
gl_FragColor = vec4(0.3137254901960784, 0.0, 1.0, v_opacity);
|
gl_FragColor = vec4(0.3137254901960784, 0.0, 1.0, 1.0);
|
||||||
gl_FragColor.rgb *= gl_FragColor.a;
|
gl_FragColor.rgb *= gl_FragColor.a;
|
||||||
}`);
|
}`);
|
||||||
});
|
});
|
||||||
@@ -228,10 +245,10 @@ void main(void) {
|
|||||||
const builder = new ShaderBuilder();
|
const builder = new ShaderBuilder();
|
||||||
builder.addUniform('float u_myUniform');
|
builder.addUniform('float u_myUniform');
|
||||||
builder.addUniform('vec2 u_myUniform2');
|
builder.addUniform('vec2 u_myUniform2');
|
||||||
builder.setSizeExpression('vec2(' + formatNumber(6) + ')');
|
builder.setSizeExpression(`vec2(${formatNumber(6)})`);
|
||||||
builder.setSymbolOffsetExpression('vec2(' + formatArray([5, -7]) + ')');
|
builder.setSymbolOffsetExpression(formatArray([5, -7]));
|
||||||
builder.setColorExpression('vec4(' + formatColor([255, 255, 255, 1]) + ')');
|
builder.setColorExpression(formatColor([255, 255, 255, 1]));
|
||||||
builder.setTextureCoordinateExpression('vec4(' + formatArray([0, 0.5, 0.5, 1]) + ')');
|
builder.setTextureCoordinateExpression(formatArray([0, 0.5, 0.5, 1]));
|
||||||
builder.setFragmentDiscardExpression('u_myUniform > 0.5');
|
builder.setFragmentDiscardExpression('u_myUniform > 0.5');
|
||||||
|
|
||||||
expect(builder.getSymbolFragmentShader()).to.eql(`precision mediump float;
|
expect(builder.getSymbolFragmentShader()).to.eql(`precision mediump float;
|
||||||
|
|||||||
Reference in New Issue
Block a user