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

Commit

Permalink
Add circle render type
Browse files Browse the repository at this point in the history
  • Loading branch information
brunoabinader authored and jfirebaugh committed Aug 13, 2015
1 parent d579cec commit d19ed5a
Show file tree
Hide file tree
Showing 29 changed files with 497 additions and 6 deletions.
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

0 comments on commit d19ed5a

Please sign in to comment.