Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas Wojciechowski committed Jan 14, 2016
1 parent c1d8e06 commit 263def1
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 82 deletions.
2 changes: 1 addition & 1 deletion debug/random.geojson

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion debug/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ map.on('style.load', function() {
"source": "geojson-random-points",
"paint": {
"circle-radius": 5,
"circle-color": "#f0f"
"circle-color": {
range: ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'],
domain: [0, 16, 32, 48, 64, 80, 100],
property: 'mapbox'
}
}
});

Expand Down
65 changes: 62 additions & 3 deletions js/data/bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ Bucket.prototype.resetBuffers = function(buffers) {
if (shader.vertexBuffer && !buffers[vertexBufferName]) {
buffers[vertexBufferName] = new Buffer({
type: Buffer.BufferType.VERTEX,
attributes: shader.attributes
attributes: this._getEnabledAttributes(shaderName)
});
}

Expand Down Expand Up @@ -150,6 +150,61 @@ Bucket.prototype.resetBuffers = function(buffers) {
}
};

Bucket.prototype._getEnabledAttributes = function(shaderName) {
return this.shaders[shaderName].attributes.filter(function(attribute) {
return !attribute.isDisabled || !attribute.isDisabled.call(this);
}, this);
};

/**
* Set the attribute pointers in a WebGL context
* @private
* @param gl The WebGL context
* @param shader The active WebGL shader
* @param {number} offset The offset of the attribute data in the currently bound GL buffer.
*/
Bucket.prototype.setAttribPointers = function(shaderName, gl, glShader, offset, args) {
var attributes = this.shaders[shaderName].attributes;

// Set disabled attributes
for (var i = 0; i < attributes.length; i++) {
var attribute = attributes[i];
var glAttribute = glShader['a_' + attribute.name];
if (attribute.isDisabled && attribute.isDisabled.call(this)) {
gl.disableVertexAttribArray(glAttribute);
gl['vertexAttrib' + attribute.components + 'fv'](glAttribute, this._getAttributeValue(shaderName, attribute, args));
}
}

// Set enabled attributes
this.buffers[this.getBufferName(shaderName, 'vertex')].setAttribPointers(gl, glShader, offset);
};

var _getAttributeValueCache = {};
// TODO break the function creation logic into a separate function
Bucket.prototype._getAttributeValue = function(shaderName, attribute, args) {
if (!_getAttributeValueCache[shaderName]) _getAttributeValueCache[shaderName] = {};

if (!_getAttributeValueCache[shaderName][attribute.name]) {
var bodyArgs = this.shaders[shaderName].attributeArgs;
var body = 'return ';
if (Array.isArray(attribute.value)) {
body += '[' + attribute.value.join(', ') + ']';
} else {
body += attribute.value;
}
_getAttributeValueCache[shaderName][attribute.name] = new Function(bodyArgs, body);
}

var value = _getAttributeValueCache[shaderName][attribute.name].apply(this, args);

if (attribute.multiplier) {
return value.map(function(v) { return v * attribute.multiplier; });
} else {
return value;
}
};

/**
* Get the name of the method used to add an item to a buffer.
* @param {string} shaderName The name of the shader that will use the buffer
Expand Down Expand Up @@ -236,13 +291,17 @@ function createVertexAddMethod(shaderName, shader, bufferName) {
}
}

var multipliedAttributePushArgs;
if (attribute.multiplier) {
multipliedAttributePushArgs = [];
for (var k = 0; k < attributePushArgs.length; k++) {
attributePushArgs[k] += '*' + attribute.multiplier;
multipliedAttributePushArgs[k] = attributePushArgs[k] + '*' + attribute.multiplier;
}
} else {
multipliedAttributePushArgs = attributePushArgs;
}

pushArgs = pushArgs.concat(attributePushArgs);
pushArgs = pushArgs.concat(multipliedAttributePushArgs);
}

body += 'return this.buffers.' + bufferName + '.push(' + pushArgs.join(',') + ');';
Expand Down
20 changes: 12 additions & 8 deletions js/data/circle_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

var Bucket = require('./bucket');
var util = require('../util/util');
var StyleFunction = require('../style/style_function');
var parseColor = require('../style/parse_color');

module.exports = CircleBucket;

Expand All @@ -14,7 +16,8 @@ var EXTENT = 4096;
* vector that is where it points.
* @private
*/
function CircleBucket() {
function CircleBucket(options) {
this.circleColorFunction = StyleFunction.create(parseColor(options.layer.paint['circle-color']));
Bucket.apply(this, arguments);
}

Expand All @@ -25,7 +28,7 @@ CircleBucket.prototype.shaders = {
vertexBuffer: true,
elementBuffer: true,

attributeArgs: ['x', 'y', 'extrudeX', 'extrudeY', 'paint'],
attributeArgs: ['global', 'feature', 'x', 'y', 'extrudeX', 'extrudeY'],

attributes: [{
name: 'pos',
Expand All @@ -39,8 +42,9 @@ CircleBucket.prototype.shaders = {
name: 'color',
components: 4,
type: Bucket.AttributeType.UNSIGNED_BYTE,
value: 'paint["circle-color"]',
multiplier: 255
value: 'this.circleColorFunction(global, feature)',
multiplier: 255,
isDisabled: function() { return this.circleColorFunction.isFeatureConstant; }
}]
}
};
Expand All @@ -66,10 +70,10 @@ CircleBucket.prototype.addFeature = function(feature) {
// │ 0 1 │
// └─────────┘

var index = this.addCircleVertex(x, y, -1, -1, this.paintProperties) - group.vertexStartIndex;
this.addCircleVertex(x, y, 1, -1, this.paintProperties);
this.addCircleVertex(x, y, 1, 1, this.paintProperties);
this.addCircleVertex(x, y, -1, 1, this.paintProperties);
var index = this.addCircleVertex(null, feature.properties, x, y, -1, -1) - group.vertexStartIndex;
this.addCircleVertex(null, feature.properties, x, y, 1, -1);
this.addCircleVertex(null, feature.properties, x, y, 1, 1);
this.addCircleVertex(null, feature.properties, x, y, -1, 1);
group.vertexLength += 4;

this.addCircleElement(index, index + 1, index + 2);
Expand Down
3 changes: 2 additions & 1 deletion js/render/draw_circle.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ function drawCircles(painter, source, layer, coords) {
if (!tile.elementGroups[layer.ref || layer.id].circle) continue;

var elementGroups = tile.elementGroups[layer.ref || layer.id].circle;
var bucket = tile.buckets[layer.ref || layer.id];
var vertex = tile.buffers.circleVertex;
var elements = tile.buffers.circleElement;

Expand All @@ -55,7 +56,7 @@ function drawCircles(painter, source, layer, coords) {
var offset = group.vertexStartIndex * vertex.itemSize;

vertex.bind(gl);
vertex.setAttribPointers(gl, shader, offset);
bucket.setAttribPointers('circle', gl, shader, offset, [{$zoom: painter.transform.zoom}]);

elements.bind(gl);

Expand Down
4 changes: 4 additions & 0 deletions js/render/gl_util.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ exports.extend = function(context) {
}
};

context.vertexAttrib1fv = function(attribute, values) {
context.vertexAttrib1f(attribute, values[0]);
};

context.vertexAttrib2fv = function(attribute, values) {
context.vertexAttrib2f(attribute, values[0], values[1]);
};
Expand Down
2 changes: 1 addition & 1 deletion js/source/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ function unserializeBuffers(input) {
function unserializeBuckets(input, buffers) {
var output = {};
for (var i = 0; i < input.length; i++) {
var bucket = new Bucket(util.extend(input[i], {buffers: buffers}));
var bucket = Bucket.create(util.extend(input[i], {buffers: buffers}));
output[bucket.id] = bucket;
}
return output;
Expand Down
47 changes: 47 additions & 0 deletions js/style/parse_color.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';

var parseCSSColor = require('csscolorparser').parseCSSColor;
var util = require('../util/util');

var colorCache = {};

function parseColor(input) {

if (colorCache[input]) {
return colorCache[input];

// RGBA array
} else if (Array.isArray(input)) {
return input;

// style function
} else if (input && input.range) {
return util.extend({}, input, {
range: input.range.map(parseColor)
});

// legacy style function
} else if (input && input.stops) {
return util.extend({}, input, {
stops: input.stops.map(function(step) {
return [step[0], parseColor(step[1])];
})
});

// Color string
} else if (typeof input === 'string') {
var output = colorDowngrade(parseCSSColor(input));
colorCache[input] = output;
return output;

} else {
throw new Error('Invalid color ' + input);
}

}

function colorDowngrade(color) {
return [color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 1];
}

module.exports = parseColor;
70 changes: 3 additions & 67 deletions js/style/style_declaration.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,7 @@
'use strict';

var parseCSSColor = require('csscolorparser').parseCSSColor;
var createGLFunction = require('mapbox-gl-function');
var util = require('../util/util');

function createBackwardsCompatibleGLFunction(reference, parameters) {
if (parameters.stops) {
var domain = [];
var range = [];

for (var i = 0; i < parameters.stops.length; i++) {
domain.push(parameters.stops[i][0]);
range.push(parameters.stops[i][1]);
}

parameters.domain = domain;
parameters.range = range;
delete parameters.stops;

if (reference.function === 'interpolated') {
parameters.type = 'exponential';
} else {
parameters.domain.shift();
parameters.type = 'interval';
}
}

var fun = createGLFunction(parameters);
return function(zoom) {
return fun({$zoom: zoom});
};
}
var StyleFunction = require('./style_function');
var parseColor = require('./parse_color');

module.exports = StyleDeclaration;

Expand All @@ -51,7 +22,7 @@ function StyleDeclaration(reference, value) {
this.value = value;
}

this.calculate = createBackwardsCompatibleGLFunction(reference, this.value);
this.calculate = StyleFunction.createBackwardsCompatible(reference, this.value);

if (reference.function !== 'interpolated' && reference.transition) {
this.calculate = transitioned(this.calculate);
Expand Down Expand Up @@ -87,38 +58,3 @@ function transitioned(calculate) {
};
};
}

var colorCache = {};

function parseColor(input) {

if (colorCache[input]) {
return colorCache[input];

// RGBA array
} else if (Array.isArray(input)) {
return input;

// GL function
} else if (input && input.stops) {
return util.extend({}, input, {
stops: input.stops.map(function(step) {
return [step[0], parseColor(step[1])];
})
});

// Color string
} else if (typeof input === 'string') {
var output = colorDowngrade(parseCSSColor(input));
colorCache[input] = output;
return output;

} else {
throw new Error('Invalid color ' + input);
}

}

function colorDowngrade(color) {
return [color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 1];
}
36 changes: 36 additions & 0 deletions js/style/style_function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';

var createStyleFunction = require('mapbox-gl-function');

function createBackwardsCompatibleStyleFunction(reference, parameters) {
if (parameters.stops) {
var domain = [];
var range = [];

for (var i = 0; i < parameters.stops.length; i++) {
domain.push(parameters.stops[i][0]);
range.push(parameters.stops[i][1]);
}

parameters.domain = domain;
parameters.range = range;
delete parameters.stops;

if (reference.function === 'interpolated') {
parameters.type = 'exponential';
} else {
parameters.domain.shift();
parameters.type = 'interval';
}
}

var fun = createStyleFunction(parameters);
return function(zoom) {
return fun({$zoom: zoom}, {});
};
}

module.exports = {
create: createStyleFunction,
createBackwardsCompatible: createBackwardsCompatibleStyleFunction
};

0 comments on commit 263def1

Please sign in to comment.