Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Add circle render type #2053

Merged
merged 1 commit into from
Aug 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions include/mbgl/style/style_properties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ struct LineProperties {
}
};

struct CircleProperties {
inline CircleProperties() {}
float radius = 5.0f;
Color color = {{ 0, 0, 0, 1 }};
float opacity = 1.0f;
std::array<float, 2> translate = {{ 0, 0 }};
TranslateAnchorType translateAnchor = TranslateAnchorType::Map;
float blur = 0;

inline bool isVisible() const {
return radius > 0 && color[3] > 0 && opacity > 0;
}
};

struct SymbolProperties {
inline SymbolProperties() {}

Expand Down Expand Up @@ -100,6 +114,7 @@ struct BackgroundProperties {
typedef mapbox::util::variant<
FillProperties,
LineProperties,
CircleProperties,
SymbolProperties,
RasterProperties,
BackgroundProperties,
Expand Down
2 changes: 2 additions & 0 deletions include/mbgl/style/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum class StyleLayerType : uint8_t {
Unknown,
Fill,
Line,
Circle,
Symbol,
Raster,
Background
Expand All @@ -36,6 +37,7 @@ MBGL_DEFINE_ENUM_CLASS(StyleLayerTypeClass, StyleLayerType, {
{ StyleLayerType::Unknown, "unknown" },
{ StyleLayerType::Fill, "fill" },
{ StyleLayerType::Line, "line" },
{ StyleLayerType::Circle, "circle" },
{ StyleLayerType::Symbol, "symbol" },
{ StyleLayerType::Raster, "raster" },
{ StyleLayerType::Background, "background" },
Expand Down
13 changes: 13 additions & 0 deletions src/mbgl/geometry/circle_buffer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <mbgl/geometry/circle_buffer.hpp>

#include <mbgl/platform/gl.hpp>

#include <climits>

using namespace mbgl;

void CircleVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey) {
vertex_type *vertices = static_cast<vertex_type *>(addElement());
vertices[0] = (x * 2) + ((ex + 1) / 2);
vertices[1] = (y * 2) + ((ey + 1) / 2);
}
27 changes: 27 additions & 0 deletions src/mbgl/geometry/circle_buffer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef MBGL_GEOMETRY_CIRCLE_BUFFER
#define MBGL_GEOMETRY_CIRCLE_BUFFER

#include <mbgl/geometry/buffer.hpp>

namespace mbgl {

class CircleVertexBuffer : public Buffer<
4 // 2 bytes per short * 4 of them.
> {
public:
typedef int16_t vertex_type;

/*
* Add a vertex to this buffer
*
* @param {number} x vertex position
* @param {number} y vertex position
* @param {number} ex extrude normal
* @param {number} ey extrude normal
*/
void add(vertex_type x, vertex_type y, float ex, float ey);
};

}

#endif // MBGL_GEOMETRY_CIRCLE_BUFFER
29 changes: 24 additions & 5 deletions src/mbgl/map/tile_worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <mbgl/geometry/glyph_atlas.hpp>
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/renderer/circle_bucket.hpp>
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/util/constants.hpp>
Expand Down Expand Up @@ -139,15 +140,22 @@ void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometr

std::unique_ptr<Bucket> bucket;

if (styleBucket.type == StyleLayerType::Fill) {
switch (styleBucket.type) {
case StyleLayerType::Fill:
bucket = createFillBucket(*geometryLayer, styleBucket);
} else if (styleBucket.type == StyleLayerType::Line) {
break;
case StyleLayerType::Line:
bucket = createLineBucket(*geometryLayer, styleBucket);
} else if (styleBucket.type == StyleLayerType::Symbol) {
break;
case StyleLayerType::Circle:
bucket = createCircleBucket(*geometryLayer, styleBucket);
break;
case StyleLayerType::Symbol:
bucket = createSymbolBucket(*geometryLayer, styleBucket);
} else if (styleBucket.type == StyleLayerType::Raster) {
break;
case StyleLayerType::Raster:
return;
} else {
default:
Log::Warning(Event::ParseTile, "unknown bucket render type for layer '%s' (source layer '%s')",
styleBucket.name.c_str(), styleBucket.source_layer.c_str());
}
Expand Down Expand Up @@ -203,6 +211,17 @@ std::unique_ptr<Bucket> TileWorker::createLineBucket(const GeometryTileLayer& la
return bucket->hasData() ? std::move(bucket) : nullptr;
}

std::unique_ptr<Bucket> TileWorker::createCircleBucket(const GeometryTileLayer& layer,
const StyleBucket& bucket_desc) {
auto bucket = std::make_unique<CircleBucket>(circleVertexBuffer,
triangleElementsBuffer);

// Circle does not have layout properties to apply.

addBucketGeometries(bucket, layer, bucket_desc.filter);
return bucket->hasData() ? std::move(bucket) : nullptr;
}

std::unique_ptr<Bucket> TileWorker::createSymbolBucket(const GeometryTileLayer& layer,
const StyleBucket& bucket_desc) {
auto bucket = std::make_unique<SymbolBucket>(*collision, id.overscaling);
Expand Down
3 changes: 3 additions & 0 deletions src/mbgl/map/tile_worker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/geometry/fill_buffer.hpp>
#include <mbgl/geometry/line_buffer.hpp>
#include <mbgl/geometry/circle_buffer.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/style/filter_expression.hpp>
Expand Down Expand Up @@ -52,6 +53,7 @@ class TileWorker : public util::noncopyable {

std::unique_ptr<Bucket> createFillBucket(const GeometryTileLayer&, const StyleBucket&);
std::unique_ptr<Bucket> createLineBucket(const GeometryTileLayer&, const StyleBucket&);
std::unique_ptr<Bucket> createCircleBucket(const GeometryTileLayer&, const StyleBucket&);
std::unique_ptr<Bucket> createSymbolBucket(const GeometryTileLayer&, const StyleBucket&);

template <class Bucket>
Expand All @@ -68,6 +70,7 @@ class TileWorker : public util::noncopyable {

FillVertexBuffer fillVertexBuffer;
LineVertexBuffer lineVertexBuffer;
CircleVertexBuffer circleVertexBuffer;

TriangleElementsBuffer triangleElementsBuffer;
LineElementsBuffer lineElementsBuffer;
Expand Down
92 changes: 92 additions & 0 deletions src/mbgl/renderer/circle_bucket.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include <mbgl/renderer/circle_bucket.hpp>
#include <mbgl/renderer/painter.hpp>

#include <mbgl/shader/circle_shader.hpp>

using namespace mbgl;

CircleBucket::CircleBucket(CircleVertexBuffer& vertexBuffer,
TriangleElementsBuffer& elementsBuffer)
: vertexBuffer_(vertexBuffer)
, elementsBuffer_(elementsBuffer)
, vertexStart_(vertexBuffer_.index())
, elementsStart_(elementsBuffer_.index()) {
}

CircleBucket::~CircleBucket() {
// Do not remove. header file only contains forward definitions to unique pointers.
}

void CircleBucket::upload() {
vertexBuffer_.upload();
elementsBuffer_.upload();
uploaded = true;
}

void CircleBucket::render(Painter& painter,
const StyleLayer& layer_desc,
const TileID& id,
const mat4& matrix) {
painter.renderCircle(*this, layer_desc, id, matrix);
}

bool CircleBucket::hasData() const {
return !triangleGroups_.empty();
}

void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) {
for (auto& circle : geometryCollection) {
for(auto & geometry : circle) {
auto x = geometry.x;
auto y = geometry.y;

// this geometry will be of the Point type, and we'll derive
// two triangles from it.
//
// ┌─────────┐
// │ 4 3 │
// │ │
// │ 1 2 │
// └─────────┘
//
vertexBuffer_.add(x, y, -1, -1); // 1
vertexBuffer_.add(x, y, 1, -1); // 2
vertexBuffer_.add(x, y, 1, 1); // 3
vertexBuffer_.add(x, y, -1, 1); // 4

if (!triangleGroups_.size() || (triangleGroups_.back()->vertex_length + 4 > 65535)) {
// Move to a new group because the old one can't hold the geometry.
triangleGroups_.emplace_back(std::make_unique<TriangleGroup>());
}

TriangleGroup& group = *triangleGroups_.back();
auto index = group.vertex_length;

// 1, 2, 3
// 1, 4, 3
elementsBuffer_.add(index, index + 1, index + 2);
elementsBuffer_.add(index, index + 3, index + 2);

group.vertex_length += 4;
group.elements_length += 2;
}
}
}

void CircleBucket::drawCircles(CircleShader& shader) {
char* vertexIndex = BUFFER_OFFSET(vertexStart_ * vertexBuffer_.itemSize);
char* elementsIndex = BUFFER_OFFSET(elementsStart_ * elementsBuffer_.itemSize);

for (auto& group : triangleGroups_) {
assert(group);

if (!group->elements_length) continue;

group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex);

MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elementsIndex));

vertexIndex += group->vertex_length * vertexBuffer_.itemSize;
elementsIndex += group->elements_length * elementsBuffer_.itemSize;
}
}
46 changes: 46 additions & 0 deletions src/mbgl/renderer/circle_bucket.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef MBGL_RENDERER_CIRCLE_BUCKET
#define MBGL_RENDERER_CIRCLE_BUCKET

#include <mbgl/renderer/bucket.hpp>

#include <mbgl/map/geometry_tile.hpp>

#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/geometry/circle_buffer.hpp>

#include <mbgl/style/style_bucket.hpp>
#include <mbgl/style/style_layout.hpp>

namespace mbgl {

class CircleVertexBuffer;
class CircleShader;

class CircleBucket : public Bucket {
using TriangleGroup = ElementGroup<3>;

public:
CircleBucket(CircleVertexBuffer &vertexBuffer, TriangleElementsBuffer &elementsBuffer);
~CircleBucket() override;

void upload() override;
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;

bool hasData() const;
void addGeometry(const GeometryCollection&);

void drawCircles(CircleShader& shader);

private:
CircleVertexBuffer& vertexBuffer_;
TriangleElementsBuffer& elementsBuffer_;

const size_t vertexStart_;
const size_t elementsStart_;

std::vector<std::unique_ptr<TriangleGroup>> triangleGroups_;
};

} // namespace mbgl

#endif // MBGL_RENDERER_CIRCLE_BUCKET
3 changes: 3 additions & 0 deletions src/mbgl/renderer/painter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <mbgl/shader/dot_shader.hpp>
#include <mbgl/shader/gaussian_shader.hpp>
#include <mbgl/shader/box_shader.hpp>
#include <mbgl/shader/circle_shader.hpp>

#include <mbgl/util/constants.hpp>
#include <mbgl/util/mat3.hpp>
Expand Down Expand Up @@ -68,6 +69,7 @@ void Painter::setup() {
assert(sdfIconShader);
assert(dotShader);
assert(gaussianShader);
assert(circleShader);


// Blending
Expand Down Expand Up @@ -103,6 +105,7 @@ void Painter::setupShaders() {
if (!dotShader) dotShader = std::make_unique<DotShader>();
if (!gaussianShader) gaussianShader = std::make_unique<GaussianShader>();
if (!collisionBoxShader) collisionBoxShader = std::make_unique<CollisionBoxShader>();
if (!circleShader) circleShader = std::make_unique<CircleShader>();
}

void Painter::resize() {
Expand Down
4 changes: 4 additions & 0 deletions src/mbgl/renderer/painter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct FrameData;
class DebugBucket;
class FillBucket;
class LineBucket;
class CircleBucket;
class SymbolBucket;
class RasterBucket;

Expand All @@ -50,6 +51,7 @@ class LineShader;
class LinejoinShader;
class LineSDFShader;
class LinepatternShader;
class CircleShader;
class PatternShader;
class IconShader;
class RasterShader;
Expand Down Expand Up @@ -107,6 +109,7 @@ class Painter : private util::noncopyable {
void renderDebugText(DebugBucket& bucket, const mat4 &matrix);
void renderFill(FillBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix);
void renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix);
void renderCircle(CircleBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix);
void renderSymbol(SymbolBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix);
void renderRaster(RasterBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix);
void renderBackground(const StyleLayer &layer_desc);
Expand Down Expand Up @@ -228,6 +231,7 @@ class Painter : private util::noncopyable {
std::unique_ptr<DotShader> dotShader;
std::unique_ptr<GaussianShader> gaussianShader;
std::unique_ptr<CollisionBoxShader> collisionBoxShader;
std::unique_ptr<CircleShader> circleShader;

StaticVertexBuffer backgroundBuffer = {
{ -1, -1 }, { 1, -1 },
Expand Down
Loading