diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2015-11-25 12:42:34 +0100 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-12-03 11:41:53 -0800 |
commit | 964a1e7b62c3a7e8fd742e16fe842f8a702437e5 (patch) | |
tree | b94ace89c3688577b196893b7988496f8cbc41a3 | |
parent | c279fb171700c464c1cdac5cd2da39f142274d8d (diff) | |
download | qtlocation-mapboxgl-964a1e7b62c3a7e8fd742e16fe842f8a702437e5.tar.gz |
[core] rudimentary support for offsetting lines
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/mbgl/geometry/line_buffer.cpp | 11 | ||||
-rw-r--r-- | src/mbgl/geometry/line_buffer.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/layer/line_layer.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/layer/line_layer.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/line_bucket.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_line.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/shader/line.vertex.glsl | 12 | ||||
-rw-r--r-- | src/mbgl/shader/line_shader.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/shader/linepattern.vertex.glsl | 14 | ||||
-rw-r--r-- | src/mbgl/shader/linepattern_shader.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/shader/linesdf.vertex.glsl | 14 | ||||
-rw-r--r-- | src/mbgl/shader/linesdf_shader.hpp | 1 |
13 files changed, 61 insertions, 14 deletions
diff --git a/package.json b/package.json index 22d56eeb7c..5a696c251e 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/src/mbgl/geometry/line_buffer.cpp b/src/mbgl/geometry/line_buffer.cpp index 77a134b468..f775a4589f 100644 --- a/src/mbgl/geometry/line_buffer.cpp +++ b/src/mbgl/geometry/line_buffer.cpp @@ -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; } diff --git a/src/mbgl/geometry/line_buffer.hpp b/src/mbgl/geometry/line_buffer.hpp index 0835c0298f..aa2dedbceb 100644 --- a/src/mbgl/geometry/line_buffer.hpp +++ b/src/mbgl/geometry/line_buffer.hpp @@ -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); }; diff --git a/src/mbgl/layer/line_layer.cpp b/src/mbgl/layer/line_layer.cpp index a3073e3bc0..1e25ed30cb 100644 --- a/src/mbgl/layer/line_layer.cpp +++ b/src/mbgl/layer/line_layer.cpp @@ -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); diff --git a/src/mbgl/layer/line_layer.hpp b/src/mbgl/layer/line_layer.hpp index 91206a4ccc..d1c654619a 100644 --- a/src/mbgl/layer/line_layer.hpp +++ b/src/mbgl/layer/line_layer.hpp @@ -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 = { "" }; diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 43bb8132de..368c4ce69d 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -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); diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 30f03ff030..d9d2d9fc5d 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -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; diff --git a/src/mbgl/shader/line.vertex.glsl b/src/mbgl/shader/line.vertex.glsl index 980212384b..1bd7f5ef5f 100644 --- a/src/mbgl/shader/line.vertex.glsl +++ b/src/mbgl/shader/line.vertex.glsl @@ -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; diff --git a/src/mbgl/shader/line_shader.hpp b/src/mbgl/shader/line_shader.hpp index 50c209ef24..14e03c2eaf 100644 --- a/src/mbgl/shader/line_shader.hpp +++ b/src/mbgl/shader/line_shader.hpp @@ -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: diff --git a/src/mbgl/shader/linepattern.vertex.glsl b/src/mbgl/shader/linepattern.vertex.glsl index 541c9fc3a7..5b3c468be0 100644 --- a/src/mbgl/shader/linepattern.vertex.glsl +++ b/src/mbgl/shader/linepattern.vertex.glsl @@ -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 diff --git a/src/mbgl/shader/linepattern_shader.hpp b/src/mbgl/shader/linepattern_shader.hpp index aae550665c..6c83cb0cc3 100644 --- a/src/mbgl/shader/linepattern_shader.hpp +++ b/src/mbgl/shader/linepattern_shader.hpp @@ -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: diff --git a/src/mbgl/shader/linesdf.vertex.glsl b/src/mbgl/shader/linesdf.vertex.glsl index 03851ed533..80516f97c0 100644 --- a/src/mbgl/shader/linesdf.vertex.glsl +++ b/src/mbgl/shader/linesdf.vertex.glsl @@ -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); diff --git a/src/mbgl/shader/linesdf_shader.hpp b/src/mbgl/shader/linesdf_shader.hpp index 1fdae14069..2a8bdc6629 100644 --- a/src/mbgl/shader/linesdf_shader.hpp +++ b/src/mbgl/shader/linesdf_shader.hpp @@ -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: |