port collision box debug rendering
This commit is contained in:
27
src/mbgl/geometry/collision_box_buffer.cpp
Normal file
27
src/mbgl/geometry/collision_box_buffer.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <mbgl/geometry/collision_box_buffer.hpp>
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
size_t CollisionBoxVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, float maxzoom, float placementZoom) {
|
||||
const size_t idx = index();
|
||||
void *data = addElement();
|
||||
|
||||
int16_t *shorts = static_cast<int16_t *>(data);
|
||||
shorts[0] /* pos */ = x;
|
||||
shorts[1] /* pos */ = y;
|
||||
shorts[2] /* offset */ = std::round(ox); // use 1/64 pixels for placement
|
||||
shorts[3] /* offset */ = std::round(oy);
|
||||
|
||||
uint8_t *ubytes = static_cast<uint8_t *>(data);
|
||||
// a_data1
|
||||
ubytes[8] = maxzoom * 10;
|
||||
ubytes[9] = placementZoom * 10;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
}
|
||||
23
src/mbgl/geometry/collision_box_buffer.hpp
Normal file
23
src/mbgl/geometry/collision_box_buffer.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef MBGL_GEOMETRY_COLLISIONBOX_BUFFER
|
||||
#define MBGL_GEOMETRY_COLLISIONBOX_BUFFER
|
||||
|
||||
#include <mbgl/geometry/buffer.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class CollisionBoxVertexBuffer : public Buffer <
|
||||
12,
|
||||
GL_ARRAY_BUFFER,
|
||||
32768
|
||||
> {
|
||||
public:
|
||||
typedef int16_t vertex_type;
|
||||
|
||||
size_t add(int16_t x, int16_t y, float ex, float ey, float maxzoom, float placementZoom);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <mbgl/geometry/icon_buffer.hpp>
|
||||
#include <mbgl/geometry/line_buffer.hpp>
|
||||
#include <mbgl/geometry/text_buffer.hpp>
|
||||
#include <mbgl/geometry/collision_box_buffer.hpp>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
@@ -50,6 +51,7 @@ protected:
|
||||
LineVertexBuffer lineVertexBuffer;
|
||||
IconVertexBuffer iconVertexBuffer;
|
||||
TextVertexBuffer textVertexBuffer;
|
||||
CollisionBoxVertexBuffer collisionBoxVertexBuffer;
|
||||
|
||||
TriangleElementsBuffer triangleElementsBuffer;
|
||||
LineElementsBuffer lineElementsBuffer;
|
||||
|
||||
@@ -106,6 +106,7 @@ void Painter::setupShaders() {
|
||||
if (!sdfIconShader) sdfIconShader = util::make_unique<SDFIconShader>();
|
||||
if (!dotShader) dotShader = util::make_unique<DotShader>();
|
||||
if (!gaussianShader) gaussianShader = util::make_unique<GaussianShader>();
|
||||
if (!collisionBoxShader) collisionBoxShader = util::make_unique<CollisionBoxShader>();
|
||||
}
|
||||
|
||||
void Painter::deleteShaders() {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <mbgl/shader/sdf_shader.hpp>
|
||||
#include <mbgl/shader/dot_shader.hpp>
|
||||
#include <mbgl/shader/gaussian_shader.hpp>
|
||||
#include <mbgl/shader/box_shader.hpp>
|
||||
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
@@ -212,6 +213,7 @@ public:
|
||||
std::unique_ptr<SDFIconShader> sdfIconShader;
|
||||
std::unique_ptr<DotShader> dotShader;
|
||||
std::unique_ptr<GaussianShader> gaussianShader;
|
||||
std::unique_ptr<CollisionBoxShader> collisionBoxShader;
|
||||
|
||||
StaticVertexBuffer backgroundBuffer = {
|
||||
{ -1, -1 }, { 1, -1 },
|
||||
|
||||
@@ -189,5 +189,20 @@ void Painter::renderSymbol(SymbolBucket &bucket, const StyleLayer &layer_desc, c
|
||||
&SymbolBucket::drawGlyphs);
|
||||
}
|
||||
|
||||
if (bucket.hasCollisionBoxData()) {
|
||||
MBGL_CHECK_ERROR(glEnable(GL_STENCIL_TEST));
|
||||
|
||||
useProgram(collisionBoxShader->program);
|
||||
collisionBoxShader->u_matrix = matrix;
|
||||
collisionBoxShader->u_scale = std::pow(2, state.getNormalizedZoom() - id.z);
|
||||
collisionBoxShader->u_zoom = state.getNormalizedZoom() * 10;
|
||||
collisionBoxShader->u_maxzoom = (id.z + 1) * 10;
|
||||
lineWidth(3.0f);
|
||||
|
||||
depthRange(strata, 1.0f);
|
||||
bucket.drawCollisionBoxes(*collisionBoxShader);
|
||||
|
||||
}
|
||||
|
||||
MBGL_CHECK_ERROR(glEnable(GL_STENCIL_TEST));
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ bool SymbolBucket::hasTextData() const { return !text.groups.empty(); }
|
||||
|
||||
bool SymbolBucket::hasIconData() const { return !icon.groups.empty(); }
|
||||
|
||||
bool SymbolBucket::hasCollisionBoxData() const { return !collisionBox.groups.empty(); }
|
||||
|
||||
std::vector<SymbolFeature> SymbolBucket::processFeatures(const GeometryTileLayer& layer,
|
||||
const FilterExpression& filter,
|
||||
GlyphStore &glyphStore,
|
||||
@@ -317,6 +319,8 @@ void SymbolBucket::placeFeatures() {
|
||||
addSymbols<IconBuffer, IconElementGroup>(icon, symbolInstance.iconQuads, iconScale);
|
||||
}
|
||||
}
|
||||
|
||||
addToDebugBuffers();
|
||||
}
|
||||
|
||||
template <typename Buffer, typename GroupType>
|
||||
@@ -379,6 +383,57 @@ void SymbolBucket::addSymbols(Buffer &buffer, const PlacedGlyphs &symbols, float
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolBucket::addToDebugBuffers() {
|
||||
|
||||
const float yStretch = 1.0f;
|
||||
const float angle = 0.0f;
|
||||
const float zoom = collision.zoom;
|
||||
float angle_sin = std::sin(-angle);
|
||||
float angle_cos = std::cos(-angle);
|
||||
std::array<float, 4> matrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}};
|
||||
|
||||
for (const SymbolInstance &symbolInstance : symbolInstances) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& feature = i == 0 ?
|
||||
symbolInstance.textCollisionFeature :
|
||||
symbolInstance.iconCollisionFeature;
|
||||
|
||||
for (const CollisionBox &box : feature.boxes) {
|
||||
auto& anchor = box.anchor;
|
||||
|
||||
vec2<float> tl{box.x1, box.y1 * yStretch};
|
||||
vec2<float> tr{box.x2, box.y1 * yStretch};
|
||||
vec2<float> bl{box.x1, box.y2 * yStretch};
|
||||
vec2<float> br{box.x2, box.y2 * yStretch};
|
||||
tl = tl.matMul(matrix);
|
||||
tr = tr.matMul(matrix);
|
||||
bl = bl.matMul(matrix);
|
||||
br = br.matMul(matrix);
|
||||
|
||||
const float maxZoom = util::max(0.0f, util::min(25.0f, static_cast<float>(zoom + log(box.maxScale) / log(2))));
|
||||
const float placementZoom= util::max(0.0f, util::min(25.0f, static_cast<float>(zoom + log(box.placementScale) / log(2))));
|
||||
|
||||
if (!collisionBox.groups.size()) {
|
||||
// Move to a new group because the old one can't hold the geometry.
|
||||
collisionBox.groups.emplace_back(util::make_unique<CollisionBoxElementGroup>());
|
||||
}
|
||||
|
||||
collisionBox.vertices.add(anchor.x, anchor.y, tl.x, tl.y, maxZoom, placementZoom);
|
||||
collisionBox.vertices.add(anchor.x, anchor.y, tr.x, tr.y, maxZoom, placementZoom);
|
||||
collisionBox.vertices.add(anchor.x, anchor.y, tr.x, tr.y, maxZoom, placementZoom);
|
||||
collisionBox.vertices.add(anchor.x, anchor.y, br.x, br.y, maxZoom, placementZoom);
|
||||
collisionBox.vertices.add(anchor.x, anchor.y, br.x, br.y, maxZoom, placementZoom);
|
||||
collisionBox.vertices.add(anchor.x, anchor.y, bl.x, bl.y, maxZoom, placementZoom);
|
||||
collisionBox.vertices.add(anchor.x, anchor.y, bl.x, bl.y, maxZoom, placementZoom);
|
||||
collisionBox.vertices.add(anchor.x, anchor.y, tl.x, tl.y, maxZoom, placementZoom);
|
||||
|
||||
auto &group= *collisionBox.groups.back();
|
||||
group.vertex_length += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolBucket::drawGlyphs(SDFShader &shader) {
|
||||
char *vertex_index = BUFFER_OFFSET(0);
|
||||
char *elements_index = BUFFER_OFFSET(0);
|
||||
@@ -414,4 +469,12 @@ void SymbolBucket::drawIcons(IconShader &shader) {
|
||||
elements_index += group->elements_length * icon.triangles.itemSize;
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolBucket::drawCollisionBoxes(CollisionBoxShader &shader) {
|
||||
char *vertex_index = BUFFER_OFFSET(0);
|
||||
for (auto &group : collisionBox.groups) {
|
||||
group->array[0].bind(shader, collisionBox.vertices, vertex_index);
|
||||
MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, group->vertex_length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <mbgl/geometry/elements_buffer.hpp>
|
||||
#include <mbgl/geometry/text_buffer.hpp>
|
||||
#include <mbgl/geometry/icon_buffer.hpp>
|
||||
#include <mbgl/geometry/collision_box_buffer.hpp>
|
||||
#include <mbgl/text/types.hpp>
|
||||
#include <mbgl/text/glyph.hpp>
|
||||
#include <mbgl/text/collision_feature.hpp>
|
||||
@@ -24,6 +25,7 @@ class Style;
|
||||
class StyleLayoutSymbol;
|
||||
class SDFShader;
|
||||
class IconShader;
|
||||
class CollisionBoxShader;
|
||||
class DotShader;
|
||||
class Collision;
|
||||
class SpriteAtlas;
|
||||
@@ -60,6 +62,7 @@ class SymbolInstance {
|
||||
class SymbolBucket : public Bucket {
|
||||
typedef ElementGroup<1> TextElementGroup;
|
||||
typedef ElementGroup<2> IconElementGroup;
|
||||
typedef ElementGroup<1> CollisionBoxElementGroup;
|
||||
|
||||
public:
|
||||
SymbolBucket(std::unique_ptr<const StyleLayoutSymbol> styleLayout, Collision &collision);
|
||||
@@ -70,6 +73,7 @@ public:
|
||||
bool hasData() const override;
|
||||
bool hasTextData() const;
|
||||
bool hasIconData() const;
|
||||
bool hasCollisionBoxData() const;
|
||||
|
||||
void addFeatures(const GeometryTileLayer&,
|
||||
const FilterExpression&,
|
||||
@@ -82,6 +86,7 @@ public:
|
||||
void drawGlyphs(SDFShader& shader);
|
||||
void drawIcons(SDFShader& shader);
|
||||
void drawIcons(IconShader& shader);
|
||||
void drawCollisionBoxes(CollisionBoxShader& shader);
|
||||
|
||||
private:
|
||||
std::vector<SymbolFeature> processFeatures(const GeometryTileLayer&,
|
||||
@@ -93,6 +98,7 @@ private:
|
||||
const GlyphPositions &face);
|
||||
|
||||
void placeFeatures();
|
||||
void addToDebugBuffers();
|
||||
|
||||
// Adds placed items to the buffer.
|
||||
template <typename Buffer, typename GroupType>
|
||||
@@ -118,6 +124,11 @@ private:
|
||||
std::vector<std::unique_ptr<IconElementGroup>> groups;
|
||||
} icon;
|
||||
|
||||
struct CollisionBoxBuffer {
|
||||
CollisionBoxVertexBuffer vertices;
|
||||
std::vector<std::unique_ptr<CollisionBoxElementGroup>> groups;
|
||||
} collisionBox;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
24
src/mbgl/shader/box.fragment.glsl
Normal file
24
src/mbgl/shader/box.fragment.glsl
Normal file
@@ -0,0 +1,24 @@
|
||||
uniform float u_zoom;
|
||||
uniform float u_maxzoom;
|
||||
|
||||
varying float v_max_zoom;
|
||||
varying float v_placement_zoom;
|
||||
|
||||
void main() {
|
||||
|
||||
float alpha = 0.5;
|
||||
|
||||
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0) * alpha;
|
||||
|
||||
if (v_placement_zoom > u_zoom) {
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * alpha;
|
||||
}
|
||||
|
||||
if (u_zoom >= v_max_zoom) {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) * alpha * 0.25;
|
||||
}
|
||||
|
||||
if (v_placement_zoom >= u_maxzoom) {
|
||||
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0) * alpha * 0.2;
|
||||
}
|
||||
}
|
||||
16
src/mbgl/shader/box.vertex.glsl
Normal file
16
src/mbgl/shader/box.vertex.glsl
Normal file
@@ -0,0 +1,16 @@
|
||||
attribute vec2 a_pos;
|
||||
attribute vec2 a_extrude;
|
||||
attribute vec2 a_data;
|
||||
|
||||
uniform mat4 u_matrix;
|
||||
uniform float u_scale;
|
||||
|
||||
varying float v_max_zoom;
|
||||
varying float v_placement_zoom;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_matrix * vec4(a_pos + a_extrude / u_scale, 0.0, 1.0);
|
||||
|
||||
v_max_zoom = a_data.x;
|
||||
v_placement_zoom = a_data.y;
|
||||
}
|
||||
32
src/mbgl/shader/box_shader.cpp
Normal file
32
src/mbgl/shader/box_shader.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <mbgl/shader/box_shader.hpp>
|
||||
#include <mbgl/shader/shaders.hpp>
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
CollisionBoxShader::CollisionBoxShader()
|
||||
: Shader(
|
||||
"collisionbox",
|
||||
shaders[BOX_SHADER].vertex,
|
||||
shaders[BOX_SHADER].fragment
|
||||
) {
|
||||
a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_pos"));
|
||||
a_extrude = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_extrude"));
|
||||
a_data = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_data"));
|
||||
}
|
||||
|
||||
void CollisionBoxShader::bind(char *offset) {
|
||||
const int stride = 12;
|
||||
|
||||
MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
|
||||
MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset + 0));
|
||||
|
||||
MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_extrude));
|
||||
MBGL_CHECK_ERROR(glVertexAttribPointer(a_extrude, 2, GL_SHORT, false, stride, offset + 4));
|
||||
|
||||
MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
|
||||
MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 2, GL_UNSIGNED_BYTE, false, stride, offset + 8));
|
||||
|
||||
}
|
||||
28
src/mbgl/shader/box_shader.hpp
Normal file
28
src/mbgl/shader/box_shader.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef MBGL_SHADER_SHADER_BOX
|
||||
#define MBGL_SHADER_SHADER_BOX
|
||||
|
||||
#include <mbgl/shader/shader.hpp>
|
||||
#include <mbgl/shader/uniform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class CollisionBoxShader : public Shader {
|
||||
public:
|
||||
CollisionBoxShader();
|
||||
|
||||
void bind(char *offset);
|
||||
|
||||
UniformMatrix<4> u_matrix = {"u_matrix", *this};
|
||||
Uniform<float> u_scale = {"u_scale", *this};
|
||||
Uniform<float> u_zoom = {"u_zoom", *this};
|
||||
Uniform<float> u_maxzoom = {"u_maxzoom", *this};
|
||||
|
||||
protected:
|
||||
int32_t a_pos = -1;
|
||||
int32_t a_extrude = -1;
|
||||
int32_t a_data = -1;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -17,7 +17,7 @@ CollisionFeature::CollisionFeature(const std::vector<Coordinate> &line, const An
|
||||
|
||||
bboxifyLabel(line, anchor, length, height);
|
||||
} else {
|
||||
boxes.emplace_back(anchor, x1, y2, x2, y2, std::numeric_limits<float>::infinity());
|
||||
boxes.emplace_back(anchor, x1, y1, x2, y2, std::numeric_limits<float>::infinity());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user