summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2016-03-28 16:35:49 -0700
committerAnsis Brammanis <brammanis@gmail.com>2016-03-28 17:44:41 -0700
commit930c3c46c559960f689994e720e3a4efd1ddf608 (patch)
treec4214d763429c4056c66d437ab0c9654a13108f9 /src
parentb352bb81d8259f1e52fe933a20f782d1c4327f1a (diff)
downloadqtlocation-mapboxgl-930c3c46c559960f689994e720e3a4efd1ddf608.tar.gz
[core] reset line distance when it is near max
port https://github.com/mapbox/mapbox-gl-js/commit/77ce4b45b24e8a0ed1bb739da436d19415c7e5e4 fix #4492
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/geometry/line_buffer.cpp2
-rw-r--r--src/mbgl/renderer/line_bucket.cpp28
-rw-r--r--src/mbgl/renderer/line_bucket.hpp2
-rw-r--r--src/mbgl/shader/linepattern.vertex.glsl6
-rw-r--r--src/mbgl/shader/linesdf.vertex.glsl6
5 files changed, 36 insertions, 8 deletions
diff --git a/src/mbgl/geometry/line_buffer.cpp b/src/mbgl/geometry/line_buffer.cpp
index b35d3e8f47..75b9af7e20 100644
--- a/src/mbgl/geometry/line_buffer.cpp
+++ b/src/mbgl/geometry/line_buffer.cpp
@@ -22,7 +22,7 @@ GLsizei LineVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey,
// 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;
+ extrude[7] = ((linesofar >> 6) & 0xFF) - 128;
return idx;
}
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index 06daf3bbc3..1e8ba0ecb5 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -41,6 +41,17 @@ void LineBucket::addGeometry(const GeometryCollection& geometryCollection) {
const float COS_HALF_SHARP_CORNER = std::cos(75.0 / 2.0 * (M_PI / 180.0));
const float SHARP_CORNER_OFFSET = 15.0f;
+// The number of bits that is used to store the line distance in the buffer.
+const int LINE_DISTANCE_BUFFER_BITS = 14;
+
+// We don't have enough bits for the line distance as we'd like to have, so
+// use this value to scale the line distance (in tile units) down to a smaller
+// value. This lets us store longer distances while sacrificing precision.
+const float LINE_DISTANCE_SCALE = 1.0 / 2.0;
+
+// The maximum line distance, in tile units, that fits in the buffer.
+const float MAX_LINE_DISTANCE = std::pow(2, LINE_DISTANCE_BUFFER_BITS) / LINE_DISTANCE_SCALE;
+
void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
const GLsizei len = [&vertices] {
GLsizei l = static_cast<GLsizei>(vertices.size());
@@ -363,7 +374,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
void LineBucket::addCurrentVertex(const GeometryCoordinate& currentVertex,
float flip,
- double distance,
+ double &distance,
const vec2<double>& normal,
float endLeft,
float endRight,
@@ -375,7 +386,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& 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, endLeft, distance)
+ e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 0, endLeft, distance * LINE_DISTANCE_SCALE)
- startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
@@ -386,13 +397,22 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& 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, -endRight, distance)
+ e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 1, -endRight, distance * LINE_DISTANCE_SCALE)
- startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
e1 = e2;
e2 = e3;
+
+ // There is a maximum "distance along the line" that we can store in the buffers.
+ // When we get close to the distance, reset it to zero and add the vertex again with
+ // a distance of zero. The max distance is determined by the number of bits we allocate
+ // to `linesofar`.
+ if (distance > MAX_LINE_DISTANCE / 2.0f) {
+ distance = 0;
+ addCurrentVertex(currentVertex, flip, distance, normal, endLeft, endRight, round, startVertex, triangleStore);
+ }
}
void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
@@ -405,7 +425,7 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& 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, 0, distance)
+ e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, flippedExtrude.x, flippedExtrude.y, 0, ty, 0, distance * LINE_DISTANCE_SCALE)
- startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index 5b6509a5ee..1586bef0a7 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -43,7 +43,7 @@ private:
TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {}
uint16_t a, b, c;
};
- void addCurrentVertex(const GeometryCoordinate& currentVertex, float flip, double distance,
+ void addCurrentVertex(const GeometryCoordinate& currentVertex, float flip, double& distance,
const vec2<double>& normal, float endLeft, float endRight, bool round,
GLint startVertex, std::vector<LineBucket::TriangleElement>& triangleStore);
void addPieSliceVertex(const GeometryCoordinate& currentVertex, float flip, double distance,
diff --git a/src/mbgl/shader/linepattern.vertex.glsl b/src/mbgl/shader/linepattern.vertex.glsl
index 5b3c468be0..6fa499106c 100644
--- a/src/mbgl/shader/linepattern.vertex.glsl
+++ b/src/mbgl/shader/linepattern.vertex.glsl
@@ -6,6 +6,10 @@
// #define scale 63.0
#define scale 0.015873016
+// We scale the distance before adding it to the buffers so that we can store
+// long distances for long segments. Use this value to unscale the distance.
+#define LINE_DISTANCE_SCALE 2.0
+
attribute vec2 a_pos;
attribute vec4 a_data;
@@ -30,7 +34,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);
- float a_linesofar = abs(floor(a_data.z / 2.0)) + a_data.w * 64.0;
+ float a_linesofar = (abs(floor(a_data.z / 2.0)) + (a_data.w + 128.0) * 64.0) * LINE_DISTANCE_SCALE;
// We store the texture normals in the most insignificant bit
// transform y so that 0 => -1 and 1 => 1
diff --git a/src/mbgl/shader/linesdf.vertex.glsl b/src/mbgl/shader/linesdf.vertex.glsl
index 80516f97c0..f24d8399b8 100644
--- a/src/mbgl/shader/linesdf.vertex.glsl
+++ b/src/mbgl/shader/linesdf.vertex.glsl
@@ -6,6 +6,10 @@
// #define scale 63.0
#define scale 0.015873016
+// We scale the distance before adding it to the buffers so that we can store
+// long distances for long segments. Use this value to unscale the distance.
+#define LINE_DISTANCE_SCALE 2.0
+
attribute vec2 a_pos;
attribute vec4 a_data;
@@ -34,7 +38,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);
- float a_linesofar = abs(floor(a_data.z / 2.0)) + a_data.w * 64.0;
+ float a_linesofar = (abs(floor(a_data.z / 2.0)) + (a_data.w + 128.0) * 64.0) * LINE_DISTANCE_SCALE;
// We store the texture normals in the most insignificant bit
// transform y so that 0 => -1 and 1 => 1