[core] rudimentary support for offsetting lines
This commit is contained in:
committed by
John Firebaugh
parent
c279fb1717
commit
964a1e7b62
@@ -26,7 +26,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"aws-sdk": "^2.2.19",
|
||||
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#b345658107e1772dbf7e24c4a8e53590cb78521d",
|
||||
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#a9f967740f1045e0ecaa5d7ebd9afbd7e84d0f94",
|
||||
"node-gyp": "^3.2.0",
|
||||
"request": "^2.67.0",
|
||||
"tape": "^4.2.2"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
GLsizei LineVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey, int8_t tx, int8_t ty, int32_t linesofar) {
|
||||
GLsizei LineVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey, bool tx, bool ty, int8_t dir, int32_t linesofar) {
|
||||
GLsizei idx = index();
|
||||
void *data = addElement();
|
||||
|
||||
@@ -16,8 +16,13 @@ GLsizei LineVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey,
|
||||
int8_t *extrude = static_cast<int8_t *>(data);
|
||||
extrude[4] = ::round(extrudeScale * ex);
|
||||
extrude[5] = ::round(extrudeScale * ey);
|
||||
extrude[6] = static_cast<int8_t>(linesofar / 128);
|
||||
extrude[7] = static_cast<int8_t>(linesofar % 128);
|
||||
|
||||
// Encode the -1/0/1 direction value into .zw coordinates of a_data, which is normally covered
|
||||
// by linesofar, so we need to merge them.
|
||||
// The z component's first bit, as well as the sign bit is reserved for the direction,
|
||||
// so we need to shift the linesofar.
|
||||
extrude[6] = ((dir < 0) ? -1 : 1) * ((dir ? 1 : 0) | static_cast<int8_t>((linesofar << 1) & 0x7F));
|
||||
extrude[7] = (linesofar >> 6) & 0x7F;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,9 @@ public:
|
||||
* @param {number} ey extrude normal
|
||||
* @param {number} tx texture normal
|
||||
* @param {number} ty texture normal
|
||||
* @param {number} dir direction of the line cap (-1/0/1)
|
||||
*/
|
||||
GLsizei add(vertex_type x, vertex_type y, float ex, float ey, int8_t tx, int8_t ty, int32_t linesofar = 0);
|
||||
GLsizei add(vertex_type x, vertex_type y, float ex, float ey, bool tx, bool ty, int8_t dir, int32_t linesofar = 0);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ void LineLayer::parsePaints(const JSVal& layer) {
|
||||
paint.translateAnchor.parse("line-translate-anchor", layer);
|
||||
paint.width.parse("line-width", layer);
|
||||
paint.gapWidth.parse("line-gap-width", layer);
|
||||
paint.offset.parse("line-offset", layer);
|
||||
paint.blur.parse("line-blur", layer);
|
||||
paint.dasharray.parse("line-dasharray", layer);
|
||||
paint.pattern.parse("line-pattern", layer);
|
||||
@@ -39,6 +40,7 @@ void LineLayer::cascade(const StyleCascadeParameters& parameters) {
|
||||
paint.translateAnchor.cascade(parameters);
|
||||
paint.width.cascade(parameters);
|
||||
paint.gapWidth.cascade(parameters);
|
||||
paint.offset.cascade(parameters);
|
||||
paint.blur.cascade(parameters);
|
||||
paint.dasharray.cascade(parameters);
|
||||
paint.pattern.cascade(parameters);
|
||||
@@ -59,6 +61,7 @@ bool LineLayer::recalculate(const StyleCalculationParameters& parameters) {
|
||||
hasTransitions |= paint.translateAnchor.calculate(parameters);
|
||||
hasTransitions |= paint.width.calculate(parameters);
|
||||
hasTransitions |= paint.gapWidth.calculate(parameters);
|
||||
hasTransitions |= paint.offset.calculate(parameters);
|
||||
hasTransitions |= paint.blur.calculate(parameters);
|
||||
hasTransitions |= paint.dasharray.calculate(parameters);
|
||||
hasTransitions |= paint.pattern.calculate(parameters);
|
||||
|
||||
@@ -24,6 +24,7 @@ public:
|
||||
PaintProperty<float> width = 1;
|
||||
PaintProperty<float> gapWidth = 0;
|
||||
PaintProperty<float> blur = 0;
|
||||
PaintProperty<float> offset = 0;
|
||||
PaintProperty<std::vector<float>, Faded<std::vector<float>>> dasharray = { {} };
|
||||
PaintProperty<std::string, Faded<std::string>> pattern = { "" };
|
||||
|
||||
|
||||
@@ -187,8 +187,9 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
|
||||
addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex,
|
||||
triangleStore);
|
||||
flip = -flip;
|
||||
|
||||
addCurrentVertex(currentVertex, -flip, distance, joinNormal, 0, 0, false, startVertex,
|
||||
triangleStore);
|
||||
} else if (middleVertex && (currentJoin == JoinType::Bevel || currentJoin == JoinType::FakeRound)) {
|
||||
const bool lineTurnsLeft = flip * (prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x) > 0;
|
||||
const float offset = -std::sqrt(miterLength * miterLength - 1);
|
||||
@@ -334,7 +335,7 @@ void LineBucket::addCurrentVertex(const Coordinate& currentVertex,
|
||||
vec2<double> extrude = normal * flip;
|
||||
if (endLeft)
|
||||
extrude = extrude - (util::perp(normal) * endLeft);
|
||||
e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 0, distance)
|
||||
e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 0, endLeft, distance)
|
||||
- startVertex;
|
||||
if (e1 >= 0 && e2 >= 0) {
|
||||
triangleStore.emplace_back(e1, e2, e3);
|
||||
@@ -345,7 +346,7 @@ void LineBucket::addCurrentVertex(const Coordinate& currentVertex,
|
||||
extrude = normal * (-flip);
|
||||
if (endRight)
|
||||
extrude = extrude - (util::perp(normal) * endRight);
|
||||
e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 1, distance)
|
||||
e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 1, -endRight, distance)
|
||||
- startVertex;
|
||||
if (e1 >= 0 && e2 >= 0) {
|
||||
triangleStore.emplace_back(e1, e2, e3);
|
||||
@@ -364,7 +365,7 @@ void LineBucket::addPieSliceVertex(const Coordinate& currentVertex,
|
||||
int8_t ty = lineTurnsLeft;
|
||||
|
||||
auto flippedExtrude = extrude * (flip * (lineTurnsLeft ? -1 : 1));
|
||||
e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, flippedExtrude.x, flippedExtrude.y, 0, ty, distance)
|
||||
e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, flippedExtrude.x, flippedExtrude.y, 0, ty, 0, distance)
|
||||
- startVertex;
|
||||
if (e1 >= 0 && e2 >= 0) {
|
||||
triangleStore.emplace_back(e1, e2, e3);
|
||||
|
||||
@@ -97,6 +97,7 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI
|
||||
linesdfShader->u_sdfgamma = lineAtlas->width / (properties.dashLineWidth * std::min(posA.width, posB.width) * 256.0 * data.pixelRatio) / 2;
|
||||
linesdfShader->u_mix = properties.dasharray.value.t;
|
||||
linesdfShader->u_extra = extra;
|
||||
linesdfShader->u_offset = properties.offset;
|
||||
linesdfShader->u_antialiasingmatrix = antialiasingMatrix;
|
||||
|
||||
bucket.drawLineSDF(*linesdfShader);
|
||||
@@ -127,6 +128,7 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI
|
||||
linepatternShader->u_fade = properties.pattern.value.t;
|
||||
linepatternShader->u_opacity = properties.opacity;
|
||||
linepatternShader->u_extra = extra;
|
||||
linepatternShader->u_offset = properties.offset;
|
||||
linepatternShader->u_antialiasingmatrix = antialiasingMatrix;
|
||||
|
||||
MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0));
|
||||
@@ -143,6 +145,7 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI
|
||||
lineShader->u_ratio = ratio;
|
||||
lineShader->u_blur = blur;
|
||||
lineShader->u_extra = extra;
|
||||
lineShader->u_offset = properties.offset;
|
||||
lineShader->u_antialiasingmatrix = antialiasingMatrix;
|
||||
|
||||
lineShader->u_color = color;
|
||||
|
||||
@@ -14,6 +14,7 @@ uniform mat4 u_matrix;
|
||||
// shared
|
||||
uniform float u_ratio;
|
||||
uniform vec2 u_linewidth;
|
||||
uniform float u_offset;
|
||||
|
||||
uniform float u_extra;
|
||||
uniform mat2 u_antialiasingmatrix;
|
||||
@@ -23,6 +24,7 @@ varying float v_gamma_scale;
|
||||
|
||||
void main() {
|
||||
vec2 a_extrude = a_data.xy;
|
||||
float a_direction = sign(a_data.z) * mod(a_data.z, 2.0);
|
||||
|
||||
// We store the texture normals in the most insignificant bit
|
||||
// transform y so that 0 => -1 and 1 => 1
|
||||
@@ -36,11 +38,19 @@ void main() {
|
||||
// of this vertex.
|
||||
vec2 dist = u_linewidth.s * a_extrude * scale;
|
||||
|
||||
// Calculate the offset when drawing a line that is to the side of the actual line.
|
||||
// We do this by creating a vector that points towards the extrude, but rotate
|
||||
// it when we're drawing round end points (a_direction = -1 or 1) since their
|
||||
// extrude vector points in another direction.
|
||||
float u = 0.5 * a_direction;
|
||||
float t = 1.0 - abs(u);
|
||||
vec2 offset = u_offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
|
||||
|
||||
// Remove the texture normal bit of the position before scaling it with the
|
||||
// model/view matrix. Add the extrusion vector *after* the model/view matrix
|
||||
// because we're extruding the line in pixel space, regardless of the current
|
||||
// tile's zoom level.
|
||||
gl_Position = u_matrix * vec4(floor(a_pos * 0.5) + dist / u_ratio, 0.0, 1.0);
|
||||
gl_Position = u_matrix * vec4(floor(a_pos * 0.5) + (offset + dist) / u_ratio, 0.0, 1.0);
|
||||
|
||||
// position of y on the screen
|
||||
float y = gl_Position.y / gl_Position.w;
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
Uniform<GLfloat> u_ratio = {"u_ratio", *this};
|
||||
Uniform<GLfloat> u_blur = {"u_blur", *this};
|
||||
Uniform<GLfloat> u_extra = {"u_extra", *this};
|
||||
Uniform<GLfloat> u_offset = {"u_offset", *this};
|
||||
UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
|
||||
|
||||
private:
|
||||
|
||||
@@ -17,6 +17,7 @@ uniform mat4 u_exmatrix;
|
||||
// shared
|
||||
uniform float u_ratio;
|
||||
uniform vec2 u_linewidth;
|
||||
uniform float u_offset;
|
||||
uniform vec4 u_color;
|
||||
|
||||
uniform float u_extra;
|
||||
@@ -28,7 +29,8 @@ varying float v_gamma_scale;
|
||||
|
||||
void main() {
|
||||
vec2 a_extrude = a_data.xy;
|
||||
float a_linesofar = a_data.z * 128.0 + a_data.w;
|
||||
float a_direction = sign(a_data.z) * mod(a_data.z, 2.0);
|
||||
float a_linesofar = abs(floor(a_data.z / 2.0)) + a_data.w * 64.0;
|
||||
|
||||
// We store the texture normals in the most insignificant bit
|
||||
// transform y so that 0 => -1 and 1 => 1
|
||||
@@ -42,11 +44,19 @@ void main() {
|
||||
// of this vertex.
|
||||
vec2 dist = u_linewidth.s * a_extrude * scale;
|
||||
|
||||
// Calculate the offset when drawing a line that is to the side of the actual line.
|
||||
// We do this by creating a vector that points towards the extrude, but rotate
|
||||
// it when we're drawing round end points (a_direction = -1 or 1) since their
|
||||
// extrude vector points in another direction.
|
||||
float u = 0.5 * a_direction;
|
||||
float t = 1.0 - abs(u);
|
||||
vec2 offset = u_offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
|
||||
|
||||
// Remove the texture normal bit of the position before scaling it with the
|
||||
// model/view matrix. Add the extrusion vector *after* the model/view matrix
|
||||
// because we're extruding the line in pixel space, regardless of the current
|
||||
// tile's zoom level.
|
||||
gl_Position = u_matrix * vec4(floor(a_pos / 2.0) + dist.xy / u_ratio, 0.0, 1.0);
|
||||
gl_Position = u_matrix * vec4(floor(a_pos / 2.0) + (offset + dist) / u_ratio, 0.0, 1.0);
|
||||
v_linesofar = a_linesofar;
|
||||
|
||||
// position of y on the screen
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
Uniform<GLfloat> u_fade = {"u_fade", *this};
|
||||
Uniform<GLfloat> u_opacity = {"u_opacity", *this};
|
||||
Uniform<GLfloat> u_extra = {"u_extra", *this};
|
||||
Uniform<GLfloat> u_offset = {"u_offset", *this};
|
||||
UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
|
||||
|
||||
private:
|
||||
|
||||
@@ -17,6 +17,7 @@ uniform mat4 u_exmatrix;
|
||||
// shared
|
||||
uniform float u_ratio;
|
||||
uniform vec2 u_linewidth;
|
||||
uniform float u_offset;
|
||||
uniform vec2 u_patternscale_a;
|
||||
uniform float u_tex_y_a;
|
||||
uniform vec2 u_patternscale_b;
|
||||
@@ -32,7 +33,8 @@ varying float v_gamma_scale;
|
||||
|
||||
void main() {
|
||||
vec2 a_extrude = a_data.xy;
|
||||
float a_linesofar = a_data.z * 128.0 + a_data.w;
|
||||
float a_direction = sign(a_data.z) * mod(a_data.z, 2.0);
|
||||
float a_linesofar = abs(floor(a_data.z / 2.0)) + a_data.w * 64.0;
|
||||
|
||||
// We store the texture normals in the most insignificant bit
|
||||
// transform y so that 0 => -1 and 1 => 1
|
||||
@@ -46,11 +48,19 @@ void main() {
|
||||
// of this vertex.
|
||||
vec2 dist = u_linewidth.s * a_extrude * scale;
|
||||
|
||||
// Calculate the offset when drawing a line that is to the side of the actual line.
|
||||
// We do this by creating a vector that points towards the extrude, but rotate
|
||||
// it when we're drawing round end points (a_direction = -1 or 1) since their
|
||||
// extrude vector points in another direction.
|
||||
float u = 0.5 * a_direction;
|
||||
float t = 1.0 - abs(u);
|
||||
vec2 offset = u_offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
|
||||
|
||||
// Remove the texture normal bit of the position before scaling it with the
|
||||
// model/view matrix. Add the extrusion vector *after* the model/view matrix
|
||||
// because we're extruding the line in pixel space, regardless of the current
|
||||
// tile's zoom level.
|
||||
gl_Position = u_matrix * vec4(floor(a_pos * 0.5) + dist / u_ratio, 0.0, 1.0);
|
||||
gl_Position = u_matrix * vec4(floor(a_pos * 0.5) + (offset + dist) / u_ratio, 0.0, 1.0);
|
||||
|
||||
v_tex_a = vec2(a_linesofar * u_patternscale_a.x, normal.y * u_patternscale_a.y + u_tex_y_a);
|
||||
v_tex_b = vec2(a_linesofar * u_patternscale_b.x, normal.y * u_patternscale_b.y + u_tex_y_b);
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
Uniform<GLfloat> u_sdfgamma = {"u_sdfgamma", *this};
|
||||
Uniform<GLfloat> u_mix = {"u_mix", *this};
|
||||
Uniform<GLfloat> u_extra = {"u_extra", *this};
|
||||
Uniform<GLfloat> u_offset = {"u_offset", *this};
|
||||
UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user