diff options
author | Chris Loer <chris.loer@gmail.com> | 2017-10-24 16:08:56 -0700 |
---|---|---|
committer | Chris Loer <chris.loer@mapbox.com> | 2017-10-25 10:23:13 -0700 |
commit | 35e77b767a3f4d69071a921adb2a177b7571cc35 (patch) | |
tree | dd7107a1e744aec6e69305bbdfa485e28d08bd08 | |
parent | 494d5500ca48776903248b1397fe352b4b1f6954 (diff) | |
download | qtlocation-mapboxgl-35e77b767a3f4d69071a921adb2a177b7571cc35.tar.gz |
Starting implementation of debug collision boxes.
- Dynamic buffers not hooked up yet
- Circles not hooked up yet
m--------- | mapbox-gl-js | 0 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/programs/attributes.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/programs/collision_box_program.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/programs/collision_box_program.hpp | 31 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/shaders/collision_box.cpp | 67 | ||||
-rw-r--r-- | src/mbgl/shaders/collision_circle.cpp | 83 | ||||
-rw-r--r-- | src/mbgl/shaders/collision_circle.hpp | 16 |
13 files changed, 159 insertions, 87 deletions
diff --git a/mapbox-gl-js b/mapbox-gl-js -Subproject cecd21c9dcf87e4b1a5282b3a071f409c164398 +Subproject 510988b20961998a7731fa9b19154394a623b2a diff --git a/package.json b/package.json index 5c91322978..5dd4624857 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "license": "BSD-2-Clause", "dependencies": { "nan": "^2.4.0", - "node-pre-gyp": "^0.6.37", + "node-pre-gyp": "^0.6.38", "npm-run-all": "^4.0.2" }, "devDependencies": { diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 1032088e70..00202ed992 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -591,13 +591,6 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket& Point<float> tr{box.x2, box.y1 * yStretch}; Point<float> bl{box.x1, box.y2 * yStretch}; Point<float> br{box.x2, box.y2 * yStretch}; - tl = util::matrixMultiply(collisionTile.reverseRotationMatrix, tl); - tr = util::matrixMultiply(collisionTile.reverseRotationMatrix, tr); - bl = util::matrixMultiply(collisionTile.reverseRotationMatrix, bl); - br = util::matrixMultiply(collisionTile.reverseRotationMatrix, br); - - const float maxZoom = util::clamp(zoom + util::log2(box.maxScale), util::MIN_ZOOM_F, util::MAX_ZOOM_F); - const float placementZoom = util::clamp(zoom + util::log2(box.placementScale), util::MIN_ZOOM_F, util::MAX_ZOOM_F); static constexpr std::size_t vertexLength = 4; static constexpr std::size_t indexLength = 8; @@ -609,10 +602,16 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket& auto& segment = collisionBox.segments.back(); uint16_t index = segment.vertexLength; - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, tl, maxZoom, placementZoom)); - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, tr, maxZoom, placementZoom)); - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, br, maxZoom, placementZoom)); - collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, bl, maxZoom, placementZoom)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, tl)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, tr)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, br)); + collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, bl)); + + auto opacityVertex = CollisionBoxOpacityAttributes::vertex(true, true); // TODO + collisionBox.opacityVertices.emplace_back(opacityVertex); + collisionBox.opacityVertices.emplace_back(opacityVertex); + collisionBox.opacityVertices.emplace_back(opacityVertex); + collisionBox.opacityVertices.emplace_back(opacityVertex); collisionBox.lines.emplace_back(index + 0, index + 1); collisionBox.lines.emplace_back(index + 1, index + 2); diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index 459de23f41..437ae2195c 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -31,6 +31,7 @@ MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 3, a_normal); MBGL_DEFINE_ATTRIBUTE(uint16_t, 1, a_edgedistance); MBGL_DEFINE_ATTRIBUTE(uint8_t, 1, a_fade_opacity); +MBGL_DEFINE_ATTRIBUTE(uint8_t, 2, a_placed); template <typename T, std::size_t N> struct a_data { diff --git a/src/mbgl/programs/collision_box_program.cpp b/src/mbgl/programs/collision_box_program.cpp index 57107db75d..babd4b2596 100644 --- a/src/mbgl/programs/collision_box_program.cpp +++ b/src/mbgl/programs/collision_box_program.cpp @@ -2,6 +2,6 @@ namespace mbgl { -static_assert(sizeof(CollisionBoxProgram::LayoutVertex) == 14, "expected CollisionBoxVertex size"); +static_assert(sizeof(CollisionBoxProgram::LayoutVertex) == 12, "expected CollisionBoxVertex size"); } // namespace mbgl diff --git a/src/mbgl/programs/collision_box_program.hpp b/src/mbgl/programs/collision_box_program.hpp index ba99e0c087..d4b5ea0e5a 100644 --- a/src/mbgl/programs/collision_box_program.hpp +++ b/src/mbgl/programs/collision_box_program.hpp @@ -11,16 +11,18 @@ namespace mbgl { -namespace uniforms { -MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_maxzoom); -} // namespace uniforms - using CollisionBoxAttributes = gl::Attributes< attributes::a_pos, attributes::a_anchor_pos, - attributes::a_extrude, - attributes::a_data<uint8_t, 2>>; + attributes::a_extrude>; + +struct CollisionBoxOpacityAttributes : gl::Attributes<attributes::a_placed> { + static Vertex vertex(bool placed, bool notUsed) { + return Vertex { + {{ static_cast<uint8_t>(placed), static_cast<uint8_t>(notUsed) }} + }; + } +}; class CollisionBoxProgram : public Program< shaders::collision_box, @@ -28,19 +30,14 @@ class CollisionBoxProgram : public Program< CollisionBoxAttributes, gl::Uniforms< uniforms::u_matrix, - uniforms::u_scale, - uniforms::u_zoom, - uniforms::u_maxzoom, - uniforms::u_collision_y_stretch, - uniforms::u_camera_to_center_distance, - uniforms::u_pitch, - uniforms::u_fadetexture>, + uniforms::u_extrude_scale, + uniforms::u_camera_to_center_distance>, style::Properties<>> { public: using Program::Program; - static LayoutVertex vertex(Point<float> a, Point<float> anchor, Point<float> o, float maxzoom, float placementZoom) { + static LayoutVertex vertex(Point<float> a, Point<float> anchor, Point<float> o) { return LayoutVertex { {{ static_cast<int16_t>(a.x), @@ -53,10 +50,6 @@ public: {{ static_cast<int16_t>(::round(o.x)), static_cast<int16_t>(::round(o.y)) - }}, - {{ - static_cast<uint8_t>(maxzoom * 10), - static_cast<uint8_t>(placementZoom * 10) }} }; } diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index d01f94e271..282663e755 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -53,6 +53,7 @@ void SymbolBucket::upload(gl::Context& context) { if (!collisionBox.vertices.empty()) { collisionBox.vertexBuffer = context.createVertexBuffer(std::move(collisionBox.vertices)); + collisionBox.opacityVertexBuffer = context.createVertexBuffer(std::move(collisionBox.opacityVertices), gl::BufferUsage::StreamDraw); collisionBox.indexBuffer = context.createIndexBuffer(std::move(collisionBox.lines)); } diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index fd7d03a806..005a5faacf 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -104,11 +104,13 @@ public: struct CollisionBoxBuffer { gl::VertexVector<CollisionBoxVertex> vertices; + gl::VertexVector<CollisionBoxOpacityAttributes::Vertex> opacityVertices; gl::IndexVector<gl::Lines> lines; SegmentVector<CollisionBoxAttributes> segments; optional<gl::VertexBuffer<CollisionBoxVertex>> vertexBuffer; optional<gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>> dynamicVertexBuffer; + optional<gl::VertexBuffer<CollisionBoxOpacityAttributes::Vertex>> opacityVertexBuffer; optional<gl::IndexBuffer<gl::Lines>> indexBuffer; } collisionBox; }; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 95e0ad7c5e..4435aaa90c 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -225,6 +225,15 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { static const style::Properties<>::PossiblyEvaluated properties {}; static const CollisionBoxProgram::PaintPropertyBinders paintAttributeData(properties, 0); + auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom()); + auto scale = std::pow(2.0f, float(parameters.state.getZoom() - tile.tile.id.overscaledZ)); + std::array<float,2> extrudeScale = + {{ + parameters.pixelsToGLUnits[0] / (pixelRatio * scale), + parameters.pixelsToGLUnits[1] / (pixelRatio * scale) + + }}; + parameters.programs.collisionBox.draw( parameters.context, gl::Lines { 1.0f }, @@ -233,13 +242,8 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { parameters.colorModeForRenderPass(), CollisionBoxProgram::UniformValues { uniforms::u_matrix::Value{ tile.matrix }, - uniforms::u_scale::Value{ std::pow(2.0f, float(parameters.state.getZoom() - tile.tile.id.overscaledZ)) }, - uniforms::u_zoom::Value{ float(parameters.state.getZoom() * 10) }, - uniforms::u_maxzoom::Value{ float((tile.id.canonical.z + 1) * 10) }, - uniforms::u_collision_y_stretch::Value{ tile.tile.yStretch() }, - uniforms::u_camera_to_center_distance::Value{ parameters.state.getCameraToCenterDistance() }, - uniforms::u_pitch::Value{ parameters.state.getPitch() }, - uniforms::u_fadetexture::Value{ 1 } + uniforms::u_extrude_scale::Value{ extrudeScale }, + uniforms::u_camera_to_center_distance::Value{ parameters.state.getCameraToCenterDistance() } }, *bucket.collisionBox.vertexBuffer, *bucket.collisionBox.indexBuffer, diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 3baa386313..dd290ca84c 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -366,7 +366,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { Placement placement(parameters.state); for (auto it = order.rbegin(); it != order.rend(); ++it) { if (it->layer.is<RenderSymbolLayer>()) { - bool showCollisionBoxes = false; // TODO + bool showCollisionBoxes = true; // TODO placement.placeLayer(*it->layer.as<RenderSymbolLayer>(), showCollisionBoxes); } } diff --git a/src/mbgl/shaders/collision_box.cpp b/src/mbgl/shaders/collision_box.cpp index 07fa94e338..9d11640bf4 100644 --- a/src/mbgl/shaders/collision_box.cpp +++ b/src/mbgl/shaders/collision_box.cpp @@ -10,77 +10,50 @@ const char* collision_box::vertexSource = R"MBGL_SHADER( attribute vec2 a_pos; attribute vec2 a_anchor_pos; attribute vec2 a_extrude; -attribute vec2 a_data; +attribute vec2 a_placed; uniform mat4 u_matrix; -uniform float u_scale; -uniform float u_pitch; -uniform float u_collision_y_stretch; +uniform vec2 u_extrude_scale; uniform float u_camera_to_center_distance; -varying float v_max_zoom; -varying float v_placement_zoom; -varying float v_perspective_zoom_adjust; -varying vec2 v_fade_tex; +varying float v_placed; +varying float v_notUsed; void main() { vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1); highp float camera_to_anchor_distance = projectedPoint.w; - highp float collision_perspective_ratio = 1.0 + 0.5 * ((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0); + highp float collision_perspective_ratio = 0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance); - highp float incidence_stretch = camera_to_anchor_distance / (u_camera_to_center_distance * cos(u_pitch)); - highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch); + gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0); + gl_Position.xy += a_extrude * u_extrude_scale * gl_Position.w * collision_perspective_ratio; - gl_Position = u_matrix * vec4(a_pos + a_extrude * collision_perspective_ratio * collision_adjustment / u_scale, 0.0, 1.0); - - v_max_zoom = a_data.x; - v_placement_zoom = a_data.y; - - v_perspective_zoom_adjust = floor(log2(collision_perspective_ratio * collision_adjustment) * 10.0); - v_fade_tex = vec2((v_placement_zoom + v_perspective_zoom_adjust) / 255.0, 0.0); + v_placed = a_placed.x; + v_notUsed = a_placed.y; } )MBGL_SHADER"; const char* collision_box::fragmentSource = R"MBGL_SHADER( -uniform float u_zoom; -// u_maxzoom is derived from the maximum scale considered by the CollisionTile -// Labels with placement zoom greater than this value will not be placed, -// regardless of perspective effects. -uniform float u_maxzoom; -uniform sampler2D u_fadetexture; - -// v_max_zoom is a collision-box-specific value that controls when line-following -// collision boxes are used. -varying float v_max_zoom; -varying float v_placement_zoom; -varying float v_perspective_zoom_adjust; -varying vec2 v_fade_tex; + +varying float v_placed; +varying float v_notUsed; void main() { float alpha = 0.5; - // Green = no collisions, label is showing - gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0) * alpha; + // Red = collision, hide label + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * alpha; - // Red = collision, label hidden - if (texture2D(u_fadetexture, v_fade_tex).a < 1.0) { - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * alpha; + // Blue = no collision, label is showing + if (v_placed > 0.5) { + gl_FragColor = vec4(0.0, 0.0, 1.0, 0.5) * alpha; } - // Faded black = this collision box is not used at this zoom (for curved labels) - if (u_zoom >= v_max_zoom + v_perspective_zoom_adjust) { - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) * alpha * 0.25; - } - - // Faded blue = the placement scale for this label is beyond the CollisionTile - // max scale, so it's impossible for this label to show without collision detection - // being run again (the label's glyphs haven't even been added to the symbol bucket) - if (v_placement_zoom >= u_maxzoom) { - gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0) * alpha * 0.2; + if (v_notUsed > 0.5) { + // This box not used, fade it out + gl_FragColor *= .1; } } - )MBGL_SHADER"; } // namespace shaders diff --git a/src/mbgl/shaders/collision_circle.cpp b/src/mbgl/shaders/collision_circle.cpp new file mode 100644 index 0000000000..1e85d99a33 --- /dev/null +++ b/src/mbgl/shaders/collision_circle.cpp @@ -0,0 +1,83 @@ +// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. + +#include <mbgl/shaders/collision_circle.hpp> + +namespace mbgl { +namespace shaders { + +const char* collision_circle::name = "collision_circle"; +const char* collision_circle::vertexSource = R"MBGL_SHADER( +attribute vec2 a_pos; +attribute vec2 a_anchor_pos; +attribute vec2 a_extrude; +attribute vec2 a_placed; + +uniform mat4 u_matrix; +uniform vec2 u_extrude_scale; +uniform float u_camera_to_center_distance; + +varying float v_placed; +varying float v_notUsed; +varying float v_radius; + +varying vec2 v_extrude; +varying vec2 v_extrude_scale; + +void main() { + vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1); + highp float camera_to_anchor_distance = projectedPoint.w; + highp float collision_perspective_ratio = 0.5 + 0.5 * (camera_to_anchor_distance / u_camera_to_center_distance); + + gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0); + + highp float padding_factor = 1.2; // Pad the vertices slightly to make room for anti-alias blur + gl_Position.xy += a_extrude * u_extrude_scale * padding_factor * gl_Position.w / collision_perspective_ratio; + + v_placed = a_placed.x; + v_notUsed = a_placed.y; + v_radius = abs(a_extrude.y); // We don't pitch the circles, so both units of the extrusion vector are equal in magnitude to the radius + + v_extrude = a_extrude * padding_factor; + v_extrude_scale = u_extrude_scale * u_camera_to_center_distance / collision_perspective_ratio; +} + +)MBGL_SHADER"; +const char* collision_circle::fragmentSource = R"MBGL_SHADER( + +varying float v_placed; +varying float v_notUsed; +varying float v_radius; +varying vec2 v_extrude; +varying vec2 v_extrude_scale; + +void main() { + float alpha = 0.5; + + // Red = collision, hide label + vec4 color = vec4(1.0, 0.0, 0.0, 1.0) * alpha; + + // Blue = no collision, label is showing + if (v_placed > 0.5) { + color = vec4(0.0, 0.0, 1.0, 0.5) * alpha; + } + + if (v_notUsed > 0.5) { + // This box not used, fade it out + color *= .2; + } + + float extrude_scale_length = length(v_extrude_scale); + float extrude_length = length(v_extrude) * extrude_scale_length; + float stroke_width = 3.0; + float radius = v_radius * extrude_scale_length; + + float distance_to_edge = abs(extrude_length - radius); + float opacity_t = smoothstep(-stroke_width, 0.0, -distance_to_edge); + + gl_FragColor = opacity_t * color; +} + +)MBGL_SHADER"; + +} // namespace shaders +} // namespace mbgl diff --git a/src/mbgl/shaders/collision_circle.hpp b/src/mbgl/shaders/collision_circle.hpp new file mode 100644 index 0000000000..12b1bcd445 --- /dev/null +++ b/src/mbgl/shaders/collision_circle.hpp @@ -0,0 +1,16 @@ +// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. + +#pragma once + +namespace mbgl { +namespace shaders { + +class collision_circle { +public: + static const char* name; + static const char* vertexSource; + static const char* fragmentSource; +}; + +} // namespace shaders +} // namespace mbgl |