summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp1
-rw-r--r--src/mbgl/geometry/buffer.hpp115
-rw-r--r--src/mbgl/geometry/circle_buffer.cpp15
-rw-r--r--src/mbgl/geometry/circle_buffer.hpp24
-rw-r--r--src/mbgl/geometry/collision_box_buffer.cpp27
-rw-r--r--src/mbgl/geometry/collision_box_buffer.hpp20
-rw-r--r--src/mbgl/geometry/debug_font_buffer.cpp44
-rw-r--r--src/mbgl/geometry/debug_font_buffer.hpp14
-rw-r--r--src/mbgl/geometry/elements_buffer.cpp18
-rw-r--r--src/mbgl/geometry/elements_buffer.hpp46
-rw-r--r--src/mbgl/geometry/feature_index.cpp20
-rw-r--r--src/mbgl/geometry/feature_index.hpp8
-rw-r--r--src/mbgl/geometry/fill_buffer.cpp15
-rw-r--r--src/mbgl/geometry/fill_buffer.hpp18
-rw-r--r--src/mbgl/geometry/icon_buffer.cpp35
-rw-r--r--src/mbgl/geometry/icon_buffer.hpp17
-rw-r--r--src/mbgl/geometry/line_buffer.cpp37
-rw-r--r--src/mbgl/geometry/line_buffer.hpp37
-rw-r--r--src/mbgl/geometry/static_vertex_buffer.cpp24
-rw-r--r--src/mbgl/geometry/static_vertex_buffer.hpp30
-rw-r--r--src/mbgl/geometry/text_buffer.cpp36
-rw-r--r--src/mbgl/geometry/text_buffer.hpp20
-rw-r--r--src/mbgl/geometry/vao.hpp79
-rw-r--r--src/mbgl/gl/attribute.hpp50
-rw-r--r--src/mbgl/gl/context.cpp30
-rw-r--r--src/mbgl/gl/context.hpp31
-rw-r--r--src/mbgl/gl/index_buffer.hpp41
-rw-r--r--src/mbgl/gl/shader.cpp (renamed from src/mbgl/shader/shader.cpp)21
-rw-r--r--src/mbgl/gl/shader.hpp45
-rw-r--r--src/mbgl/gl/types.hpp21
-rw-r--r--src/mbgl/gl/uniform.cpp (renamed from src/mbgl/shader/uniform.cpp)6
-rw-r--r--src/mbgl/gl/uniform.hpp (renamed from src/mbgl/shader/uniform.hpp)8
-rw-r--r--src/mbgl/gl/vao.cpp (renamed from src/mbgl/geometry/vao.cpp)21
-rw-r--r--src/mbgl/gl/vao.hpp78
-rw-r--r--src/mbgl/gl/vertex_buffer.hpp17
-rw-r--r--src/mbgl/layout/symbol_layout.cpp111
-rw-r--r--src/mbgl/layout/symbol_layout.hpp2
-rw-r--r--src/mbgl/map/map.cpp11
-rw-r--r--src/mbgl/renderer/circle_bucket.cpp52
-rw-r--r--src/mbgl/renderer/circle_bucket.hpp20
-rw-r--r--src/mbgl/renderer/debug_bucket.cpp95
-rw-r--r--src/mbgl/renderer/debug_bucket.hpp21
-rw-r--r--src/mbgl/renderer/element_group.hpp28
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp106
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp37
-rw-r--r--src/mbgl/renderer/line_bucket.cpp218
-rw-r--r--src/mbgl/renderer/line_bucket.hpp33
-rw-r--r--src/mbgl/renderer/painter.cpp28
-rw-r--r--src/mbgl/renderer/painter.hpp47
-rw-r--r--src/mbgl/renderer/painter_background.cpp10
-rw-r--r--src/mbgl/renderer/painter_circle.cpp2
-rw-r--r--src/mbgl/renderer/painter_clipping.cpp6
-rw-r--r--src/mbgl/renderer/painter_debug.cpp10
-rw-r--r--src/mbgl/renderer/painter_fill.cpp8
-rw-r--r--src/mbgl/renderer/painter_line.cpp4
-rw-r--r--src/mbgl/renderer/painter_raster.cpp2
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp14
-rw-r--r--src/mbgl/renderer/raster_bucket.cpp8
-rw-r--r--src/mbgl/renderer/raster_bucket.hpp12
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp61
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp49
-rw-r--r--src/mbgl/shader/circle_shader.cpp7
-rw-r--r--src/mbgl/shader/circle_shader.hpp29
-rw-r--r--src/mbgl/shader/circle_vertex.cpp7
-rw-r--r--src/mbgl/shader/circle_vertex.hpp39
-rw-r--r--src/mbgl/shader/collision_box_shader.cpp25
-rw-r--r--src/mbgl/shader/collision_box_shader.hpp23
-rw-r--r--src/mbgl/shader/collision_box_vertex.cpp7
-rw-r--r--src/mbgl/shader/collision_box_vertex.hpp43
-rw-r--r--src/mbgl/shader/fill_outline_pattern_shader.cpp15
-rw-r--r--src/mbgl/shader/fill_outline_pattern_shader.hpp37
-rw-r--r--src/mbgl/shader/fill_outline_shader.cpp15
-rw-r--r--src/mbgl/shader/fill_outline_shader.hpp26
-rw-r--r--src/mbgl/shader/fill_pattern_shader.cpp15
-rw-r--r--src/mbgl/shader/fill_pattern_shader.hpp36
-rw-r--r--src/mbgl/shader/fill_shader.cpp15
-rw-r--r--src/mbgl/shader/fill_shader.hpp25
-rw-r--r--src/mbgl/shader/fill_vertex.cpp7
-rw-r--r--src/mbgl/shader/fill_vertex.hpp30
-rw-r--r--src/mbgl/shader/icon_shader.cpp31
-rw-r--r--src/mbgl/shader/icon_shader.hpp24
-rw-r--r--src/mbgl/shader/line_pattern_shader.cpp15
-rw-r--r--src/mbgl/shader/line_pattern_shader.hpp41
-rw-r--r--src/mbgl/shader/line_sdf_shader.cpp15
-rw-r--r--src/mbgl/shader/line_sdf_shader.hpp42
-rw-r--r--src/mbgl/shader/line_shader.cpp10
-rw-r--r--src/mbgl/shader/line_shader.hpp38
-rw-r--r--src/mbgl/shader/line_vertex.cpp7
-rw-r--r--src/mbgl/shader/line_vertex.hpp72
-rw-r--r--src/mbgl/shader/linepattern_shader.cpp23
-rw-r--r--src/mbgl/shader/linepattern_shader.hpp35
-rw-r--r--src/mbgl/shader/linesdf_shader.cpp23
-rw-r--r--src/mbgl/shader/linesdf_shader.hpp36
-rw-r--r--src/mbgl/shader/outline_shader.cpp20
-rw-r--r--src/mbgl/shader/outline_shader.hpp21
-rw-r--r--src/mbgl/shader/outlinepattern_shader.cpp20
-rw-r--r--src/mbgl/shader/outlinepattern_shader.hpp32
-rw-r--r--src/mbgl/shader/pattern_shader.cpp20
-rw-r--r--src/mbgl/shader/pattern_shader.hpp31
-rw-r--r--src/mbgl/shader/plain_shader.cpp20
-rw-r--r--src/mbgl/shader/plain_shader.hpp20
-rw-r--r--src/mbgl/shader/raster_shader.cpp12
-rw-r--r--src/mbgl/shader/raster_shader.hpp42
-rw-r--r--src/mbgl/shader/raster_vertex.cpp7
-rw-r--r--src/mbgl/shader/raster_vertex.hpp39
-rw-r--r--src/mbgl/shader/sdf_shader.cpp31
-rw-r--r--src/mbgl/shader/sdf_shader.hpp32
-rw-r--r--src/mbgl/shader/shader.hpp53
-rw-r--r--src/mbgl/shader/shaders.hpp72
-rw-r--r--src/mbgl/shader/symbol_icon_shader.cpp15
-rw-r--r--src/mbgl/shader/symbol_icon_shader.hpp32
-rw-r--r--src/mbgl/shader/symbol_sdf_shader.cpp15
-rw-r--r--src/mbgl/shader/symbol_sdf_shader.hpp40
-rw-r--r--src/mbgl/shader/symbol_vertex.cpp9
-rw-r--r--src/mbgl/shader/symbol_vertex.hpp54
-rw-r--r--src/mbgl/style/layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.cpp4
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.cpp4
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/line_layer_impl.cpp4
-rw-r--r--src/mbgl/style/layers/line_layer_impl.hpp2
-rw-r--r--src/mbgl/style/source_impl.cpp51
-rw-r--r--src/mbgl/text/collision_tile.cpp46
-rw-r--r--src/mbgl/text/collision_tile.hpp10
-rw-r--r--src/mbgl/tile/geometry_tile.cpp2
-rw-r--r--src/mbgl/tile/tile.cpp1
-rw-r--r--src/mbgl/tile/tile.hpp1
-rw-r--r--src/mbgl/util/intersection_tests.cpp49
-rw-r--r--src/mbgl/util/intersection_tests.hpp6
-rw-r--r--src/mbgl/util/tile_coordinate.hpp25
131 files changed, 1847 insertions, 1878 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index 63adf9de2a..dbd5f1f433 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -185,6 +185,7 @@ void AnnotationManager::updateStyle(Style& style) {
layer->setSourceLayer(PointLayerID);
layer->setIconImage({"{sprite}"});
layer->setIconAllowOverlap(true);
+ layer->setIconIgnorePlacement(true);
layer->impl->spriteAtlas = &spriteAtlas;
diff --git a/src/mbgl/geometry/buffer.hpp b/src/mbgl/geometry/buffer.hpp
deleted file mode 100644
index 2d010e39ac..0000000000
--- a/src/mbgl/geometry/buffer.hpp
+++ /dev/null
@@ -1,115 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/context.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/optional.hpp>
-
-#include <memory>
-#include <cstdlib>
-#include <cassert>
-#include <stdexcept>
-
-namespace mbgl {
-
-template <uint32_t item_size,
- gl::BufferType target = gl::BufferType::Vertex,
- uint32_t defaultLength = 8192,
- bool retainAfterUpload = false>
-class Buffer : private util::noncopyable {
- static_assert(target == gl::BufferType::Vertex || target == gl::BufferType::Element,
- "target must be one of gl::BufferType::Vertex or gl::BufferType::Element");
-
-public:
- ~Buffer() {
- cleanup();
- }
-
- // Returns the number of elements in this buffer. This is not the number of
- // bytes, but rather the number of coordinates with associated information.
- uint32_t index() const {
- return pos / itemSize;
- }
-
- bool empty() const {
- return pos == 0;
- }
-
- // Transfers this buffer to the GPU and binds the buffer to the GL context.
- void bind(gl::Context& context) {
- const bool initialized { buffer };
- if (!initialized) {
- buffer = context.createBuffer();
- }
-
- if (target == gl::BufferType::Vertex) {
- context.vertexBuffer = *buffer;
- } else {
- context.elementBuffer = *buffer;
- }
-
- if (!initialized) {
- if (array == nullptr) {
- Log::Debug(Event::OpenGL, "Buffer doesn't contain elements");
- pos = 0;
- }
- context.uploadBuffer(target, pos, array);
- if (!retainAfterUpload) {
- cleanup();
- }
- }
- }
-
- void cleanup() {
- if (array) {
- free(array);
- array = nullptr;
- }
- }
-
- gl::BufferID getID() const {
- return buffer ? *buffer : 0;
- }
-
- // Uploads the buffer to the GPU to be available when we need it.
- void upload(gl::Context& context) {
- if (!buffer) {
- bind(context);
- }
- }
-
-protected:
- // increase the buffer size by at least /required/ bytes.
- void *addElement() {
- if (buffer) {
- throw std::runtime_error("Can't add elements after buffer was bound to GPU");
- }
- if (length < pos + itemSize) {
- while (length < pos + itemSize) length += defaultLength;
- array = realloc(array, length);
- if (array == nullptr) {
- throw std::runtime_error("Buffer reallocation failed");
- }
- }
- pos += itemSize;
- return reinterpret_cast<char *>(array) + (pos - itemSize);
- }
-
-public:
- static constexpr const uint32_t itemSize = item_size;
-
-private:
- // CPU buffer
- void* array = nullptr;
-
- // Byte position where we are writing.
- uint32_t pos = 0;
-
- // Number of bytes that are valid in this buffer.
- uint32_t length = 0;
-
- // GL buffer object handle.
- mbgl::optional<gl::UniqueBuffer> buffer;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/circle_buffer.cpp b/src/mbgl/geometry/circle_buffer.cpp
deleted file mode 100644
index cc31fb83bf..0000000000
--- a/src/mbgl/geometry/circle_buffer.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <mbgl/geometry/circle_buffer.hpp>
-
-#include <mbgl/gl/gl.hpp>
-
-#include <climits>
-
-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);
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/circle_buffer.hpp b/src/mbgl/geometry/circle_buffer.hpp
deleted file mode 100644
index 2b188c4003..0000000000
--- a/src/mbgl/geometry/circle_buffer.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#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);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/collision_box_buffer.cpp b/src/mbgl/geometry/collision_box_buffer.cpp
deleted file mode 100644
index ae58cf7bca..0000000000
--- a/src/mbgl/geometry/collision_box_buffer.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <mbgl/geometry/collision_box_buffer.hpp>
-#include <mbgl/gl/gl.hpp>
-#include <mbgl/util/math.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-
-uint32_t CollisionBoxVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, float maxzoom, float placementZoom) {
- const uint32_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 */ = ::round(ox); // use 1/64 pixels for placement
- shorts[3] /* offset */ = ::round(oy);
-
- uint8_t *ubytes = static_cast<uint8_t *>(data);
- // a_data
- ubytes[8] = maxzoom * 10;
- ubytes[9] = placementZoom * 10;
-
- return idx;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/collision_box_buffer.hpp b/src/mbgl/geometry/collision_box_buffer.hpp
deleted file mode 100644
index 5360ac3f4c..0000000000
--- a/src/mbgl/geometry/collision_box_buffer.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-#include <array>
-
-namespace mbgl {
-
-class CollisionBoxVertexBuffer : public Buffer <
- 12,
- gl::BufferType::Vertex,
- 32768
-> {
-public:
- typedef int16_t vertex_type;
-
- uint32_t add(int16_t x, int16_t y, float ex, float ey, float maxzoom, float placementZoom);
-};
-
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/debug_font_buffer.cpp b/src/mbgl/geometry/debug_font_buffer.cpp
deleted file mode 100644
index f64ce8816b..0000000000
--- a/src/mbgl/geometry/debug_font_buffer.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <mbgl/geometry/debug_font_buffer.hpp>
-#include <mbgl/geometry/debug_font_data.hpp>
-
-#include <mbgl/gl/gl.hpp>
-#include <cmath>
-#include <cstring>
-
-namespace mbgl {
-
-void DebugFontBuffer::addText(const char *text, double left, double baseline, double scale) {
- uint16_t *coords = nullptr;
-
- const size_t len = strlen(text);
- for (size_t i = 0; i < len; ++i) {
- if (text[i] < 32 || (unsigned char)(text[i]) >= 127) {
- continue;
- }
-
- const glyph& glyph = simplex[text[i] - 32];
-
- int16_t prev_x = -1, prev_y = -1, prev = false;
- for (int32_t j = 0; j < glyph.length; j += 2) {
- if (glyph.data[j] == -1 && glyph.data[j + 1] == -1) {
- prev = false;
- } else {
- int16_t x = ::round(left + glyph.data[j] * scale);
- int16_t y = ::round(baseline - glyph.data[j + 1] * scale);
- if (prev) {
- coords = static_cast<uint16_t *>(addElement());
- coords[0] = prev_x;
- coords[1] = prev_y;
-
- coords = static_cast<uint16_t *>(addElement());
- coords[0] = x;
- coords[1] = y;
- }
- prev_x = x; prev_y = y; prev = true;
- }
- }
- left += glyph.width * scale;
- }
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/debug_font_buffer.hpp b/src/mbgl/geometry/debug_font_buffer.hpp
deleted file mode 100644
index f2debe97a4..0000000000
--- a/src/mbgl/geometry/debug_font_buffer.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-
-namespace mbgl {
-
-class DebugFontBuffer : public Buffer<
- 4 // 2 bytes per coordinate, 2 coordinates
-> {
-public:
- void addText(const char *text, double left, double baseline, double scale = 1);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/elements_buffer.cpp b/src/mbgl/geometry/elements_buffer.cpp
deleted file mode 100644
index b7d8cb2015..0000000000
--- a/src/mbgl/geometry/elements_buffer.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <mbgl/geometry/elements_buffer.hpp>
-
-namespace mbgl {
-
-void TriangleElementsBuffer::add(element_type a, element_type b, element_type c) {
- element_type *elements = static_cast<element_type *>(addElement());
- elements[0] = a;
- elements[1] = b;
- elements[2] = c;
-}
-
-void LineElementsBuffer::add(element_type a, element_type b) {
- element_type *elements = static_cast<element_type *>(addElement());
- elements[0] = a;
- elements[1] = b;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/elements_buffer.hpp b/src/mbgl/geometry/elements_buffer.hpp
deleted file mode 100644
index f995229c9d..0000000000
--- a/src/mbgl/geometry/elements_buffer.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-#include <mbgl/geometry/vao.hpp>
-
-#include <mbgl/util/noncopyable.hpp>
-
-#include <array>
-
-namespace mbgl {
-
-template <uint8_t count>
-struct ElementGroup : public util::noncopyable {
- std::array<VertexArrayObject, count> array;
- uint32_t vertex_length;
- uint32_t elements_length;
-
- ElementGroup(uint32_t vertex_length_ = 0, uint32_t elements_length_ = 0)
- : vertex_length(vertex_length_)
- , elements_length(elements_length_)
- {
- }
-};
-
-class TriangleElementsBuffer : public Buffer<
- 6, // bytes per triangle (3 * unsigned short == 6 bytes)
- gl::BufferType::Element
-> {
-public:
- typedef uint16_t element_type;
-
- void add(element_type a, element_type b, element_type c);
-};
-
-
-class LineElementsBuffer : public Buffer<
- 4, // bytes per triangle (2 * unsigned short == 6 bytes)
- gl::BufferType::Element
-> {
-public:
- typedef uint16_t element_type;
-
- void add(element_type a, element_type b);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index 62db3b478d..b37bdb5ecc 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -52,7 +52,7 @@ static bool topDownSymbols(const IndexedSubfeature& a, const IndexedSubfeature&
void FeatureIndex::query(
std::unordered_map<std::string, std::vector<Feature>>& result,
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const float bearing,
const double tileSize,
const double scale,
@@ -83,7 +83,7 @@ void FeatureIndex::query(
return;
}
- std::vector<IndexedSubfeature> symbolFeatures = collisionTile->queryRenderedSymbols(box, scale);
+ std::vector<IndexedSubfeature> symbolFeatures = collisionTile->queryRenderedSymbols(queryGeometry, scale);
std::sort(symbolFeatures.begin(), symbolFeatures.end(), topDownSymbols);
for (const auto& symbolFeature : symbolFeatures) {
addFeature(result, symbolFeature, queryGeometry, filterLayerIDs, geometryTileData, tileID, style, bearing, pixelsToTileUnits);
@@ -93,7 +93,7 @@ void FeatureIndex::query(
void FeatureIndex::addFeature(
std::unordered_map<std::string, std::vector<Feature>>& result,
const IndexedSubfeature& indexedFeature,
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const optional<std::vector<std::string>>& filterLayerIDs,
const GeometryTileData& geometryTileData,
const CanonicalTileID& tileID,
@@ -128,8 +128,8 @@ void FeatureIndex::addFeature(
}
}
-optional<GeometryCollection> FeatureIndex::translateQueryGeometry(
- const GeometryCollection& queryGeometry,
+optional<GeometryCoordinates> FeatureIndex::translateQueryGeometry(
+ const GeometryCoordinates& queryGeometry,
const std::array<float, 2>& translate,
const style::TranslateAnchorType anchorType,
const float bearing,
@@ -143,13 +143,9 @@ optional<GeometryCollection> FeatureIndex::translateQueryGeometry(
translateVec = util::rotate(translateVec, -bearing);
}
- GeometryCollection translated;
- for (const auto& ring : queryGeometry) {
- translated.emplace_back();
- auto& translatedRing = translated.back();
- for (const auto& p : ring) {
- translatedRing.push_back(p - translateVec);
- }
+ GeometryCoordinates translated;
+ for (const auto& p : queryGeometry) {
+ translated.push_back(p - translateVec);
}
return translated;
}
diff --git a/src/mbgl/geometry/feature_index.hpp b/src/mbgl/geometry/feature_index.hpp
index 0fddcb4700..021770c78d 100644
--- a/src/mbgl/geometry/feature_index.hpp
+++ b/src/mbgl/geometry/feature_index.hpp
@@ -35,7 +35,7 @@ public:
void query(
std::unordered_map<std::string, std::vector<Feature>>& result,
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const float bearing,
const double tileSize,
const double scale,
@@ -44,8 +44,8 @@ public:
const CanonicalTileID&,
const style::Style&) const;
- static optional<GeometryCollection> translateQueryGeometry(
- const GeometryCollection& queryGeometry,
+ static optional<GeometryCoordinates> translateQueryGeometry(
+ const GeometryCoordinates& queryGeometry,
const std::array<float, 2>& translate,
const style::TranslateAnchorType,
const float bearing,
@@ -59,7 +59,7 @@ private:
void addFeature(
std::unordered_map<std::string, std::vector<Feature>>& result,
const IndexedSubfeature&,
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const optional<std::vector<std::string>>& filterLayerIDs,
const GeometryTileData&,
const CanonicalTileID&,
diff --git a/src/mbgl/geometry/fill_buffer.cpp b/src/mbgl/geometry/fill_buffer.cpp
deleted file mode 100644
index 6cb07ea66a..0000000000
--- a/src/mbgl/geometry/fill_buffer.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <mbgl/geometry/fill_buffer.hpp>
-
-#include <mbgl/gl/gl.hpp>
-
-#include <climits>
-
-namespace mbgl {
-
-void FillVertexBuffer::add(vertex_type x, vertex_type y) {
- vertex_type *vertices = static_cast<vertex_type *>(addElement());
- vertices[0] = x;
- vertices[1] = y;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/fill_buffer.hpp b/src/mbgl/geometry/fill_buffer.hpp
deleted file mode 100644
index a180d9c5a2..0000000000
--- a/src/mbgl/geometry/fill_buffer.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-#include <vector>
-#include <cstdint>
-
-namespace mbgl {
-
-class FillVertexBuffer : public Buffer<
- 4 // bytes per coordinates (2 * unsigned short == 4 bytes)
-> {
-public:
- typedef int16_t vertex_type;
-
- void add(vertex_type x, vertex_type y);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/icon_buffer.cpp b/src/mbgl/geometry/icon_buffer.cpp
deleted file mode 100644
index 745003a548..0000000000
--- a/src/mbgl/geometry/icon_buffer.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <mbgl/geometry/icon_buffer.hpp>
-#include <mbgl/gl/gl.hpp>
-#include <mbgl/util/math.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-
-uint32_t IconVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, int16_t tx, int16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle) {
- const uint32_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 */ = ::round(ox * 64); // use 1/64 pixels for placement
- shorts[3] /* offset */ = ::round(oy * 64);
-
- uint16_t *ushorts = static_cast<uint16_t *>(data);
- // a_texture_pos
- ushorts[4] /* tex */ = tx / 4;
- ushorts[5] /* tex */ = ty / 4;
-
- uint8_t *ubytes = static_cast<uint8_t *>(data);
- // a_data
- ubytes[12] /* labelminzoom */ = labelminzoom * 10;
- ubytes[13] /* labelangle */ = labelangle;
-
- ubytes[14] /* minzoom */ = minzoom * 10; // 1/10 zoom levels: z16 == 160.
- ubytes[15] /* maxzoom */ = ::fmin(maxzoom, 25) * 10; // 1/10 zoom levels: z16 == 160.
-
- return idx;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/icon_buffer.hpp b/src/mbgl/geometry/icon_buffer.hpp
deleted file mode 100644
index 81e17df495..0000000000
--- a/src/mbgl/geometry/icon_buffer.hpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-
-#include <array>
-
-namespace mbgl {
-
- class IconVertexBuffer : public Buffer<
- 16
- > {
- public:
- uint32_t add(int16_t x, int16_t y, float ox, float oy, int16_t tx, int16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle);
-
- };
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/line_buffer.cpp b/src/mbgl/geometry/line_buffer.cpp
deleted file mode 100644
index 0eabf8e1e9..0000000000
--- a/src/mbgl/geometry/line_buffer.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <mbgl/geometry/line_buffer.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-
-uint32_t LineVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey, bool tx, bool ty, int8_t dir, int32_t linesofar) {
- uint32_t idx = index();
- void *data = addElement();
-
- int16_t *coords = static_cast<int16_t *>(data);
- coords[0] = (x * 2) | tx;
- coords[1] = (y * 2) | ty;
-
- uint8_t *ubytes = static_cast<uint8_t *>(data);
- // add 128 to store an byte in an unsigned byte
- ubytes[4] = ::round(extrudeScale * ex) + 128;
- ubytes[5] = ::round(extrudeScale * ey) + 128;
-
- // Encode the -1/0/1 direction value into the first two bits of .z of a_data.
- // Combine it with the lower 6 bits of `linesofar` (shifted by 2 bites to make
- // room for the direction value). The upper 8 bits of `linesofar` are placed in
- // the `w` component. `linesofar` is scaled down by `LINE_DISTANCE_SCALE` so that
- // we can store longer distances while sacrificing precision.
-
- // Encode the -1/0/1 direction value into .zw coordinates of a_data, which is normally covered
- // by linesofar, so we need to merge them.
- // The z component's first bit, as well as the sign bit is reserved for the direction,
- // so we need to shift the linesofar.
-
- ubytes[6] = ((dir == 0 ? 0 : (dir < 0 ? -1 : 1 )) + 1) | ((linesofar & 0x3F) << 2);
- ubytes[7] = linesofar >> 6;
-
- return idx;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/line_buffer.hpp b/src/mbgl/geometry/line_buffer.hpp
deleted file mode 100644
index bfa9a55021..0000000000
--- a/src/mbgl/geometry/line_buffer.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-
-namespace mbgl {
-
-class LineVertexBuffer : public Buffer<
- 8 // 2 coordinates per vertex + 1 linesofar + 1 extrude coord pair == 4 (== 8 bytes)
-> {
-public:
- typedef int16_t vertex_type;
-
- /*
- * Scale the extrusion vector so that the normal length is this value.
- * Contains the "texture" normals (-1..1). This is distinct from the extrude
- * normals for line joins, because the x-value remains 0 for the texture
- * normal array, while the extrude normal actually moves the vertex to create
- * the acute/bevelled line join.
- */
- static const int8_t extrudeScale = 63;
-
- /*
- * 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
- * @param {number} tx texture normal
- * @param {number} ty texture normal
- * @param {number} dir direction of the line cap (-1/0/1)
- */
- uint32_t add(vertex_type x, vertex_type y, float ex, float ey, bool tx, bool ty, int8_t dir, int32_t linesofar = 0);
-};
-
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/static_vertex_buffer.cpp b/src/mbgl/geometry/static_vertex_buffer.cpp
deleted file mode 100644
index c66b194748..0000000000
--- a/src/mbgl/geometry/static_vertex_buffer.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <mbgl/geometry/static_vertex_buffer.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-StaticVertexBuffer::StaticVertexBuffer(std::initializer_list<std::array<VertexType, 2>> init) {
- for (const auto& vertex : init) {
- VertexType* vertices = static_cast<VertexType*>(addElement());
- vertices[0] = std::get<0>(vertex);
- vertices[1] = std::get<1>(vertex);
- }
-}
-
-StaticRasterVertexBuffer::StaticRasterVertexBuffer(std::initializer_list<std::array<VertexType, 4>> init) {
- for (const auto& vertex : init) {
- VertexType* vertices = static_cast<VertexType*>(addElement());
- vertices[0] = std::get<0>(vertex);
- vertices[1] = std::get<1>(vertex);
- vertices[2] = std::get<2>(vertex);
- vertices[3] = std::get<3>(vertex);
- }
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/static_vertex_buffer.hpp b/src/mbgl/geometry/static_vertex_buffer.hpp
deleted file mode 100644
index edf3b966fd..0000000000
--- a/src/mbgl/geometry/static_vertex_buffer.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-
-#include <array>
-#include <cstdint>
-
-namespace mbgl {
-
-class StaticVertexBuffer : public Buffer<
- 4, // bytes per vertex (2 * signed short == 4 bytes)
- gl::BufferType::Vertex,
- 32 // default length
-> {
-public:
- using VertexType = int16_t;
- StaticVertexBuffer(std::initializer_list<std::array<VertexType, 2>>);
-};
-
-class StaticRasterVertexBuffer : public Buffer<
- 8, // bytes per vertex (4 * signed short == 8 bytes)
- gl::BufferType::Vertex,
- 32 // default length
-> {
-public:
- using VertexType = int16_t;
- StaticRasterVertexBuffer(std::initializer_list<std::array<VertexType, 4>>);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/text_buffer.cpp b/src/mbgl/geometry/text_buffer.cpp
deleted file mode 100644
index 8fed7a71d1..0000000000
--- a/src/mbgl/geometry/text_buffer.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <mbgl/geometry/text_buffer.hpp>
-#include <mbgl/gl/gl.hpp>
-#include <mbgl/util/math.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-
-uint32_t TextVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle) {
- const uint32_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 */ = ::round(ox * 64); // use 1/64 pixels for placement
- shorts[3] /* offset */ = ::round(oy * 64);
-
- uint16_t *ushorts = static_cast<uint16_t *>(data);
- // a_texture_pos
- ushorts[4] /* tex */ = tx / 4;
- ushorts[5] /* tex */ = ty / 4;
-
- uint8_t *ubytes = static_cast<uint8_t *>(data);
- // a_data
- ubytes[12] /* labelminzoom */ = labelminzoom * 10;
- ubytes[13] /* labelangle */ = labelangle;
-
- ubytes[14] /* minzoom */ = minzoom * 10; // 1/10 zoom levels: z16 == 160.
- ubytes[15] /* maxzoom */ = ::fmin(maxzoom, 25) * 10; // 1/10 zoom levels: z16 == 160.
-
- return idx;
-}
-
-} // namespace mbgl
-
diff --git a/src/mbgl/geometry/text_buffer.hpp b/src/mbgl/geometry/text_buffer.hpp
deleted file mode 100644
index 4b46a38770..0000000000
--- a/src/mbgl/geometry/text_buffer.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-#include <array>
-
-namespace mbgl {
-
-class TextVertexBuffer : public Buffer <
- 16,
- gl::BufferType::Vertex,
- 32768
-> {
-public:
- typedef int16_t vertex_type;
-
- uint32_t add(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle);
-};
-
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/vao.hpp b/src/mbgl/geometry/vao.hpp
deleted file mode 100644
index 65abab1e4e..0000000000
--- a/src/mbgl/geometry/vao.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/gl/context.hpp>
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/optional.hpp>
-
-#include <stdexcept>
-
-namespace mbgl {
-
-class VertexArrayObject : public util::noncopyable {
-public:
- VertexArrayObject();
- ~VertexArrayObject();
-
- template <typename VertexBuffer>
- void bind(Shader& shader,
- VertexBuffer& vertexBuffer,
- int8_t* offset,
- gl::Context& context) {
- bindVertexArrayObject(context);
- if (bound_shader == 0) {
- vertexBuffer.bind(context);
- shader.bind(offset);
- if (vertexArray) {
- storeBinding(shader, vertexBuffer.getID(), 0, offset);
- }
- } else {
- verifyBinding(shader, vertexBuffer.getID(), 0, offset);
- }
- }
-
- template <typename VertexBuffer, typename ElementsBuffer>
- void bind(Shader& shader,
- VertexBuffer& vertexBuffer,
- ElementsBuffer& elementsBuffer,
- int8_t* offset,
- gl::Context& context) {
- bindVertexArrayObject(context);
- if (bound_shader == 0) {
- vertexBuffer.bind(context);
- elementsBuffer.bind(context);
- shader.bind(offset);
- if (vertexArray) {
- storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
- }
- } else {
- verifyBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
- }
- }
-
- gl::VertexArrayID getID() const {
- return *vertexArray;
- }
-
-private:
- void bindVertexArrayObject(gl::Context&);
- void storeBinding(Shader& shader,
- gl::BufferID vertexBuffer,
- gl::BufferID elementsBuffer,
- int8_t* offset);
- void verifyBinding(Shader& shader,
- gl::BufferID vertexBuffer,
- gl::BufferID elementsBuffer,
- int8_t* offset);
-
- mbgl::optional<gl::UniqueVertexArray> vertexArray;
-
- // For debug reasons, we're storing the bind information so that we can
- // detect errors and report
- gl::ProgramID bound_shader = 0;
- const char* bound_shader_name = "";
- gl::BufferID bound_vertex_buffer = 0;
- gl::BufferID bound_elements_buffer = 0;
- int8_t *bound_offset = nullptr;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp
new file mode 100644
index 0000000000..8bc474e967
--- /dev/null
+++ b/src/mbgl/gl/attribute.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <mbgl/gl/types.hpp>
+#include <mbgl/gl/shader.hpp>
+
+#include <cstddef>
+#include <limits>
+#include <vector>
+
+namespace mbgl {
+namespace gl {
+
+template <typename T, std::size_t N>
+class Attribute {
+public:
+ Attribute(const char* name, const Shader& shader)
+ : location(shader.getAttributeLocation(name)) {}
+
+ AttributeLocation location;
+};
+
+class AttributeBinding {
+public:
+ template <class Vertex, class T, std::size_t N, std::size_t O>
+ AttributeBinding(const T (Vertex::*)[N], const Attribute<T, N>& attribute, std::integral_constant<std::size_t, O>)
+ : location(attribute.location),
+ type(DataTypeOf<T>::value),
+ count(N),
+ offset(O) {
+ static_assert(std::is_standard_layout<Vertex>::value, "vertex type must use standard layout");
+ static_assert(O % 4 == 0, "vertex attribute must be optimally aligned");
+ static_assert(1 <= N && N <= 4, "count must be 1, 2, 3, or 4");
+ static_assert(sizeof(Vertex) <= std::numeric_limits<int32_t>::max(), "vertex type is too big");
+ }
+
+ AttributeLocation location;
+ DataType type;
+ uint8_t count;
+ std::size_t offset;
+};
+
+#define MBGL_MAKE_ATTRIBUTE_BINDING(Vertex, shader, name) \
+ ::mbgl::gl::AttributeBinding(&Vertex::name, \
+ shader.name, \
+ std::integral_constant<std::size_t, offsetof(Vertex, name)>())
+
+template <class Shader, class Vertex> struct AttributeBindings;
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp
index ded7936feb..2a04fcc18e 100644
--- a/src/mbgl/gl/context.cpp
+++ b/src/mbgl/gl/context.cpp
@@ -91,10 +91,32 @@ UniqueShader Context::createFragmentShader() {
return UniqueShader{ MBGL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER)), { this } };
}
-UniqueBuffer Context::createBuffer() {
+UniqueBuffer Context::createVertexBuffer(const void* data, std::size_t size) {
BufferID id = 0;
MBGL_CHECK_ERROR(glGenBuffers(1, &id));
- return UniqueBuffer{ std::move(id), { this } };
+ UniqueBuffer result { std::move(id), { this } };
+ vertexBuffer = result;
+ MBGL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
+ return result;
+}
+
+UniqueBuffer Context::createIndexBuffer(const void* data, std::size_t size) {
+ BufferID id = 0;
+ MBGL_CHECK_ERROR(glGenBuffers(1, &id));
+ UniqueBuffer result { std::move(id), { this } };
+ elementBuffer = result;
+ MBGL_CHECK_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
+ return result;
+}
+
+void Context::bindAttribute(const AttributeBinding& binding, std::size_t stride, const int8_t* offset) {
+ MBGL_CHECK_ERROR(glEnableVertexAttribArray(binding.location));
+ MBGL_CHECK_ERROR(glVertexAttribPointer(binding.location,
+ binding.count,
+ static_cast<GLenum>(binding.type),
+ false,
+ static_cast<GLsizei>(stride),
+ offset + binding.offset));
}
UniqueTexture Context::createTexture() {
@@ -120,10 +142,6 @@ UniqueFramebuffer Context::createFramebuffer() {
return UniqueFramebuffer{ std::move(id), { this } };
}
-void Context::uploadBuffer(BufferType type, size_t size, void* data) {
- MBGL_CHECK_ERROR(glBufferData(static_cast<GLenum>(type), size, data, GL_STATIC_DRAW));
-}
-
UniqueTexture
Context::createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit unit) {
auto obj = createTexture();
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index 0ec846033a..6a5d44793a 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -4,6 +4,9 @@
#include <mbgl/gl/state.hpp>
#include <mbgl/gl/value.hpp>
#include <mbgl/gl/texture.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/gl/attribute.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <memory>
@@ -22,12 +25,24 @@ public:
UniqueProgram createProgram();
UniqueShader createVertexShader();
UniqueShader createFragmentShader();
- UniqueBuffer createBuffer();
UniqueTexture createTexture();
UniqueVertexArray createVertexArray();
UniqueFramebuffer createFramebuffer();
- void uploadBuffer(BufferType, size_t, void*);
+ template <class V>
+ VertexBuffer<V> createVertexBuffer(std::vector<V>&& v) {
+ return VertexBuffer<V> {
+ v.size(),
+ createVertexBuffer(v.data(), v.size() * sizeof(V))
+ };
+ }
+
+ template <class P>
+ IndexBuffer<P> createIndexBuffer(std::vector<P>&& v) {
+ return IndexBuffer<P> {
+ createIndexBuffer(v.data(), v.size() * sizeof(P))
+ };
+ }
// Create a texture from an image with data.
template <typename Image>
@@ -46,6 +61,14 @@ public:
TextureFilter = TextureFilter::Nearest,
TextureMipMap = TextureMipMap::No);
+ template <class Shader, class Vertex>
+ void bindAttributes(const Shader& shader, const VertexBuffer<Vertex>&, const int8_t* offset) {
+ static_assert(std::is_same<typename Shader::VertexType, Vertex>::value, "vertex type mismatch");
+ for (const auto& binding : AttributeBindings<Shader, Vertex>()(shader)) {
+ bindAttribute(binding, sizeof(Vertex), offset);
+ }
+ }
+
// Actually remove the objects we marked as abandoned with the above methods.
// Only call this while the OpenGL context is exclusive to this thread.
void performCleanup();
@@ -98,9 +121,11 @@ public:
State<value::BindVertexArray> vertexArrayObject;
private:
+ UniqueBuffer createVertexBuffer(const void* data, std::size_t size);
+ UniqueBuffer createIndexBuffer(const void* data, std::size_t size);
UniqueTexture createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit);
+ void bindAttribute(const AttributeBinding&, std::size_t stride, const int8_t* offset);
-private:
friend detail::ProgramDeleter;
friend detail::ShaderDeleter;
friend detail::BufferDeleter;
diff --git a/src/mbgl/gl/index_buffer.hpp b/src/mbgl/gl/index_buffer.hpp
new file mode 100644
index 0000000000..f38d7fd4f5
--- /dev/null
+++ b/src/mbgl/gl/index_buffer.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <mbgl/gl/object.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class Line {
+public:
+ Line(uint16_t a_, uint16_t b_)
+ : a(a_), b(b_) {}
+
+ uint16_t a;
+ uint16_t b;
+
+ static constexpr std::size_t IndexCount = 2;
+};
+
+class Triangle {
+public:
+ Triangle(uint16_t a_, uint16_t b_, uint16_t c_)
+ : a(a_), b(b_), c(c_) {}
+
+ uint16_t a;
+ uint16_t b;
+ uint16_t c;
+
+ static constexpr std::size_t IndexCount = 3;
+};
+
+template <class Primitive>
+class IndexBuffer {
+public:
+ static_assert(std::is_same<Primitive, Line>::value || std::is_same<Primitive, Triangle>::value,
+ "primitive must be Line or Triangle");
+ static constexpr std::size_t primitiveSize = sizeof(Primitive);
+ UniqueBuffer buffer;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/gl/shader.cpp
index 1198300cec..d8ee734567 100644
--- a/src/mbgl/shader/shader.cpp
+++ b/src/mbgl/gl/shader.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/shader/shader.hpp>
+#include <mbgl/gl/shader.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/util/stopwatch.hpp>
@@ -15,11 +15,12 @@
#include <cassert>
namespace mbgl {
+namespace gl {
Shader::Shader(const char* name_,
const char* vertexSource,
const char* fragmentSource,
- gl::Context& context,
+ Context& context,
Defines defines)
: name(name_),
program(context.createProgram()),
@@ -47,13 +48,6 @@ Shader::Shader(const char* name_,
MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get()));
MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get()));
- // Bind attribute variables
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_pos, "a_pos"));
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_extrude, "a_extrude"));
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_offset, "a_offset"));
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_data, "a_data"));
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_texture_pos, "a_texture_pos"));
-
// Link program
GLint status;
MBGL_CHECK_ERROR(glLinkProgram(program.get()));
@@ -71,7 +65,7 @@ Shader::Shader(const char* name_,
}
}
-bool Shader::compileShader(gl::UniqueShader& shader, const GLchar *source) {
+bool Shader::compileShader(UniqueShader& shader, const GLchar *source) {
GLint status = 0;
const GLsizei lengths = static_cast<GLsizei>(std::strlen(source));
@@ -107,8 +101,13 @@ Shader::~Shader() {
}
}
-gl::UniformLocation Shader::getUniformLocation(const char* uniform) const {
+UniformLocation Shader::getUniformLocation(const char* uniform) const {
return MBGL_CHECK_ERROR(glGetUniformLocation(program.get(), uniform));
}
+AttributeLocation Shader::getAttributeLocation(const char* attribute) const {
+ return MBGL_CHECK_ERROR(glGetAttribLocation(program.get(), attribute));
+}
+
+} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/gl/shader.hpp b/src/mbgl/gl/shader.hpp
new file mode 100644
index 0000000000..f88bd4f867
--- /dev/null
+++ b/src/mbgl/gl/shader.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <mbgl/gl/types.hpp>
+#include <mbgl/gl/object.hpp>
+#include <mbgl/util/noncopyable.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class Context;
+
+class Shader : private util::noncopyable {
+public:
+ ~Shader();
+ const char* name;
+
+ ProgramID getID() const {
+ return program.get();
+ }
+
+ AttributeLocation getAttributeLocation(const char* uniform) const;
+ UniformLocation getUniformLocation(const char* uniform) const;
+
+ enum Defines : bool {
+ None = false,
+ Overdraw = true,
+ };
+
+protected:
+ Shader(const char* name_,
+ const char* vertex,
+ const char* fragment,
+ Context&,
+ Defines defines = Defines::None);
+
+private:
+ bool compileShader(UniqueShader&, const char *source);
+
+ UniqueProgram program;
+ UniqueShader vertexShader;
+ UniqueShader fragmentShader;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp
index e9d14e4807..f24674457a 100644
--- a/src/mbgl/gl/types.hpp
+++ b/src/mbgl/gl/types.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
+#include <type_traits>
namespace mbgl {
namespace gl {
@@ -22,6 +23,26 @@ using DepthValue = double;
using StencilValue = int32_t;
using StencilMaskValue = uint32_t;
+enum class DataType : uint32_t {
+ Byte = 0x1400,
+ UnsignedByte = 0x1401,
+ Short = 0x1402,
+ UnsignedShort = 0x1403,
+ Integer = 0x1404,
+ UnsignedInteger = 0x1405,
+ Float = 0x1406
+};
+
+template <typename T> struct DataTypeOf;
+
+template <> struct DataTypeOf<int8_t> : std::integral_constant<DataType, DataType::Byte> {};
+template <> struct DataTypeOf<uint8_t> : std::integral_constant<DataType, DataType::UnsignedByte> {};
+template <> struct DataTypeOf<int16_t> : std::integral_constant<DataType, DataType::Short> {};
+template <> struct DataTypeOf<uint16_t> : std::integral_constant<DataType, DataType::UnsignedShort> {};
+template <> struct DataTypeOf<int32_t> : std::integral_constant<DataType, DataType::Integer> {};
+template <> struct DataTypeOf<uint32_t> : std::integral_constant<DataType, DataType::UnsignedInteger> {};
+template <> struct DataTypeOf<float> : std::integral_constant<DataType, DataType::Float> {};
+
enum class BufferType : uint32_t {
Vertex = 0x8892,
Element = 0x8893
diff --git a/src/mbgl/shader/uniform.cpp b/src/mbgl/gl/uniform.cpp
index bd4c13eee1..07a27963d9 100644
--- a/src/mbgl/shader/uniform.cpp
+++ b/src/mbgl/gl/uniform.cpp
@@ -1,8 +1,9 @@
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
+#include <mbgl/gl/uniform.hpp>
#include <mbgl/gl/gl.hpp>
+#include <mbgl/util/color.hpp>
namespace mbgl {
+namespace gl {
template <>
void Uniform<float>::bind(const float& t) {
@@ -52,4 +53,5 @@ void UniformMatrix<4>::bind(const std::array<float, 16>& t) {
// Add more as needed.
+} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/shader/uniform.hpp b/src/mbgl/gl/uniform.hpp
index 5df6942ff6..5af781043d 100644
--- a/src/mbgl/shader/uniform.hpp
+++ b/src/mbgl/gl/uniform.hpp
@@ -1,10 +1,11 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
+#include <mbgl/gl/shader.hpp>
#include <array>
namespace mbgl {
+namespace gl {
template <typename T>
class Uniform {
@@ -24,7 +25,7 @@ private:
void bind(const T&);
T current;
- gl::UniformLocation location;
+ UniformLocation location;
};
template <size_t C, size_t R = C>
@@ -53,7 +54,8 @@ private:
void bind(const T&);
T current;
- gl::UniformLocation location;
+ UniformLocation location;
};
+} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/geometry/vao.cpp b/src/mbgl/gl/vao.cpp
index 2c5e1677ff..b235b0e63b 100644
--- a/src/mbgl/geometry/vao.cpp
+++ b/src/mbgl/gl/vao.cpp
@@ -1,18 +1,14 @@
-#include <mbgl/geometry/vao.hpp>
+#include <mbgl/gl/vao.hpp>
#include <mbgl/gl/vertex_array.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/gl/gl.hpp>
namespace mbgl {
+namespace gl {
-VertexArrayObject::VertexArrayObject() {
-}
-
-VertexArrayObject::~VertexArrayObject() = default;
-
-void VertexArrayObject::bindVertexArrayObject(gl::Context& context) {
- if (!gl::GenVertexArrays || !gl::BindVertexArray) {
+void VertexArrayObject::bindVertexArrayObject(Context& context) {
+ if (!GenVertexArrays || !BindVertexArray) {
static bool reported = false;
if (!reported) {
Log::Warning(Event::OpenGL, "Not using Vertex Array Objects");
@@ -31,8 +27,8 @@ void VertexArrayObject::bindVertexArrayObject(gl::Context& context) {
}
void VertexArrayObject::verifyBinding(Shader& shader,
- gl::BufferID vertexBuffer,
- gl::BufferID elementsBuffer,
+ BufferID vertexBuffer,
+ BufferID elementsBuffer,
int8_t* offset) {
if (bound_shader != shader.getID()) {
throw std::runtime_error(std::string("trying to rebind VAO to another shader from " +
@@ -48,8 +44,8 @@ void VertexArrayObject::verifyBinding(Shader& shader,
}
void VertexArrayObject::storeBinding(Shader& shader,
- gl::BufferID vertexBuffer,
- gl::BufferID elementsBuffer,
+ BufferID vertexBuffer,
+ BufferID elementsBuffer,
int8_t* offset) {
bound_shader = shader.getID();
bound_shader_name = shader.name;
@@ -58,4 +54,5 @@ void VertexArrayObject::storeBinding(Shader& shader,
bound_elements_buffer = elementsBuffer;
}
+} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/gl/vao.hpp b/src/mbgl/gl/vao.hpp
new file mode 100644
index 0000000000..826c028d32
--- /dev/null
+++ b/src/mbgl/gl/vao.hpp
@@ -0,0 +1,78 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/util/optional.hpp>
+
+#include <stdexcept>
+
+namespace mbgl {
+namespace gl {
+
+class VertexArrayObject {
+public:
+ template <typename Shader, typename T>
+ void bind(Shader& shader,
+ const VertexBuffer<T>& vertexBuffer,
+ int8_t* offset,
+ Context& context) {
+ bindVertexArrayObject(context);
+ if (bound_shader == 0) {
+ context.vertexBuffer = vertexBuffer.buffer;
+ context.bindAttributes(shader, vertexBuffer, offset);
+ if (vertexArray) {
+ storeBinding(shader, vertexBuffer.buffer, 0, offset);
+ }
+ } else {
+ verifyBinding(shader, vertexBuffer.buffer, 0, offset);
+ }
+ }
+
+ template <typename Shader, typename T, typename P>
+ void bind(Shader& shader,
+ const VertexBuffer<T>& vertexBuffer,
+ const IndexBuffer<P>& indexBuffer,
+ int8_t* offset,
+ Context& context) {
+ bindVertexArrayObject(context);
+ if (bound_shader == 0) {
+ context.vertexBuffer = vertexBuffer.buffer;
+ context.elementBuffer = indexBuffer.buffer;
+ context.bindAttributes(shader, vertexBuffer, offset);
+ if (vertexArray) {
+ storeBinding(shader, vertexBuffer.buffer, indexBuffer.buffer, offset);
+ }
+ } else {
+ verifyBinding(shader, vertexBuffer.buffer, indexBuffer.buffer, offset);
+ }
+ }
+
+ VertexArrayID getID() const {
+ return *vertexArray;
+ }
+
+private:
+ void bindVertexArrayObject(Context&);
+ void storeBinding(Shader& shader,
+ BufferID vertexBuffer,
+ BufferID elementsBuffer,
+ int8_t* offset);
+ void verifyBinding(Shader& shader,
+ BufferID vertexBuffer,
+ BufferID elementsBuffer,
+ int8_t* offset);
+
+ optional<UniqueVertexArray> vertexArray;
+
+ // For debug reasons, we're storing the bind information so that we can
+ // detect errors and report
+ ProgramID bound_shader = 0;
+ const char* bound_shader_name = "";
+ BufferID bound_vertex_buffer = 0;
+ BufferID bound_elements_buffer = 0;
+ int8_t *bound_offset = nullptr;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/vertex_buffer.hpp b/src/mbgl/gl/vertex_buffer.hpp
new file mode 100644
index 0000000000..c77a9a4213
--- /dev/null
+++ b/src/mbgl/gl/vertex_buffer.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <mbgl/gl/object.hpp>
+
+namespace mbgl {
+namespace gl {
+
+template <class Vertex>
+class VertexBuffer {
+public:
+ static constexpr std::size_t vertexSize = sizeof(Vertex);
+ std::size_t vertexCount;
+ UniqueBuffer buffer;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index fdd66095fe..07ba2bf4a3 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -8,12 +8,14 @@
#include <mbgl/text/get_anchors.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/text/collision_tile.hpp>
+#include <mbgl/util/constants.hpp>
#include <mbgl/util/utf.hpp>
#include <mbgl/util/token.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
+#include <mbgl/math/clamp.hpp>
#include <mbgl/math/minmax.hpp>
#include <mbgl/platform/platform.hpp>
#include <mbgl/platform/log.hpp>
@@ -53,8 +55,8 @@ SymbolLayout::SymbolLayout(std::string bucketName_,
auto layerName = layer.getName();
// Determine and load glyph ranges
- const size_t featureCount = static_cast<size_t>(layer.featureCount());
- for (size_t i = 0; i < featureCount; i++) {
+ const size_t featureCount = layer.featureCount();
+ for (size_t i = 0; i < featureCount; ++i) {
auto feature = layer.getFeature(i);
if (!filter(feature->getType(), feature->getID(), [&] (const auto& key) { return feature->getValue(key); }))
continue;
@@ -391,7 +393,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
if (hasText) {
collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale, layout.textIgnorePlacement);
if (glyphScale < collisionTile.maxScale) {
- addSymbols<SymbolBucket::TextBuffer, SymbolBucket::TextElementGroup>(
+ addSymbols(
bucket->text, symbolInstance.glyphQuads, glyphScale,
layout.textKeepUpright, textPlacement, collisionTile.config.angle);
}
@@ -400,7 +402,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
if (hasIcon) {
collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.iconIgnorePlacement);
if (iconScale < collisionTile.maxScale) {
- addSymbols<SymbolBucket::IconBuffer, SymbolBucket::IconElementGroup>(
+ addSymbols(
bucket->icon, symbolInstance.iconQuads, iconScale,
layout.iconKeepUpright, iconPlacement, collisionTile.config.angle);
}
@@ -414,7 +416,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
return bucket;
}
-template <typename Buffer, typename GroupType>
+template <typename Buffer>
void SymbolLayout::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float scale, const bool keepUpright, const style::SymbolPlacementType placement, const float placementAngle) {
const float placementZoom = ::fmax(std::log(scale) / std::log(2) + zoom, 0);
@@ -449,53 +451,58 @@ void SymbolLayout::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
const int glyph_vertex_length = 4;
- if (buffer.groups.empty() || (buffer.groups.back()->vertex_length + glyph_vertex_length > 65535)) {
+ if (buffer.groups.empty() || buffer.groups.back().vertexLength + glyph_vertex_length > 65535) {
// Move to a new group because the old one can't hold the geometry.
- buffer.groups.emplace_back(std::make_unique<GroupType>());
+ buffer.groups.emplace_back();
}
// We're generating triangle fans, so we always start with the first
// coordinate in this polygon.
- assert(buffer.groups.back());
- auto &triangleGroup = *buffer.groups.back();
- size_t triangleIndex = triangleGroup.vertex_length;
+ auto& group = buffer.groups.back();
+ size_t index = group.vertexLength;
// Encode angle of glyph
uint8_t glyphAngle = std::round((symbol.glyphAngle / (M_PI * 2)) * 256);
// coordinates (2 triangles)
- buffer.vertices.add(anchorPoint.x, anchorPoint.y, tl.x, tl.y, tex.x, tex.y, minZoom,
+ buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, tl.x, tl.y, tex.x, tex.y, minZoom,
maxZoom, placementZoom, glyphAngle);
- buffer.vertices.add(anchorPoint.x, anchorPoint.y, tr.x, tr.y, tex.x + tex.w, tex.y,
+ buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, tr.x, tr.y, tex.x + tex.w, tex.y,
minZoom, maxZoom, placementZoom, glyphAngle);
- buffer.vertices.add(anchorPoint.x, anchorPoint.y, bl.x, bl.y, tex.x, tex.y + tex.h,
+ buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, bl.x, bl.y, tex.x, tex.y + tex.h,
minZoom, maxZoom, placementZoom, glyphAngle);
- buffer.vertices.add(anchorPoint.x, anchorPoint.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h,
+ buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h,
minZoom, maxZoom, placementZoom, glyphAngle);
// add the two triangles, referencing the four coordinates we just inserted.
- buffer.triangles.add(triangleIndex + 0, triangleIndex + 1, triangleIndex + 2);
- buffer.triangles.add(triangleIndex + 1, triangleIndex + 2, triangleIndex + 3);
-
- triangleGroup.vertex_length += glyph_vertex_length;
- triangleGroup.elements_length += 2;
+ buffer.triangles.emplace_back(static_cast<uint16_t>(index + 0),
+ static_cast<uint16_t>(index + 1),
+ static_cast<uint16_t>(index + 2));
+ buffer.triangles.emplace_back(static_cast<uint16_t>(index + 1),
+ static_cast<uint16_t>(index + 2),
+ static_cast<uint16_t>(index + 3));
+
+ group.vertexLength += glyph_vertex_length;
+ group.indexLength += 2;
}
}
void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket& bucket) {
+ if (!hasSymbolInstances()) {
+ return;
+ }
+
const float yStretch = collisionTile.yStretch;
- const float angle = collisionTile.config.angle;
- 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;
+ auto& collisionBox = bucket.collisionBox;
+ if (collisionBox.groups.empty()) {
+ // Move to a new group because the old one can't hold the geometry.
+ collisionBox.groups.emplace_back();
+ }
+ for (const SymbolInstance &symbolInstance : symbolInstances) {
+ auto populateCollisionBox = [&](const auto& feature) {
for (const CollisionBox &box : feature.boxes) {
auto& anchor = box.anchor;
@@ -503,33 +510,29 @@ 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(matrix, tl);
- tr = util::matrixMultiply(matrix, tr);
- bl = util::matrixMultiply(matrix, bl);
- br = util::matrixMultiply(matrix, br);
-
- 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))));
-
- auto& collisionBox = bucket.collisionBox;
- if (collisionBox.groups.empty()) {
- // Move to a new group because the old one can't hold the geometry.
- collisionBox.groups.emplace_back(std::make_unique<SymbolBucket::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;
+ 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 + log(box.maxScale) / log(2), util::MIN_ZOOM, util::MAX_ZOOM);
+ const float placementZoom = util::clamp(zoom + log(box.placementScale) / log(2), util::MIN_ZOOM, util::MAX_ZOOM);
+
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, tl.x, tl.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, tr.x, tr.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, tr.x, tr.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, br.x, br.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, br.x, br.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, bl.x, bl.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, bl.x, bl.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, tl.x, tl.y, maxZoom, placementZoom);
+
+ auto& group = collisionBox.groups.back();
+ group.vertexLength += 8;
}
- }
+ };
+ populateCollisionBox(symbolInstance.textCollisionFeature);
+ populateCollisionBox(symbolInstance.iconCollisionFeature);
}
}
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index c4e6455794..54acf84aaf 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -70,7 +70,7 @@ private:
void addToDebugBuffers(CollisionTile&, SymbolBucket&);
// Adds placed items to the buffer.
- template <typename Buffer, typename GroupType>
+ template <typename Buffer>
void addSymbols(Buffer&, const SymbolQuads&, float scale,
const bool keepUpright, const style::SymbolPlacementType, const float placementAngle);
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index e04f7f3900..bf2462e2ab 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -22,6 +22,7 @@
#include <mbgl/util/mapbox.hpp>
#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/actor/thread_pool.hpp>
+#include <mbgl/platform/log.hpp>
namespace mbgl {
@@ -421,7 +422,7 @@ void Map::moveBy(const ScreenCoordinate& point, const Duration& duration) {
}
void Map::setLatLng(const LatLng& latLng, const Duration& duration) {
- setLatLng(latLng, ScreenCoordinate {}, duration);
+ setLatLng(latLng, optional<ScreenCoordinate> {}, duration);
}
void Map::setLatLng(const LatLng& latLng, optional<EdgeInsets> padding, const Duration& duration) {
@@ -749,13 +750,15 @@ std::vector<Feature> Map::queryRenderedFeatures(const ScreenBox& box, const opti
AnnotationIDs Map::queryPointAnnotations(const ScreenBox& box) {
auto features = queryRenderedFeatures(box, {{ AnnotationManager::PointLayerID }});
- AnnotationIDs ids;
- ids.reserve(features.size());
+ std::set<AnnotationID> set;
for (auto &feature : features) {
assert(feature.id);
assert(*feature.id <= std::numeric_limits<AnnotationID>::max());
- ids.push_back(static_cast<AnnotationID>(feature.id->get<uint64_t>()));
+ set.insert(static_cast<AnnotationID>(feature.id->get<uint64_t>()));
}
+ AnnotationIDs ids;
+ ids.reserve(set.size());
+ std::move(set.begin(), set.end(), std::back_inserter(ids));
return ids;
}
diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp
index 7b10fafc93..f12139d004 100644
--- a/src/mbgl/renderer/circle_bucket.cpp
+++ b/src/mbgl/renderer/circle_bucket.cpp
@@ -18,8 +18,8 @@ CircleBucket::~CircleBucket() {
}
void CircleBucket::upload(gl::Context& context) {
- vertexBuffer_.upload(context);
- elementsBuffer_.upload(context);
+ vertexBuffer = context.createVertexBuffer(std::move(vertices));
+ indexBuffer = context.createIndexBuffer(std::move(triangles));
uploaded = true;
}
@@ -31,7 +31,7 @@ void CircleBucket::render(Painter& painter,
}
bool CircleBucket::hasData() const {
- return !triangleGroups_.empty();
+ return !groups.empty();
}
bool CircleBucket::needsClipping() const {
@@ -59,45 +59,47 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) {
// │ 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
+ vertices.emplace_back(x, y, -1, -1); // 1
+ vertices.emplace_back(x, y, 1, -1); // 2
+ vertices.emplace_back(x, y, 1, 1); // 3
+ vertices.emplace_back(x, y, -1, 1); // 4
- if (!triangleGroups_.size() || (triangleGroups_.back()->vertex_length + 4 > 65535)) {
+ if (!groups.size() || groups.back().vertexLength + 4 > 65535) {
// Move to a new group because the old one can't hold the geometry.
- triangleGroups_.emplace_back(std::make_unique<TriangleGroup>());
+ groups.emplace_back();
}
- TriangleGroup& group = *triangleGroups_.back();
- auto index = group.vertex_length;
+ auto& group = groups.back();
+ uint16_t index = group.vertexLength;
// 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;
+ triangles.emplace_back(index,
+ static_cast<uint16_t>(index + 1),
+ static_cast<uint16_t>(index + 2));
+ triangles.emplace_back(index,
+ static_cast<uint16_t>(index + 3),
+ static_cast<uint16_t>(index + 2));
+
+ group.vertexLength += 4;
+ group.indexLength += 2;
}
}
}
-void CircleBucket::drawCircles(CircleShader& shader, gl::Context& context) {
+void CircleBucket::drawCircles(CircleShader& shader, gl::Context& context, PaintMode paintMode) {
GLbyte* vertexIndex = BUFFER_OFFSET(0);
GLbyte* elementsIndex = BUFFER_OFFSET(0);
- for (auto& group : triangleGroups_) {
- assert(group);
-
- if (!group->elements_length) continue;
+ for (auto& group : groups) {
+ if (!group.indexLength) continue;
- group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex, context);
+ group.getVAO(shader, paintMode).bind(shader, *vertexBuffer, *indexBuffer, vertexIndex, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elementsIndex));
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT, elementsIndex));
- vertexIndex += group->vertex_length * vertexBuffer_.itemSize;
- elementsIndex += group->elements_length * elementsBuffer_.itemSize;
+ vertexIndex += group.vertexLength * vertexBuffer->vertexSize;
+ elementsIndex += group.indexLength * indexBuffer->primitiveSize;
}
}
diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp
index 9e9357d77f..2f3faccdec 100644
--- a/src/mbgl/renderer/circle_bucket.hpp
+++ b/src/mbgl/renderer/circle_bucket.hpp
@@ -1,19 +1,18 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/renderer/element_group.hpp>
#include <mbgl/map/mode.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
-#include <mbgl/geometry/elements_buffer.hpp>
-#include <mbgl/geometry/circle_buffer.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/shader/circle_vertex.hpp>
namespace mbgl {
-class CircleVertexBuffer;
class CircleShader;
class CircleBucket : public Bucket {
- using TriangleGroup = ElementGroup<3>;
-
public:
CircleBucket(const MapMode);
~CircleBucket() override;
@@ -25,13 +24,16 @@ public:
bool needsClipping() const override;
void addGeometry(const GeometryCollection&);
- void drawCircles(CircleShader&, gl::Context&);
+ void drawCircles(CircleShader&, gl::Context&, PaintMode);
private:
- CircleVertexBuffer vertexBuffer_;
- TriangleElementsBuffer elementsBuffer_;
+ std::vector<CircleVertex> vertices;
+ std::vector<gl::Triangle> triangles;
+
+ std::vector<ElementGroup<CircleShader>> groups;
- std::vector<std::unique_ptr<TriangleGroup>> triangleGroups_;
+ optional<gl::VertexBuffer<CircleVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
const MapMode mode;
};
diff --git a/src/mbgl/renderer/debug_bucket.cpp b/src/mbgl/renderer/debug_bucket.cpp
index 249924abb7..c47ae434be 100644
--- a/src/mbgl/renderer/debug_bucket.cpp
+++ b/src/mbgl/renderer/debug_bucket.cpp
@@ -1,54 +1,101 @@
#include <mbgl/renderer/debug_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/shader/plain_shader.hpp>
+#include <mbgl/shader/fill_shader.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+#include <mbgl/geometry/debug_font_data.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/gl/gl.hpp>
-#include <cassert>
+#include <cmath>
#include <string>
+#include <vector>
namespace mbgl {
-DebugBucket::DebugBucket(const OverscaledTileID& id,
- const bool renderable_,
- const bool complete_,
- optional<Timestamp> modified_,
- optional<Timestamp> expires_,
- MapDebugOptions debugMode_)
- : renderable(renderable_),
- complete(complete_),
- modified(std::move(modified_)),
- expires(std::move(expires_)),
- debugMode(debugMode_) {
+std::vector<FillVertex> buildTextVertices(const OverscaledTileID& id,
+ const bool renderable,
+ const bool complete,
+ optional<Timestamp> modified,
+ optional<Timestamp> expires,
+ MapDebugOptions debugMode) {
+ std::vector<FillVertex> textPoints;
+
+ auto addText = [&] (const std::string& text, double left, double baseline, double scale) {
+ for (uint8_t c : text) {
+ if (c < 32 || c >= 127)
+ continue;
+
+ optional<Point<int16_t>> prev;
+
+ const glyph& glyph = simplex[c - 32];
+ for (int32_t j = 0; j < glyph.length; j += 2) {
+ if (glyph.data[j] == -1 && glyph.data[j + 1] == -1) {
+ prev = {};
+ } else {
+ Point<int16_t> p {
+ int16_t(::round(left + glyph.data[j] * scale)),
+ int16_t(::round(baseline - glyph.data[j + 1] * scale))
+ };
+
+ if (prev) {
+ textPoints.emplace_back(prev->x, prev->y);
+ textPoints.emplace_back(p.x, p.y);
+ }
+
+ prev = p;
+ }
+ }
+
+ left += glyph.width * scale;
+ }
+ };
+
double baseline = 200;
if (debugMode & MapDebugOptions::ParseStatus) {
const std::string text = util::toString(id) + " - " +
(complete ? "complete" : renderable ? "renderable" : "pending");
- fontBuffer.addText(text.c_str(), 50, baseline, 5);
+ addText(text, 50, baseline, 5);
baseline += 200;
}
if (debugMode & MapDebugOptions::Timestamps && modified && expires) {
const std::string modifiedText = "modified: " + util::iso8601(*modified);
- fontBuffer.addText(modifiedText.c_str(), 50, baseline, 5);
+ addText(modifiedText, 50, baseline, 5);
const std::string expiresText = "expires: " + util::iso8601(*expires);
- fontBuffer.addText(expiresText.c_str(), 50, baseline + 200, 5);
+ addText(expiresText, 50, baseline + 200, 5);
}
+
+ return textPoints;
+}
+
+DebugBucket::DebugBucket(const OverscaledTileID& id,
+ const bool renderable_,
+ const bool complete_,
+ optional<Timestamp> modified_,
+ optional<Timestamp> expires_,
+ MapDebugOptions debugMode_,
+ gl::Context& context)
+ : renderable(renderable_),
+ complete(complete_),
+ modified(std::move(modified_)),
+ expires(std::move(expires_)),
+ debugMode(debugMode_),
+ vertexBuffer(context.createVertexBuffer(buildTextVertices(id, renderable_, complete_, modified_, expires_, debugMode_))) {
}
-void DebugBucket::drawLines(PlainShader& shader, gl::Context& context) {
- if (!fontBuffer.empty()) {
- array.bind(shader, fontBuffer, BUFFER_OFFSET_0, context);
- MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, (GLsizei)(fontBuffer.index())));
+void DebugBucket::drawLines(FillShader& shader, gl::Context& context) {
+ if (vertexBuffer.vertexCount != 0) {
+ array.bind(shader, vertexBuffer, BUFFER_OFFSET_0, context);
+ MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(vertexBuffer.vertexCount)));
}
}
-void DebugBucket::drawPoints(PlainShader& shader, gl::Context& context) {
- if (!fontBuffer.empty()) {
- array.bind(shader, fontBuffer, BUFFER_OFFSET_0, context);
- MBGL_CHECK_ERROR(glDrawArrays(GL_POINTS, 0, (GLsizei)(fontBuffer.index())));
+void DebugBucket::drawPoints(FillShader& shader, gl::Context& context) {
+ if (vertexBuffer.vertexCount != 0) {
+ array.bind(shader, vertexBuffer, BUFFER_OFFSET_0, context);
+ MBGL_CHECK_ERROR(glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(vertexBuffer.vertexCount)));
}
}
diff --git a/src/mbgl/renderer/debug_bucket.hpp b/src/mbgl/renderer/debug_bucket.hpp
index 51315967da..89087f0010 100644
--- a/src/mbgl/renderer/debug_bucket.hpp
+++ b/src/mbgl/renderer/debug_bucket.hpp
@@ -1,14 +1,18 @@
#pragma once
#include <mbgl/map/mode.hpp>
-#include <mbgl/geometry/debug_font_buffer.hpp>
-#include <mbgl/geometry/vao.hpp>
#include <mbgl/util/chrono.hpp>
+#include <mbgl/util/geometry.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/vao.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
namespace mbgl {
class OverscaledTileID;
-class PlainShader;
+class FillShader;
namespace gl {
class Context;
@@ -21,10 +25,11 @@ public:
bool complete,
optional<Timestamp> modified,
optional<Timestamp> expires,
- MapDebugOptions);
+ MapDebugOptions,
+ gl::Context&);
- void drawLines(PlainShader&, gl::Context&);
- void drawPoints(PlainShader&, gl::Context&);
+ void drawLines(FillShader&, gl::Context&);
+ void drawPoints(FillShader&, gl::Context&);
const bool renderable;
const bool complete;
@@ -33,8 +38,8 @@ public:
const MapDebugOptions debugMode;
private:
- DebugFontBuffer fontBuffer;
- VertexArrayObject array;
+ gl::VertexBuffer<FillVertex> vertexBuffer;
+ gl::VertexArrayObject array;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/element_group.hpp b/src/mbgl/renderer/element_group.hpp
new file mode 100644
index 0000000000..59b5c3068d
--- /dev/null
+++ b/src/mbgl/renderer/element_group.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <mbgl/gl/vao.hpp>
+#include <mbgl/renderer/render_pass.hpp>
+
+namespace mbgl {
+
+template <class... Shaders>
+struct ElementGroup {
+ template <class Shader>
+ struct VAOs {
+ gl::VertexArrayObject normalVAO;
+ gl::VertexArrayObject overdrawVAO;
+ };
+
+ std::tuple<VAOs<Shaders>...> vaos;
+
+ template <class Shader>
+ gl::VertexArrayObject& getVAO(const Shader&, PaintMode paintMode) {
+ auto& vao = std::get<VAOs<Shader>>(vaos);
+ return paintMode == PaintMode::Overdraw ? vao.overdrawVAO : vao.normalVAO;
+ }
+
+ std::size_t vertexLength = 0;
+ std::size_t indexLength = 0;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp
index d07fe5c725..cd4277cabc 100644
--- a/src/mbgl/renderer/fill_bucket.cpp
+++ b/src/mbgl/renderer/fill_bucket.cpp
@@ -1,10 +1,10 @@
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/shader/plain_shader.hpp>
-#include <mbgl/shader/pattern_shader.hpp>
-#include <mbgl/shader/outline_shader.hpp>
-#include <mbgl/shader/outlinepattern_shader.hpp>
+#include <mbgl/shader/fill_shader.hpp>
+#include <mbgl/shader/fill_pattern_shader.hpp>
+#include <mbgl/shader/fill_outline_shader.hpp>
+#include <mbgl/shader/fill_outline_pattern_shader.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/platform/log.hpp>
@@ -54,22 +54,24 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
if (nVertices == 0)
continue;
- if (lineGroups.empty() || lineGroups.back()->vertex_length + nVertices > 65535)
- lineGroups.emplace_back(std::make_unique<LineGroup>());
+ if (lineGroups.empty() || lineGroups.back().vertexLength + nVertices > 65535)
+ lineGroups.emplace_back();
- LineGroup& lineGroup = *lineGroups.back();
- GLsizei lineIndex = lineGroup.vertex_length;
+ auto& lineGroup = lineGroups.back();
+ uint16_t lineIndex = lineGroup.vertexLength;
- vertexBuffer.add(ring[0].x, ring[0].y);
- lineElementsBuffer.add(lineIndex + nVertices - 1, lineIndex);
+ vertices.emplace_back(ring[0].x, ring[0].y);
+ lines.emplace_back(static_cast<uint16_t>(lineIndex + nVertices - 1),
+ static_cast<uint16_t>(lineIndex));
for (uint32_t i = 1; i < nVertices; i++) {
- vertexBuffer.add(ring[i].x, ring[i].y);
- lineElementsBuffer.add(lineIndex + i - 1, lineIndex + i);
+ vertices.emplace_back(ring[i].x, ring[i].y);
+ lines.emplace_back(static_cast<uint16_t>(lineIndex + i - 1),
+ static_cast<uint16_t>(lineIndex + i));
}
- lineGroup.vertex_length += nVertices;
- lineGroup.elements_length += nVertices;
+ lineGroup.vertexLength += nVertices;
+ lineGroup.indexLength += nVertices;
}
std::vector<uint32_t> indices = mapbox::earcut(polygon);
@@ -77,28 +79,28 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
std::size_t nIndicies = indices.size();
assert(nIndicies % 3 == 0);
- if (triangleGroups.empty() || triangleGroups.back()->vertex_length + totalVertices > 65535) {
- triangleGroups.emplace_back(std::make_unique<TriangleGroup>());
+ if (triangleGroups.empty() || triangleGroups.back().vertexLength + totalVertices > 65535) {
+ triangleGroups.emplace_back();
}
- TriangleGroup& triangleGroup = *triangleGroups.back();
- GLsizei triangleIndex = triangleGroup.vertex_length;
+ auto& triangleGroup = triangleGroups.back();
+ uint16_t triangleIndex = triangleGroup.vertexLength;
for (uint32_t i = 0; i < nIndicies; i += 3) {
- triangleElementsBuffer.add(triangleIndex + indices[i],
- triangleIndex + indices[i + 1],
- triangleIndex + indices[i + 2]);
+ triangles.emplace_back(static_cast<uint16_t>(triangleIndex + indices[i]),
+ static_cast<uint16_t>(triangleIndex + indices[i + 1]),
+ static_cast<uint16_t>(triangleIndex + indices[i + 2]));
}
- triangleGroup.vertex_length += totalVertices;
- triangleGroup.elements_length += nIndicies / 3;
+ triangleGroup.vertexLength += totalVertices;
+ triangleGroup.indexLength += nIndicies / 3;
}
}
void FillBucket::upload(gl::Context& context) {
- vertexBuffer.upload(context);
- triangleElementsBuffer.upload(context);
- lineElementsBuffer.upload(context);
+ vertexBuffer = context.createVertexBuffer(std::move(vertices));
+ lineIndexBuffer = context.createIndexBuffer(std::move(lines));
+ triangleIndexBuffer = context.createIndexBuffer(std::move(triangles));
// From now on, we're going to render during the opaque and translucent pass.
uploaded = true;
@@ -119,67 +121,63 @@ bool FillBucket::needsClipping() const {
return true;
}
-void FillBucket::drawElements(PlainShader& shader,
+void FillBucket::drawElements(FillShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *triangleIndexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * triangleIndexBuffer->primitiveSize;
}
}
-void FillBucket::drawElements(PatternShader& shader,
+void FillBucket::drawElements(FillPatternShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *triangleIndexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * triangleIndexBuffer->primitiveSize;
}
}
-void FillBucket::drawVertices(OutlineShader& shader,
+void FillBucket::drawVertices(FillOutlineShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : lineGroups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, vertexBuffer, lineElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *lineIndexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_LINES, static_cast<GLsizei>(group.indexLength * 2), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * lineElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * lineIndexBuffer->primitiveSize;
}
}
-void FillBucket::drawVertices(OutlinePatternShader& shader,
+void FillBucket::drawVertices(FillOutlinePatternShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : lineGroups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind(
- shader, vertexBuffer, lineElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *lineIndexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_LINES, static_cast<GLsizei>(group.indexLength * 2), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * lineElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * lineIndexBuffer->primitiveSize;
}
}
diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp
index 2e6d390bfe..34cd886687 100644
--- a/src/mbgl/renderer/fill_bucket.hpp
+++ b/src/mbgl/renderer/fill_bucket.hpp
@@ -1,19 +1,21 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/renderer/element_group.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
-#include <mbgl/geometry/elements_buffer.hpp>
-#include <mbgl/geometry/fill_buffer.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
#include <vector>
#include <memory>
namespace mbgl {
-class OutlinePatternShader;
-class PlainShader;
-class PatternShader;
-class OutlineShader;
+class FillShader;
+class FillPatternShader;
+class FillOutlineShader;
+class FillOutlinePatternShader;
class FillBucket : public Bucket {
public:
@@ -27,21 +29,22 @@ public:
void addGeometry(const GeometryCollection&);
- void drawElements(PlainShader&, gl::Context&, PaintMode);
- void drawElements(PatternShader&, gl::Context&, PaintMode);
- void drawVertices(OutlineShader&, gl::Context&, PaintMode);
- void drawVertices(OutlinePatternShader&, gl::Context&, PaintMode);
+ void drawElements(FillShader&, gl::Context&, PaintMode);
+ void drawElements(FillPatternShader&, gl::Context&, PaintMode);
+ void drawVertices(FillOutlineShader&, gl::Context&, PaintMode);
+ void drawVertices(FillOutlinePatternShader&, gl::Context&, PaintMode);
private:
- FillVertexBuffer vertexBuffer;
- TriangleElementsBuffer triangleElementsBuffer;
- LineElementsBuffer lineElementsBuffer;
+ std::vector<FillVertex> vertices;
+ std::vector<gl::Line> lines;
+ std::vector<gl::Triangle> triangles;
- typedef ElementGroup<4> TriangleGroup;
- typedef ElementGroup<4> LineGroup;
+ std::vector<ElementGroup<FillOutlineShader, FillOutlinePatternShader>> lineGroups;
+ std::vector<ElementGroup<FillShader, FillPatternShader>> triangleGroups;
- std::vector<std::unique_ptr<TriangleGroup>> triangleGroups;
- std::vector<std::unique_ptr<LineGroup>> lineGroups;
+ optional<gl::VertexBuffer<FillVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Line>> lineIndexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> triangleIndexBuffer;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index 17a92ad3d8..7a5309bafc 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -1,10 +1,9 @@
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/style/layers/line_layer.hpp>
-#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/shader/line_shader.hpp>
-#include <mbgl/shader/linesdf_shader.hpp>
-#include <mbgl/shader/linepattern_shader.hpp>
+#include <mbgl/shader/line_sdf_shader.hpp>
+#include <mbgl/shader/line_pattern_shader.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/gl/gl.hpp>
@@ -54,11 +53,11 @@ 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());
+void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
+ const GLsizei len = [&coordinates] {
+ GLsizei l = static_cast<GLsizei>(coordinates.size());
// If the line has duplicate vertices at the end, adjust length to remove them.
- while (l > 2 && vertices[l - 1] == vertices[l - 2]) {
+ while (l > 2 && coordinates[l - 1] == coordinates[l - 2]) {
l--;
}
return l;
@@ -73,9 +72,9 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling));
- const GeometryCoordinate firstVertex = vertices.front();
- const GeometryCoordinate lastVertex = vertices[len - 1];
- const bool closed = firstVertex == lastVertex;
+ const GeometryCoordinate firstCoordinate = coordinates.front();
+ const GeometryCoordinate lastCoordinate = coordinates[len - 1];
+ const bool closed = firstCoordinate == lastCoordinate;
if (len == 2 && closed) {
// fprintf(stderr, "a line may not have coincident points\n");
@@ -87,9 +86,9 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
double distance = 0;
bool startOfLine = true;
- optional<GeometryCoordinate> currentVertex;
- optional<GeometryCoordinate> prevVertex;
- optional<GeometryCoordinate> nextVertex;
+ optional<GeometryCoordinate> currentCoordinate;
+ optional<GeometryCoordinate> prevCoordinate;
+ optional<GeometryCoordinate> nextCoordinate;
optional<Point<double>> prevNormal;
optional<Point<double>> nextNormal;
@@ -97,43 +96,43 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
e1 = e2 = e3 = -1;
if (closed) {
- currentVertex = vertices[len - 2];
- nextNormal = util::perp(util::unit(convertPoint<double>(firstVertex - *currentVertex)));
+ currentCoordinate = coordinates[len - 2];
+ nextNormal = util::perp(util::unit(convertPoint<double>(firstCoordinate - *currentCoordinate)));
}
- const int32_t startVertex = vertexBuffer.index();
+ const std::size_t startVertex = vertices.size();
std::vector<TriangleElement> triangleStore;
for (GLsizei i = 0; i < len; ++i) {
if (closed && i == len - 1) {
// if the line is closed, we treat the last vertex like the first
- nextVertex = vertices[1];
+ nextCoordinate = coordinates[1];
} else if (i + 1 < len) {
// just the next vertex
- nextVertex = vertices[i + 1];
+ nextCoordinate = coordinates[i + 1];
} else {
// there is no next vertex
- nextVertex = {};
+ nextCoordinate = {};
}
// if two consecutive vertices exist, skip the current one
- if (nextVertex && vertices[i] == *nextVertex) {
+ if (nextCoordinate && coordinates[i] == *nextCoordinate) {
continue;
}
if (nextNormal) {
prevNormal = *nextNormal;
}
- if (currentVertex) {
- prevVertex = *currentVertex;
+ if (currentCoordinate) {
+ prevCoordinate = *currentCoordinate;
}
- currentVertex = vertices[i];
+ currentCoordinate = coordinates[i];
// Calculate the normal towards the next vertex in this line. In case
// there is no next vertex, pretend that the line is continuing straight,
// meaning that we are just using the previous normal.
- nextNormal = nextVertex ? util::perp(util::unit(convertPoint<double>(*nextVertex - *currentVertex)))
+ nextNormal = nextCoordinate ? util::perp(util::unit(convertPoint<double>(*nextCoordinate - *currentCoordinate)))
: prevNormal;
// If we still don't have a previous normal, this is the beginning of a
@@ -162,22 +161,22 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
const double cosHalfAngle = joinNormal.x * nextNormal->x + joinNormal.y * nextNormal->y;
const double miterLength = cosHalfAngle != 0 ? 1 / cosHalfAngle: 1;
- const bool isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevVertex && nextVertex;
+ const bool isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevCoordinate && nextCoordinate;
if (isSharpCorner && i > 0) {
- const double prevSegmentLength = util::dist<double>(*currentVertex, *prevVertex);
+ const double prevSegmentLength = util::dist<double>(*currentCoordinate, *prevCoordinate);
if (prevSegmentLength > 2.0 * sharpCornerOffset) {
- GeometryCoordinate newPrevVertex = *currentVertex - convertPoint<int16_t>(util::round(convertPoint<double>(*currentVertex - *prevVertex) * (sharpCornerOffset / prevSegmentLength)));
- distance += util::dist<double>(newPrevVertex, *prevVertex);
+ GeometryCoordinate newPrevVertex = *currentCoordinate - convertPoint<int16_t>(util::round(convertPoint<double>(*currentCoordinate - *prevCoordinate) * (sharpCornerOffset / prevSegmentLength)));
+ distance += util::dist<double>(newPrevVertex, *prevCoordinate);
addCurrentVertex(newPrevVertex, distance, *prevNormal, 0, 0, false, startVertex, triangleStore);
- prevVertex = newPrevVertex;
+ prevCoordinate = newPrevVertex;
}
}
// The join if a middle vertex, otherwise the cap
- const bool middleVertex = prevVertex && nextVertex;
+ const bool middleVertex = prevCoordinate && nextCoordinate;
LineJoinType currentJoin = layout.lineJoin;
- const LineCapType currentCap = nextVertex ? beginCap : endCap;
+ const LineCapType currentCap = nextCoordinate ? beginCap : endCap;
if (middleVertex) {
if (currentJoin == LineJoinType::Round) {
@@ -208,12 +207,12 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
}
// Calculate how far along the line the currentVertex is
- if (prevVertex)
- distance += util::dist<double>(*currentVertex, *prevVertex);
+ if (prevCoordinate)
+ distance += util::dist<double>(*currentCoordinate, *prevCoordinate);
if (middleVertex && currentJoin == LineJoinType::Miter) {
joinNormal = joinNormal * miterLength;
- addCurrentVertex(*currentVertex, distance, joinNormal, 0, 0, false, startVertex,
+ addCurrentVertex(*currentCoordinate, distance, joinNormal, 0, 0, false, startVertex,
triangleStore);
} else if (middleVertex && currentJoin == LineJoinType::FlipBevel) {
@@ -229,10 +228,10 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
joinNormal = util::perp(joinNormal) * bevelLength * direction;
}
- addCurrentVertex(*currentVertex, distance, joinNormal, 0, 0, false, startVertex,
+ addCurrentVertex(*currentCoordinate, distance, joinNormal, 0, 0, false, startVertex,
triangleStore);
- addCurrentVertex(*currentVertex, distance, joinNormal * -1.0, 0, 0, false, startVertex,
+ addCurrentVertex(*currentCoordinate, distance, joinNormal * -1.0, 0, 0, false, startVertex,
triangleStore);
} else if (middleVertex && (currentJoin == LineJoinType::Bevel || currentJoin == LineJoinType::FakeRound)) {
const bool lineTurnsLeft = (prevNormal->x * nextNormal->y - prevNormal->y * nextNormal->x) > 0;
@@ -250,7 +249,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
// Close previous segement with bevel
if (!startOfLine) {
- addCurrentVertex(*currentVertex, distance, *prevNormal, offsetA, offsetB, false,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, offsetA, offsetB, false,
startVertex, triangleStore);
}
@@ -266,40 +265,40 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
for (int m = 0; m < n; m++) {
auto approxFractionalJoinNormal = util::unit(*nextNormal * ((m + 1.0) / (n + 1.0)) + *prevNormal);
- addPieSliceVertex(*currentVertex, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore);
+ addPieSliceVertex(*currentCoordinate, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore);
}
- addPieSliceVertex(*currentVertex, distance, joinNormal, lineTurnsLeft, startVertex, triangleStore);
+ addPieSliceVertex(*currentCoordinate, distance, joinNormal, lineTurnsLeft, startVertex, triangleStore);
for (int k = n - 1; k >= 0; k--) {
auto approxFractionalJoinNormal = util::unit(*prevNormal * ((k + 1.0) / (n + 1.0)) + *nextNormal);
- addPieSliceVertex(*currentVertex, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore);
+ addPieSliceVertex(*currentCoordinate, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore);
}
}
// Start next segment
- if (nextVertex) {
- addCurrentVertex(*currentVertex, distance, *nextNormal, -offsetA, -offsetB,
+ if (nextCoordinate) {
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, -offsetA, -offsetB,
false, startVertex, triangleStore);
}
} else if (!middleVertex && currentCap == LineCapType::Butt) {
if (!startOfLine) {
// Close previous segment with a butt
- addCurrentVertex(*currentVertex, distance, *prevNormal, 0, 0, false,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, 0, 0, false,
startVertex, triangleStore);
}
// Start next segment with a butt
- if (nextVertex) {
- addCurrentVertex(*currentVertex, distance, *nextNormal, 0, 0, false,
+ if (nextCoordinate) {
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, 0, 0, false,
startVertex, triangleStore);
}
} else if (!middleVertex && currentCap == LineCapType::Square) {
if (!startOfLine) {
// Close previous segment with a square cap
- addCurrentVertex(*currentVertex, distance, *prevNormal, 1, 1, false,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, 1, 1, false,
startVertex, triangleStore);
// The segment is done. Unset vertices to disconnect segments.
@@ -307,19 +306,19 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
}
// Start next segment
- if (nextVertex) {
- addCurrentVertex(*currentVertex, distance, *nextNormal, -1, -1, false,
+ if (nextCoordinate) {
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, -1, -1, false,
startVertex, triangleStore);
}
} else if (middleVertex ? currentJoin == LineJoinType::Round : currentCap == LineCapType::Round) {
if (!startOfLine) {
// Close previous segment with a butt
- addCurrentVertex(*currentVertex, distance, *prevNormal, 0, 0, false,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, 0, 0, false,
startVertex, triangleStore);
// Add round cap or linejoin at end of segment
- addCurrentVertex(*currentVertex, distance, *prevNormal, 1, 1, true, startVertex,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, 1, 1, true, startVertex,
triangleStore);
// The segment is done. Unset vertices to disconnect segments.
@@ -327,67 +326,65 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
}
// Start next segment with a butt
- if (nextVertex) {
+ if (nextCoordinate) {
// Add round cap before first segment
- addCurrentVertex(*currentVertex, distance, *nextNormal, -1, -1, true,
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, -1, -1, true,
startVertex, triangleStore);
- addCurrentVertex(*currentVertex, distance, *nextNormal, 0, 0, false,
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, 0, 0, false,
startVertex, triangleStore);
}
}
if (isSharpCorner && i < len - 1) {
- const double nextSegmentLength = util::dist<double>(*currentVertex, *nextVertex);
+ const double nextSegmentLength = util::dist<double>(*currentCoordinate, *nextCoordinate);
if (nextSegmentLength > 2 * sharpCornerOffset) {
- GeometryCoordinate newCurrentVertex = *currentVertex + convertPoint<int16_t>(util::round(convertPoint<double>(*nextVertex - *currentVertex) * (sharpCornerOffset / nextSegmentLength)));
- distance += util::dist<double>(newCurrentVertex, *currentVertex);
+ GeometryCoordinate newCurrentVertex = *currentCoordinate + convertPoint<int16_t>(util::round(convertPoint<double>(*nextCoordinate - *currentCoordinate) * (sharpCornerOffset / nextSegmentLength)));
+ distance += util::dist<double>(newCurrentVertex, *currentCoordinate);
addCurrentVertex(newCurrentVertex, distance, *nextNormal, 0, 0, false, startVertex, triangleStore);
- currentVertex = newCurrentVertex;
+ currentCoordinate = newCurrentVertex;
}
}
startOfLine = false;
}
- const GLsizei endVertex = vertexBuffer.index();
- const GLsizei vertexCount = endVertex - startVertex;
+ const std::size_t endVertex = vertices.size();
+ const std::size_t vertexCount = endVertex - startVertex;
- // Store the triangle/line groups.
- {
- if (triangleGroups.empty() || (triangleGroups.back()->vertex_length + vertexCount > 65535)) {
- // Move to a new group because the old one can't hold the geometry.
- triangleGroups.emplace_back(std::make_unique<TriangleGroup>());
- }
+ if (groups.empty() || groups.back().vertexLength + vertexCount > 65535) {
+ // Move to a new group because the old one can't hold the geometry.
+ groups.emplace_back();
+ }
- assert(triangleGroups.back());
- auto& group = *triangleGroups.back();
- for (const auto& triangle : triangleStore) {
- triangleElementsBuffer.add(group.vertex_length + triangle.a,
- group.vertex_length + triangle.b,
- group.vertex_length + triangle.c);
- }
+ auto& group = groups.back();
+ uint16_t index = group.vertexLength;
- group.vertex_length += vertexCount;
- group.elements_length += triangleStore.size();
+ for (const auto& triangle : triangleStore) {
+ triangles.emplace_back(static_cast<uint16_t>(index + triangle.a),
+ static_cast<uint16_t>(index + triangle.b),
+ static_cast<uint16_t>(index + triangle.c));
}
+
+ group.vertexLength += vertexCount;
+ group.indexLength += triangleStore.size();
}
-void LineBucket::addCurrentVertex(const GeometryCoordinate& currentVertex,
+void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
double &distance,
const Point<double>& normal,
double endLeft,
double endRight,
bool round,
- int32_t startVertex,
+ std::size_t startVertex,
std::vector<TriangleElement>& triangleStore) {
int8_t tx = round ? 1 : 0;
Point<double> extrude = normal;
if (endLeft)
extrude = extrude - (util::perp(normal) * endLeft);
- e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 0, endLeft, distance * LINE_DISTANCE_SCALE)
- - startVertex;
+ vertices.emplace_back(currentCoordinate.x, currentCoordinate.y, extrude.x, extrude.y, tx, 0, endLeft, distance * LINE_DISTANCE_SCALE);
+ e3 = vertices.size() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
@@ -397,8 +394,8 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentVertex,
extrude = normal * -1.0;
if (endRight)
extrude = extrude - (util::perp(normal) * endRight);
- e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 1, -endRight, distance * LINE_DISTANCE_SCALE)
- - startVertex;
+ vertices.emplace_back(currentCoordinate.x, currentCoordinate.y, extrude.x, extrude.y, tx, 1, -endRight, distance * LINE_DISTANCE_SCALE);
+ e3 = vertices.size() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
@@ -411,7 +408,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentVertex,
// to `linesofar`.
if (distance > MAX_LINE_DISTANCE / 2.0f) {
distance = 0;
- addCurrentVertex(currentVertex, distance, normal, endLeft, endRight, round, startVertex, triangleStore);
+ addCurrentVertex(currentCoordinate, distance, normal, endLeft, endRight, round, startVertex, triangleStore);
}
}
@@ -419,13 +416,13 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
double distance,
const Point<double>& extrude,
bool lineTurnsLeft,
- int32_t startVertex,
+ std::size_t startVertex,
std::vector<TriangleElement>& triangleStore) {
int8_t ty = lineTurnsLeft;
Point<double> flippedExtrude = extrude * (lineTurnsLeft ? -1.0 : 1.0);
- e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, flippedExtrude.x, flippedExtrude.y, 0, ty, 0, distance * LINE_DISTANCE_SCALE)
- - startVertex;
+ vertices.emplace_back(currentVertex.x, currentVertex.y, flippedExtrude.x, flippedExtrude.y, 0, ty, 0, distance * LINE_DISTANCE_SCALE);
+ e3 = vertices.size() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
@@ -438,8 +435,8 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
}
void LineBucket::upload(gl::Context& context) {
- vertexBuffer.upload(context);
- triangleElementsBuffer.upload(context);
+ vertexBuffer = context.createVertexBuffer(std::move(vertices));
+ indexBuffer = context.createIndexBuffer(std::move(triangles));
// From now on, we're only going to render during the translucent pass.
uploaded = true;
@@ -453,7 +450,7 @@ void LineBucket::render(Painter& painter,
}
bool LineBucket::hasData() const {
- return !triangleGroups.empty();
+ return !groups.empty();
}
bool LineBucket::needsClipping() const {
@@ -465,17 +462,16 @@ void LineBucket::drawLines(LineShader& shader,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
- for (auto& group : triangleGroups) {
- assert(group);
- if (!group->elements_length) {
+ for (auto& group : groups) {
+ if (!group.indexLength) {
continue;
}
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * indexBuffer->primitiveSize;
}
}
@@ -484,36 +480,34 @@ void LineBucket::drawLineSDF(LineSDFShader& shader,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
- for (auto& group : triangleGroups) {
- assert(group);
- if (!group->elements_length) {
+ for (auto& group : groups) {
+ if (!group.indexLength) {
continue;
}
- group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * indexBuffer->primitiveSize;
}
}
-void LineBucket::drawLinePatterns(LinepatternShader& shader,
+void LineBucket::drawLinePatterns(LinePatternShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
- for (auto& group : triangleGroups) {
- assert(group);
- if (!group->elements_length) {
+ for (auto& group : groups) {
+ if (!group.indexLength) {
continue;
}
- group->array[paintMode == PaintMode::Overdraw ? 5 : 4].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * indexBuffer->primitiveSize;
}
}
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index 5ddaca8ae8..14af710877 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -1,24 +1,22 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/renderer/element_group.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
-#include <mbgl/geometry/vao.hpp>
-#include <mbgl/geometry/elements_buffer.hpp>
-#include <mbgl/geometry/line_buffer.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/shader/line_vertex.hpp>
#include <mbgl/style/layers/line_layer_properties.hpp>
#include <vector>
namespace mbgl {
-class LineVertexBuffer;
-class TriangleElementsBuffer;
class LineShader;
class LineSDFShader;
-class LinepatternShader;
+class LinePatternShader;
class LineBucket : public Bucket {
- using TriangleGroup = ElementGroup<6>;
public:
LineBucket(uint32_t overscaling);
@@ -34,7 +32,7 @@ public:
void drawLines(LineShader&, gl::Context&, PaintMode);
void drawLineSDF(LineSDFShader&, gl::Context&, PaintMode);
- void drawLinePatterns(LinepatternShader&, gl::Context&, PaintMode);
+ void drawLinePatterns(LinePatternShader&, gl::Context&, PaintMode);
private:
struct TriangleElement {
@@ -43,23 +41,26 @@ private:
};
void addCurrentVertex(const GeometryCoordinate& currentVertex, double& distance,
const Point<double>& normal, double endLeft, double endRight, bool round,
- int32_t startVertex, std::vector<LineBucket::TriangleElement>& triangleStore);
+ std::size_t startVertex, std::vector<LineBucket::TriangleElement>& triangleStore);
void addPieSliceVertex(const GeometryCoordinate& currentVertex, double distance,
- const Point<double>& extrude, bool lineTurnsLeft, int32_t startVertex,
+ const Point<double>& extrude, bool lineTurnsLeft, std::size_t startVertex,
std::vector<TriangleElement>& triangleStore);
public:
style::LineLayoutProperties layout;
private:
- LineVertexBuffer vertexBuffer;
- TriangleElementsBuffer triangleElementsBuffer;
+ std::vector<LineVertex> vertices;
+ std::vector<gl::Triangle> triangles;
- int32_t e1;
- int32_t e2;
- int32_t e3;
+ std::vector<ElementGroup<LineShader, LineSDFShader, LinePatternShader>> groups;
- std::vector<std::unique_ptr<TriangleGroup>> triangleGroups;
+ optional<gl::VertexBuffer<LineVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
+
+ std::ptrdiff_t e1;
+ std::ptrdiff_t e2;
+ std::ptrdiff_t e3;
const uint32_t overscaling;
};
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index 4c624a0d7a..ad0e75cd92 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -39,14 +39,35 @@ namespace mbgl {
using namespace style;
Painter::Painter(const TransformState& state_)
- : state(state_) {
+ : state(state_),
+ tileTriangleVertexBuffer(context.createVertexBuffer(std::vector<FillVertex> {{
+ { 0, 0 },
+ { util::EXTENT, 0 },
+ { 0, util::EXTENT },
+ { util::EXTENT, 0 },
+ { 0, util::EXTENT },
+ { util::EXTENT, util::EXTENT }
+ }})),
+ tileLineStripVertexBuffer(context.createVertexBuffer(std::vector<FillVertex> {{
+ { 0, 0 },
+ { util::EXTENT, 0 },
+ { util::EXTENT, util::EXTENT },
+ { 0, util::EXTENT },
+ { 0, 0 }
+ }})),
+ rasterVertexBuffer(context.createVertexBuffer(std::vector<RasterVertex> {{
+ { 0, 0, 0, 0 },
+ { util::EXTENT, 0, 32767, 0 },
+ { 0, util::EXTENT, 0, 32767 },
+ { util::EXTENT, util::EXTENT, 32767, 32767 }
+ }})) {
#ifndef NDEBUG
gl::debugging::enable();
#endif
shaders = std::make_unique<Shaders>(context);
#ifndef NDEBUG
- overdrawShaders = std::make_unique<Shaders>(context, Shader::Overdraw);
+ overdrawShaders = std::make_unique<Shaders>(context, gl::Shader::Overdraw);
#endif
// Reset GL values
@@ -109,9 +130,6 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a
{
MBGL_DEBUG_GROUP("upload");
- tileStencilBuffer.upload(context);
- rasterBoundsBuffer.upload(context);
- tileBorderBuffer.upload(context);
spriteAtlas->upload(context, 0);
lineAtlas->upload(context, 0);
glyphAtlas->upload(context, 0);
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 2159881ffd..28aa5aab44 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -8,10 +8,10 @@
#include <mbgl/renderer/render_item.hpp>
#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/geometry/vao.hpp>
-#include <mbgl/geometry/static_vertex_buffer.hpp>
-
+#include <mbgl/gl/vao.hpp>
#include <mbgl/gl/context.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+#include <mbgl/shader/raster_vertex.hpp>
#include <mbgl/style/style.hpp>
@@ -41,7 +41,7 @@ class SymbolBucket;
class RasterBucket;
class Shaders;
-class SDFShader;
+class SymbolSDFShader;
class PaintParameters;
struct ClipID;
@@ -121,8 +121,8 @@ private:
const RenderTile&,
float scaleDivisor,
std::array<float, 2> texsize,
- SDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SDFShader&, gl::Context&, PaintMode),
+ SymbolSDFShader& sdfShader,
+ void (SymbolBucket::*drawSDF)(SymbolSDFShader&, gl::Context&, PaintMode),
// Layout
style::AlignmentType rotationAlignment,
@@ -188,36 +188,11 @@ private:
std::unique_ptr<Shaders> overdrawShaders;
#endif
- // Set up the stencil quad we're using to generate the stencil mask.
- StaticVertexBuffer tileStencilBuffer {
- // top left triangle
- {{ 0, 0 }},
- {{ util::EXTENT, 0 }},
- {{ 0, util::EXTENT }},
-
- // bottom right triangle
- {{ util::EXTENT, 0 }},
- {{ 0, util::EXTENT }},
- {{ util::EXTENT, util::EXTENT }},
- };
-
- StaticRasterVertexBuffer rasterBoundsBuffer {
- {{ 0, 0, 0, 0 }},
- {{ util::EXTENT, 0, 32767, 0 }},
- {{ 0, util::EXTENT, 0, 32767 }},
- {{ util::EXTENT, util::EXTENT, 32767, 32767 }},
- };
-
- // Set up the tile boundary lines we're using to draw the tile outlines.
- StaticVertexBuffer tileBorderBuffer {
- {{ 0, 0 }},
- {{ util::EXTENT, 0 }},
- {{ util::EXTENT, util::EXTENT }},
- {{ 0, util::EXTENT }},
- {{ 0, 0 }},
- };
-
- VertexArrayObject tileBorderArray;
+ gl::VertexBuffer<FillVertex> tileTriangleVertexBuffer;
+ gl::VertexBuffer<FillVertex> tileLineStripVertexBuffer;
+ gl::VertexBuffer<RasterVertex> rasterVertexBuffer;
+
+ gl::VertexArrayObject tileBorderArray;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp
index af92f17c97..61ec76d1d8 100644
--- a/src/mbgl/renderer/painter_background.cpp
+++ b/src/mbgl/renderer/painter_background.cpp
@@ -22,8 +22,8 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
optional<SpriteAtlasPosition> imagePosA;
optional<SpriteAtlasPosition> imagePosB;
- auto& patternShader = parameters.shaders.pattern;
- auto& plainShader = parameters.shaders.plain;
+ auto& patternShader = parameters.shaders.fillPattern;
+ auto& plainShader = parameters.shaders.fill;
auto& arrayBackgroundPattern = parameters.shaders.backgroundPatternArray;
auto& arrayBackground = parameters.shaders.backgroundArray;
@@ -46,14 +46,14 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
patternShader.u_opacity = properties.backgroundOpacity;
spriteAtlas->bind(true, context, 0);
- arrayBackgroundPattern.bind(patternShader, tileStencilBuffer, BUFFER_OFFSET(0), context);
+ arrayBackgroundPattern.bind(patternShader, tileTriangleVertexBuffer, BUFFER_OFFSET(0), context);
} else {
context.program = plainShader.getID();
plainShader.u_color = properties.backgroundColor;
plainShader.u_opacity = properties.backgroundOpacity;
- arrayBackground.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET(0), context);
+ arrayBackground.bind(plainShader, tileTriangleVertexBuffer, BUFFER_OFFSET(0), context);
}
context.stencilTest = false;
@@ -84,7 +84,7 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
plainShader.u_matrix = vertexMatrix;
}
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)tileStencilBuffer.index()));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, static_cast<GLsizei>(tileTriangleVertexBuffer.vertexCount)));
}
}
diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp
index 327011d03e..462ed59ebf 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -51,7 +51,7 @@ void Painter::renderCircle(PaintParameters& parameters,
circleShader.u_blur = properties.circleBlur;
circleShader.u_opacity = properties.circleOpacity;
- bucket.drawCircles(circleShader, context);
+ bucket.drawCircles(circleShader, context, paintMode());
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp
index 03402a2695..68f580c280 100644
--- a/src/mbgl/renderer/painter_clipping.cpp
+++ b/src/mbgl/renderer/painter_clipping.cpp
@@ -14,7 +14,7 @@ namespace mbgl {
void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<UnwrappedTileID, ClipID>& stencils) {
MBGL_DEBUG_GROUP("clipping masks");
- auto& plainShader = parameters.shaders.plain;
+ auto& plainShader = parameters.shaders.fill;
auto& arrayCoveringPlain = parameters.shaders.coveringPlainArray;
mat4 matrix;
@@ -29,7 +29,7 @@ void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<Unwr
context.colorMask = { false, false, false, false };
context.stencilMask = mask;
- arrayCoveringPlain.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET_0, context);
+ arrayCoveringPlain.bind(plainShader, tileTriangleVertexBuffer, BUFFER_OFFSET_0, context);
for (const auto& stencil : stencils) {
const auto& id = stencil.first;
@@ -42,7 +42,7 @@ void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<Unwr
const GLint ref = (GLint)(clip.reference.to_ulong());
context.stencilFunc = { gl::StencilTestFunction::Always, ref, mask };
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(tileTriangleVertexBuffer.vertexCount)));
}
}
diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp
index f19b77462a..23a2a8e571 100644
--- a/src/mbgl/renderer/painter_debug.cpp
+++ b/src/mbgl/renderer/painter_debug.cpp
@@ -35,10 +35,10 @@ void Painter::renderDebugText(Tile& tile, const mat4 &matrix) {
tile.debugBucket->debugMode != frame.debugOptions) {
tile.debugBucket = std::make_unique<DebugBucket>(
tile.id, tile.isRenderable(), tile.isComplete(), tile.modified,
- tile.expires, frame.debugOptions);
+ tile.expires, frame.debugOptions, context);
}
- auto& plainShader = shaders->plain;
+ auto& plainShader = shaders->fill;
context.program = plainShader.getID();
plainShader.u_matrix = matrix;
plainShader.u_opacity = 1.0f;
@@ -74,16 +74,16 @@ void Painter::renderDebugFrame(const mat4 &matrix) {
gl::StencilTestOperation::Replace };
context.stencilTest = true;
- auto& plainShader = shaders->plain;
+ auto& plainShader = shaders->fill;
context.program = plainShader.getID();
plainShader.u_matrix = matrix;
plainShader.u_opacity = 1.0f;
// draw tile outline
- tileBorderArray.bind(plainShader, tileBorderBuffer, BUFFER_OFFSET_0, context);
+ tileBorderArray.bind(plainShader, tileLineStripVertexBuffer, BUFFER_OFFSET_0, context);
plainShader.u_color = { 1.0f, 0.0f, 0.0f, 1.0f };
context.lineWidth = 4.0f * frame.pixelRatio;
- MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index()));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, static_cast<GLsizei>(tileLineStripVertexBuffer.vertexCount)));
}
#ifndef NDEBUG
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index 6d6ae4df61..50ead900f6 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -43,10 +43,10 @@ void Painter::renderFill(PaintParameters& parameters,
context.depthMask = true;
context.lineWidth = 2.0f; // This is always fixed and does not depend on the pixelRatio!
- auto& outlineShader = parameters.shaders.outline;
- auto& patternShader = parameters.shaders.pattern;
- auto& outlinePatternShader = parameters.shaders.outlinePattern;
- auto& plainShader = parameters.shaders.plain;
+ auto& outlineShader = parameters.shaders.fillOutline;
+ auto& patternShader = parameters.shaders.fillPattern;
+ auto& outlinePatternShader = parameters.shaders.fillOutlinePattern;
+ auto& plainShader = parameters.shaders.fill;
// Because we're drawing top-to-bottom, and we update the stencil mask
// befrom, we have to draw the outline first (!)
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index ee749746b9..85a5786353 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -57,8 +57,8 @@ void Painter::renderLine(PaintParameters& parameters,
setDepthSublayer(0);
- auto& linesdfShader = parameters.shaders.linesdf;
- auto& linepatternShader = parameters.shaders.linepattern;
+ auto& linesdfShader = parameters.shaders.lineSDF;
+ auto& linepatternShader = parameters.shaders.linePattern;
auto& lineShader = parameters.shaders.line;
if (!properties.lineDasharray.value.from.empty()) {
diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp
index 8a05456927..8b39c8adf8 100644
--- a/src/mbgl/renderer/painter_raster.cpp
+++ b/src/mbgl/renderer/painter_raster.cpp
@@ -47,7 +47,7 @@ void Painter::renderRaster(PaintParameters& parameters,
context.depthMask = false;
setDepthSublayer(0);
- bucket.drawRaster(rasterShader, rasterBoundsBuffer, rasterVAO, context);
+ bucket.drawRaster(rasterShader, rasterVertexBuffer, rasterVAO, context);
}
}
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index a91329d003..2ed6facad8 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -19,8 +19,8 @@ void Painter::renderSDF(SymbolBucket& bucket,
const RenderTile& tile,
float sdfFontSize,
std::array<float, 2> texsize,
- SDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SDFShader&, gl::Context&, PaintMode),
+ SymbolSDFShader& sdfShader,
+ void (SymbolBucket::*drawSDF)(SymbolSDFShader&, gl::Context&, PaintMode),
// Layout
AlignmentType rotationAlignment,
@@ -168,7 +168,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
tile,
1.0f,
{{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }},
- parameters.shaders.sdfIcon,
+ parameters.shaders.symbolIconSDF,
&SymbolBucket::drawIcons,
layout.iconRotationAlignment,
// icon-pitch-alignment is not yet implemented
@@ -200,7 +200,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
}};
}
- auto& iconShader = parameters.shaders.icon;
+ auto& iconShader = parameters.shaders.symbolIcon;
context.program = iconShader.getID();
iconShader.u_matrix = vtxMatrix;
@@ -235,7 +235,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
tile,
24.0f,
{{ float(glyphAtlas->width) / 4, float(glyphAtlas->height) / 4 }},
- parameters.shaders.sdfGlyph,
+ parameters.shaders.symbolGlyph,
&SymbolBucket::drawGlyphs,
layout.textRotationAlignment,
layout.textPitchAlignment,
@@ -251,9 +251,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
}
if (bucket.hasCollisionBoxData()) {
- context.stencilOp = { gl::StencilTestOperation::Keep, gl::StencilTestOperation::Keep,
- gl::StencilTestOperation::Replace };
- context.stencilTest = true;
+ context.stencilTest = false;
auto& collisionBoxShader = shaders->collisionBox;
context.program = collisionBoxShader.getID();
diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp
index 3edbe3e042..80d6dfe8dd 100644
--- a/src/mbgl/renderer/raster_bucket.cpp
+++ b/src/mbgl/renderer/raster_bucket.cpp
@@ -3,7 +3,7 @@
#include <mbgl/shader/raster_shader.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/gl/gl.hpp>
-
+#include <mbgl/gl/context.hpp>
namespace mbgl {
@@ -26,14 +26,14 @@ void RasterBucket::render(Painter& painter,
}
void RasterBucket::drawRaster(RasterShader& shader,
- StaticRasterVertexBuffer& vertices,
- VertexArrayObject& array,
+ gl::VertexBuffer<RasterVertex>& vertices,
+ gl::VertexArrayObject& array,
gl::Context& context) {
assert(texture);
context.bindTexture(*texture, 0, gl::TextureFilter::Linear);
context.bindTexture(*texture, 1, gl::TextureFilter::Linear);
array.bind(shader, vertices, BUFFER_OFFSET_0, context);
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)vertices.index()));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, static_cast<GLsizei>(vertices.vertexCount)));
}
bool RasterBucket::hasData() const {
diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp
index db8138b875..b0d3ca49c7 100644
--- a/src/mbgl/renderer/raster_bucket.hpp
+++ b/src/mbgl/renderer/raster_bucket.hpp
@@ -2,13 +2,19 @@
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/util/image.hpp>
-#include <mbgl/gl/context.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/gl/texture.hpp>
namespace mbgl {
class RasterShader;
-class StaticRasterVertexBuffer;
+class RasterVertex;
+
+namespace gl {
+class Context;
+template <class> class VertexBuffer;
class VertexArrayObject;
+} // namespace gl
class RasterBucket : public Bucket {
public:
@@ -19,7 +25,7 @@ public:
bool hasData() const override;
bool needsClipping() const override;
- void drawRaster(RasterShader&, StaticRasterVertexBuffer&, VertexArrayObject&, gl::Context&);
+ void drawRaster(RasterShader&, gl::VertexBuffer<RasterVertex>&, gl::VertexArrayObject&, gl::Context&);
private:
PremultipliedImage image;
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index 3ef0686e4d..565c58c7ed 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -1,8 +1,8 @@
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
-#include <mbgl/shader/sdf_shader.hpp>
-#include <mbgl/shader/icon_shader.hpp>
+#include <mbgl/shader/symbol_sdf_shader.hpp>
+#include <mbgl/shader/symbol_icon_shader.hpp>
#include <mbgl/shader/collision_box_shader.hpp>
#include <mbgl/gl/gl.hpp>
@@ -22,12 +22,17 @@ SymbolBucket::SymbolBucket(const MapMode mode_,
void SymbolBucket::upload(gl::Context& context) {
if (hasTextData()) {
- text.vertices.upload(context);
- text.triangles.upload(context);
+ text.vertexBuffer = context.createVertexBuffer(std::move(text.vertices));
+ text.indexBuffer = context.createIndexBuffer(std::move(text.triangles));
}
+
if (hasIconData()) {
- icon.vertices.upload(context);
- icon.triangles.upload(context);
+ icon.vertexBuffer = context.createVertexBuffer(std::move(icon.vertices));
+ icon.indexBuffer = context.createIndexBuffer(std::move(icon.triangles));
+ }
+
+ if (hasCollisionBoxData()) {
+ collisionBox.vertexBuffer = context.createVertexBuffer(std::move(collisionBox.vertices));
}
uploaded = true;
@@ -61,51 +66,48 @@ bool SymbolBucket::needsClipping() const {
return mode == MapMode::Still;
}
-void SymbolBucket::drawGlyphs(SDFShader& shader,
+void SymbolBucket::drawGlyphs(SymbolSDFShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET_0;
GLbyte* elements_index = BUFFER_OFFSET_0;
for (auto& group : text.groups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, text.vertices, text.triangles, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *text.vertexBuffer, *text.indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * text.vertices.itemSize;
- elements_index += group->elements_length * text.triangles.itemSize;
+ vertex_index += group.vertexLength * text.vertexBuffer->vertexSize;
+ elements_index += group.indexLength * text.indexBuffer->primitiveSize;
}
}
-void SymbolBucket::drawIcons(SDFShader& shader,
+void SymbolBucket::drawIcons(SymbolSDFShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET_0;
GLbyte* elements_index = BUFFER_OFFSET_0;
for (auto& group : icon.groups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, icon.vertices, icon.triangles, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *icon.vertexBuffer, *icon.indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * icon.vertices.itemSize;
- elements_index += group->elements_length * icon.triangles.itemSize;
+ vertex_index += group.vertexLength * icon.vertexBuffer->vertexSize;
+ elements_index += group.indexLength * icon.indexBuffer->primitiveSize;
}
}
-void SymbolBucket::drawIcons(IconShader& shader,
+void SymbolBucket::drawIcons(SymbolIconShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET_0;
GLbyte* elements_index = BUFFER_OFFSET_0;
for (auto& group : icon.groups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind(
- shader, icon.vertices, icon.triangles, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *icon.vertexBuffer, *icon.indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * icon.vertices.itemSize;
- elements_index += group->elements_length * icon.triangles.itemSize;
+ vertex_index += group.vertexLength * icon.vertexBuffer->vertexSize;
+ elements_index += group.indexLength * icon.indexBuffer->primitiveSize;
}
}
@@ -113,8 +115,9 @@ void SymbolBucket::drawCollisionBoxes(CollisionBoxShader& shader,
gl::Context& context) {
GLbyte* vertex_index = BUFFER_OFFSET_0;
for (auto& group : collisionBox.groups) {
- group->array[0].bind(shader, collisionBox.vertices, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, group->vertex_length));
+ group.getVAO(shader, PaintMode::Regular).bind(
+ shader, *collisionBox.vertexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(group.vertexLength)));
}
}
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index 87c8250d55..e5180c31e2 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -1,11 +1,12 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/renderer/element_group.hpp>
#include <mbgl/map/mode.hpp>
-#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/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/shader/symbol_vertex.hpp>
+#include <mbgl/shader/collision_box_vertex.hpp>
#include <mbgl/text/glyph_range.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
@@ -14,8 +15,8 @@
namespace mbgl {
-class SDFShader;
-class IconShader;
+class SymbolSDFShader;
+class SymbolIconShader;
class CollisionBoxShader;
class SymbolBucket : public Bucket {
@@ -33,9 +34,9 @@ public:
bool hasCollisionBoxData() const;
bool needsClipping() const override;
- void drawGlyphs(SDFShader&, gl::Context&, PaintMode);
- void drawIcons(SDFShader&, gl::Context&, PaintMode);
- void drawIcons(IconShader&, gl::Context&, PaintMode);
+ void drawGlyphs(SymbolSDFShader&, gl::Context&, PaintMode);
+ void drawIcons(SymbolSDFShader&, gl::Context&, PaintMode);
+ void drawIcons(SymbolIconShader&, gl::Context&, PaintMode);
void drawCollisionBoxes(CollisionBoxShader&, gl::Context&);
const MapMode mode;
@@ -46,25 +47,31 @@ public:
private:
friend class SymbolLayout;
- typedef ElementGroup<2> TextElementGroup;
- typedef ElementGroup<4> IconElementGroup;
- typedef ElementGroup<1> CollisionBoxElementGroup;
-
struct TextBuffer {
- TextVertexBuffer vertices;
- TriangleElementsBuffer triangles;
- std::vector<std::unique_ptr<TextElementGroup>> groups;
+ std::vector<SymbolVertex> vertices;
+ std::vector<gl::Triangle> triangles;
+ std::vector<ElementGroup<SymbolSDFShader>> groups;
+
+ optional<gl::VertexBuffer<SymbolVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
} text;
struct IconBuffer {
- IconVertexBuffer vertices;
- TriangleElementsBuffer triangles;
- std::vector<std::unique_ptr<IconElementGroup>> groups;
+ std::vector<SymbolVertex> vertices;
+ std::vector<gl::Triangle> triangles;
+ std::vector<ElementGroup<SymbolSDFShader, SymbolIconShader>> groups;
+
+ optional<gl::VertexBuffer<SymbolVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
} icon;
struct CollisionBoxBuffer {
- CollisionBoxVertexBuffer vertices;
- std::vector<std::unique_ptr<CollisionBoxElementGroup>> groups;
+ std::vector<CollisionBoxVertex> vertices;
+ std::vector<gl::Line> lines;
+ std::vector<ElementGroup<CollisionBoxShader>> groups;
+
+ optional<gl::VertexBuffer<CollisionBoxVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Line>> indexBuffer;
} collisionBox;
};
diff --git a/src/mbgl/shader/circle_shader.cpp b/src/mbgl/shader/circle_shader.cpp
index b3430d4450..9e294f8d76 100644
--- a/src/mbgl/shader/circle_shader.cpp
+++ b/src/mbgl/shader/circle_shader.cpp
@@ -1,7 +1,7 @@
#include <mbgl/shader/circle_shader.hpp>
#include <mbgl/shader/circle.vertex.hpp>
#include <mbgl/shader/circle.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/shader/circle_vertex.hpp>
namespace mbgl {
@@ -12,9 +12,4 @@ CircleShader::CircleShader(gl::Context& context, Defines defines)
context, defines) {
}
-void CircleShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 4, offset));
-}
-
} // namespace mbgl
diff --git a/src/mbgl/shader/circle_shader.hpp b/src/mbgl/shader/circle_shader.hpp
index b87d856775..c2c4053ba4 100644
--- a/src/mbgl/shader/circle_shader.hpp
+++ b/src/mbgl/shader/circle_shader.hpp
@@ -1,25 +1,30 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
#include <mbgl/util/color.hpp>
namespace mbgl {
-class CircleShader : public Shader {
+class CircleVertex;
+
+class CircleShader : public gl::Shader {
public:
CircleShader(gl::Context&, Defines defines = None);
- void bind(int8_t* offset) final;
+ using VertexType = CircleVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
- Uniform<float> u_devicepixelratio = {"u_devicepixelratio", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_radius = {"u_radius", *this};
- Uniform<float> u_blur = {"u_blur", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<int32_t> u_scale_with_map = {"u_scale_with_map", *this};
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
+ gl::Uniform<float> u_devicepixelratio = {"u_devicepixelratio", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_radius = {"u_radius", *this};
+ gl::Uniform<float> u_blur = {"u_blur", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<int32_t> u_scale_with_map = {"u_scale_with_map", *this};
};
} // namespace mbgl
diff --git a/src/mbgl/shader/circle_vertex.cpp b/src/mbgl/shader/circle_vertex.cpp
new file mode 100644
index 0000000000..8beb88e650
--- /dev/null
+++ b/src/mbgl/shader/circle_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/circle_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(CircleVertex) == 4, "expected CircleVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/circle_vertex.hpp b/src/mbgl/shader/circle_vertex.hpp
new file mode 100644
index 0000000000..4fce49f137
--- /dev/null
+++ b/src/mbgl/shader/circle_vertex.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+
+namespace mbgl {
+
+class CircleVertex {
+public:
+ /*
+ * @param {number} x vertex position
+ * @param {number} y vertex position
+ * @param {number} ex extrude normal
+ * @param {number} ey extrude normal
+ */
+ CircleVertex(int16_t x, int16_t y, float ex, float ey)
+ : a_pos {
+ static_cast<int16_t>((x * 2) + ((ex + 1) / 2)),
+ static_cast<int16_t>((y * 2) + ((ey + 1) / 2))
+ } {}
+
+ const int16_t a_pos[2];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, CircleVertex> {
+ std::array<AttributeBinding, 1> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(CircleVertex, shader, a_pos)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/collision_box_shader.cpp b/src/mbgl/shader/collision_box_shader.cpp
index c0a24f0f6f..d61c849cd1 100644
--- a/src/mbgl/shader/collision_box_shader.cpp
+++ b/src/mbgl/shader/collision_box_shader.cpp
@@ -1,28 +1,15 @@
#include <mbgl/shader/collision_box_shader.hpp>
-#include <mbgl/shader/collisionbox.vertex.hpp>
-#include <mbgl/shader/collisionbox.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/shader/collision_box.vertex.hpp>
+#include <mbgl/shader/collision_box.fragment.hpp>
+#include <mbgl/shader/collision_box_vertex.hpp>
namespace mbgl {
CollisionBoxShader::CollisionBoxShader(gl::Context& context)
- : Shader(shaders::collisionbox::name,
- shaders::collisionbox::vertex,
- shaders::collisionbox::fragment,
+ : Shader(shaders::collision_box::name,
+ shaders::collision_box::vertex,
+ shaders::collision_box::fragment,
context) {
}
-void CollisionBoxShader::bind(GLbyte *offset) {
- const GLint 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));
-}
-
} // namespace mbgl
diff --git a/src/mbgl/shader/collision_box_shader.hpp b/src/mbgl/shader/collision_box_shader.hpp
index 65c3ca0146..2f5c506168 100644
--- a/src/mbgl/shader/collision_box_shader.hpp
+++ b/src/mbgl/shader/collision_box_shader.hpp
@@ -1,20 +1,27 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
namespace mbgl {
-class CollisionBoxShader : public Shader {
+class CollisionBoxVertex;
+
+class CollisionBoxShader : public gl::Shader {
public:
CollisionBoxShader(gl::Context&);
- void bind(int8_t* offset) final;
+ using VertexType = CollisionBoxVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+ gl::Attribute<int16_t, 2> a_extrude = {"a_extrude", *this};
+ gl::Attribute<uint8_t, 2> a_data = {"a_data", *this};
- 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};
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<float> u_scale = {"u_scale", *this};
+ gl::Uniform<float> u_zoom = {"u_zoom", *this};
+ gl::Uniform<float> u_maxzoom = {"u_maxzoom", *this};
};
} // namespace mbgl
diff --git a/src/mbgl/shader/collision_box_vertex.cpp b/src/mbgl/shader/collision_box_vertex.cpp
new file mode 100644
index 0000000000..397fbfe6a3
--- /dev/null
+++ b/src/mbgl/shader/collision_box_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/collision_box_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(CollisionBoxVertex) == 10, "expected CollisionBoxVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/collision_box_vertex.hpp b/src/mbgl/shader/collision_box_vertex.hpp
new file mode 100644
index 0000000000..ba72b1c0ee
--- /dev/null
+++ b/src/mbgl/shader/collision_box_vertex.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+#include <cmath>
+
+namespace mbgl {
+
+class CollisionBoxVertex {
+public:
+ CollisionBoxVertex(int16_t x, int16_t y, float ox, float oy, float maxzoom, float placementZoom)
+ : a_pos { x, y },
+ a_extrude {
+ static_cast<int16_t>(::round(ox)),
+ static_cast<int16_t>(::round(oy))
+ },
+ a_data {
+ static_cast<uint8_t>(maxzoom * 10),
+ static_cast<uint8_t>(placementZoom * 10)
+ } {}
+
+ const int16_t a_pos[2];
+ const int16_t a_extrude[2];
+ const uint8_t a_data[2];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, CollisionBoxVertex> {
+ std::array<AttributeBinding, 3> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(CollisionBoxVertex, shader, a_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(CollisionBoxVertex, shader, a_extrude),
+ MBGL_MAKE_ATTRIBUTE_BINDING(CollisionBoxVertex, shader, a_data)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_outline_pattern_shader.cpp b/src/mbgl/shader/fill_outline_pattern_shader.cpp
new file mode 100644
index 0000000000..b03921d384
--- /dev/null
+++ b/src/mbgl/shader/fill_outline_pattern_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/fill_outline_pattern_shader.hpp>
+#include <mbgl/shader/fill_outline_pattern.vertex.hpp>
+#include <mbgl/shader/fill_outline_pattern.fragment.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+FillOutlinePatternShader::FillOutlinePatternShader(gl::Context& context, Defines defines)
+ : Shader(shaders::fill_outline_pattern::name,
+ shaders::fill_outline_pattern::vertex,
+ shaders::fill_outline_pattern::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_outline_pattern_shader.hpp b/src/mbgl/shader/fill_outline_pattern_shader.hpp
new file mode 100644
index 0000000000..630e6a7ce8
--- /dev/null
+++ b/src/mbgl/shader/fill_outline_pattern_shader.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+
+namespace mbgl {
+
+class FillVertex;
+
+class FillOutlinePatternShader : public gl::Shader {
+public:
+ FillOutlinePatternShader(gl::Context&, Defines defines = None);
+
+ using VertexType = FillVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_mix = {"u_mix", *this};
+ gl::Uniform<float> u_scale_a = {"u_scale_a", *this};
+ gl::Uniform<float> u_scale_b = {"u_scale_b", *this};
+ gl::Uniform<float> u_tile_units_to_pixels = {"u_tile_units_to_pixels", *this};
+ gl::Uniform<int32_t> u_image = {"u_image", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pixel_coord_upper = {"u_pixel_coord_upper", *this};
+ gl::Uniform<std::array<float, 2>> u_pixel_coord_lower = {"u_pixel_coord_lower", *this};
+ gl::Uniform<std::array<float, 2>> u_world = {"u_world", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_outline_shader.cpp b/src/mbgl/shader/fill_outline_shader.cpp
new file mode 100644
index 0000000000..6e6d8c2239
--- /dev/null
+++ b/src/mbgl/shader/fill_outline_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/fill_outline_shader.hpp>
+#include <mbgl/shader/fill_outline.vertex.hpp>
+#include <mbgl/shader/fill_outline.fragment.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+FillOutlineShader::FillOutlineShader(gl::Context& context, Defines defines)
+ : Shader(shaders::fill_outline::name,
+ shaders::fill_outline::vertex,
+ shaders::fill_outline::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_outline_shader.hpp b/src/mbgl/shader/fill_outline_shader.hpp
new file mode 100644
index 0000000000..c20bc187d3
--- /dev/null
+++ b/src/mbgl/shader/fill_outline_shader.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+
+class FillVertex;
+
+class FillOutlineShader : public gl::Shader {
+public:
+ FillOutlineShader(gl::Context&, Defines defines = None);
+
+ using VertexType = FillVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<Color> u_outline_color = {"u_outline_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<std::array<float, 2>> u_world = {"u_world", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_pattern_shader.cpp b/src/mbgl/shader/fill_pattern_shader.cpp
new file mode 100644
index 0000000000..60be6d79ad
--- /dev/null
+++ b/src/mbgl/shader/fill_pattern_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/fill_pattern_shader.hpp>
+#include <mbgl/shader/fill_pattern.vertex.hpp>
+#include <mbgl/shader/fill_pattern.fragment.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+FillPatternShader::FillPatternShader(gl::Context& context, Defines defines)
+ : Shader(shaders::fill_pattern::name,
+ shaders::fill_pattern::vertex,
+ shaders::fill_pattern::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_pattern_shader.hpp b/src/mbgl/shader/fill_pattern_shader.hpp
new file mode 100644
index 0000000000..36be538000
--- /dev/null
+++ b/src/mbgl/shader/fill_pattern_shader.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+
+namespace mbgl {
+
+class FillVertex;
+
+class FillPatternShader : public gl::Shader {
+public:
+ FillPatternShader(gl::Context&, Defines defines = None);
+
+ using VertexType = FillVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_mix = {"u_mix", *this};
+ gl::Uniform<float> u_scale_a = {"u_scale_a", *this};
+ gl::Uniform<float> u_scale_b = {"u_scale_b", *this};
+ gl::Uniform<float> u_tile_units_to_pixels = {"u_tile_units_to_pixels", *this};
+ gl::Uniform<int32_t> u_image = {"u_image", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pixel_coord_upper = {"u_pixel_coord_upper", *this};
+ gl::Uniform<std::array<float, 2>> u_pixel_coord_lower = {"u_pixel_coord_lower", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_shader.cpp b/src/mbgl/shader/fill_shader.cpp
new file mode 100644
index 0000000000..7026bb2f1c
--- /dev/null
+++ b/src/mbgl/shader/fill_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/fill_shader.hpp>
+#include <mbgl/shader/fill.vertex.hpp>
+#include <mbgl/shader/fill.fragment.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+FillShader::FillShader(gl::Context& context, Defines defines)
+ : Shader(shaders::fill::name,
+ shaders::fill::vertex,
+ shaders::fill::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_shader.hpp b/src/mbgl/shader/fill_shader.hpp
new file mode 100644
index 0000000000..1240b73aa2
--- /dev/null
+++ b/src/mbgl/shader/fill_shader.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+
+class FillVertex;
+
+class FillShader : public gl::Shader {
+public:
+ FillShader(gl::Context&, Defines defines = None);
+
+ using VertexType = FillVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_vertex.cpp b/src/mbgl/shader/fill_vertex.cpp
new file mode 100644
index 0000000000..c39a0b96b1
--- /dev/null
+++ b/src/mbgl/shader/fill_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(FillVertex) == 4, "expected FillVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_vertex.hpp b/src/mbgl/shader/fill_vertex.hpp
new file mode 100644
index 0000000000..1b8130382a
--- /dev/null
+++ b/src/mbgl/shader/fill_vertex.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+
+namespace mbgl {
+
+class FillVertex {
+public:
+ FillVertex(int16_t x, int16_t y)
+ : a_pos { x, y } {}
+
+ const int16_t a_pos[2];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, FillVertex> {
+ std::array<AttributeBinding, 1> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(FillVertex, shader, a_pos)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/icon_shader.cpp b/src/mbgl/shader/icon_shader.cpp
deleted file mode 100644
index d002e49a49..0000000000
--- a/src/mbgl/shader/icon_shader.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <mbgl/shader/icon_shader.hpp>
-#include <mbgl/shader/icon.vertex.hpp>
-#include <mbgl/shader/icon.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-IconShader::IconShader(gl::Context& context, Defines defines)
- : Shader(shaders::icon::name,
- shaders::icon::vertex,
- shaders::icon::fragment,
- context, defines) {
-}
-
-void IconShader::bind(int8_t* offset) {
- const GLsizei stride = 16;
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_offset));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_offset, 2, GL_SHORT, false, stride, offset + 4));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_texture_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_texture_pos, 2, GL_UNSIGNED_SHORT, false, stride, offset + 8));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, stride, offset + 12));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/icon_shader.hpp b/src/mbgl/shader/icon_shader.hpp
deleted file mode 100644
index c4f24c91f7..0000000000
--- a/src/mbgl/shader/icon_shader.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-
-namespace mbgl {
-
-class IconShader : public Shader {
-public:
- IconShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
- Uniform<float> u_zoom = {"u_zoom", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
- Uniform<int32_t> u_rotate_with_map = {"u_rotate_with_map", *this};
- Uniform<int32_t> u_texture = {"u_texture", *this};
- Uniform<int32_t> u_fadetexture = {"u_fadetexture", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/line_pattern_shader.cpp b/src/mbgl/shader/line_pattern_shader.cpp
new file mode 100644
index 0000000000..e6bc32a5c9
--- /dev/null
+++ b/src/mbgl/shader/line_pattern_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/line_pattern_shader.hpp>
+#include <mbgl/shader/line_pattern.vertex.hpp>
+#include <mbgl/shader/line_pattern.fragment.hpp>
+#include <mbgl/shader/line_vertex.hpp>
+
+namespace mbgl {
+
+LinePatternShader::LinePatternShader(gl::Context& context, Defines defines)
+ : Shader(shaders::line_pattern::name,
+ shaders::line_pattern::vertex,
+ shaders::line_pattern::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_pattern_shader.hpp b/src/mbgl/shader/line_pattern_shader.hpp
new file mode 100644
index 0000000000..1bd6085c8b
--- /dev/null
+++ b/src/mbgl/shader/line_pattern_shader.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/gl/attribute.hpp>
+
+namespace mbgl {
+
+class LineVertex;
+
+class LinePatternShader : public gl::Shader {
+public:
+ LinePatternShader(gl::Context&, Defines defines = None);
+
+ using VertexType = LineVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<float> u_linewidth = {"u_linewidth", *this};
+ gl::Uniform<float> u_gapwidth = {"u_gapwidth", *this};
+ gl::Uniform<float> u_antialiasing = {"u_antialiasing", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
+ gl::Uniform<float> u_ratio = {"u_ratio", *this};
+ gl::Uniform<float> u_point = {"u_point", *this};
+ gl::Uniform<float> u_blur = {"u_blur", *this};
+ gl::Uniform<float> u_fade = {"u_fade", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_extra = {"u_extra", *this};
+ gl::Uniform<float> u_offset = {"u_offset", *this};
+ gl::Uniform<int32_t> u_image = {"u_image", *this};
+ gl::UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_sdf_shader.cpp b/src/mbgl/shader/line_sdf_shader.cpp
new file mode 100644
index 0000000000..dd724365ea
--- /dev/null
+++ b/src/mbgl/shader/line_sdf_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/line_sdf_shader.hpp>
+#include <mbgl/shader/line_sdf.vertex.hpp>
+#include <mbgl/shader/line_sdf.fragment.hpp>
+#include <mbgl/shader/line_vertex.hpp>
+
+namespace mbgl {
+
+LineSDFShader::LineSDFShader(gl::Context& context, Defines defines)
+ : Shader(shaders::line_sdf::name,
+ shaders::line_sdf::vertex,
+ shaders::line_sdf::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_sdf_shader.hpp b/src/mbgl/shader/line_sdf_shader.hpp
new file mode 100644
index 0000000000..d74e42e50f
--- /dev/null
+++ b/src/mbgl/shader/line_sdf_shader.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+
+class LineVertex;
+
+class LineSDFShader : public gl::Shader {
+public:
+ LineSDFShader(gl::Context&, Defines defines = None);
+
+ using VertexType = LineVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_linewidth = {"u_linewidth", *this};
+ gl::Uniform<float> u_gapwidth = {"u_gapwidth", *this};
+ gl::Uniform<float> u_antialiasing = {"u_antialiasing", *this};
+ gl::Uniform<float> u_ratio = {"u_ratio", *this};
+ gl::Uniform<float> u_blur = {"u_blur", *this};
+ gl::Uniform<std::array<float, 2>> u_patternscale_a = { "u_patternscale_a", *this};
+ gl::Uniform<float> u_tex_y_a = {"u_tex_y_a", *this};
+ gl::Uniform<std::array<float, 2>> u_patternscale_b = { "u_patternscale_b", *this};
+ gl::Uniform<float> u_tex_y_b = {"u_tex_y_b", *this};
+ gl::Uniform<int32_t> u_image = {"u_image", *this};
+ gl::Uniform<float> u_sdfgamma = {"u_sdfgamma", *this};
+ gl::Uniform<float> u_mix = {"u_mix", *this};
+ gl::Uniform<float> u_extra = {"u_extra", *this};
+ gl::Uniform<float> u_offset = {"u_offset", *this};
+ gl::UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
+};
+
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_shader.cpp b/src/mbgl/shader/line_shader.cpp
index 684390815c..4e934cd60c 100644
--- a/src/mbgl/shader/line_shader.cpp
+++ b/src/mbgl/shader/line_shader.cpp
@@ -1,7 +1,7 @@
#include <mbgl/shader/line_shader.hpp>
#include <mbgl/shader/line.vertex.hpp>
#include <mbgl/shader/line.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/shader/line_vertex.hpp>
namespace mbgl {
@@ -12,12 +12,4 @@ LineShader::LineShader(gl::Context& context, Defines defines)
context, defines) {
}
-void LineShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, 8, offset + 4));
-}
-
} // namespace mbgl
diff --git a/src/mbgl/shader/line_shader.hpp b/src/mbgl/shader/line_shader.hpp
index a6be32ebc3..79991e1883 100644
--- a/src/mbgl/shader/line_shader.hpp
+++ b/src/mbgl/shader/line_shader.hpp
@@ -1,28 +1,34 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
#include <mbgl/util/color.hpp>
namespace mbgl {
-class LineShader : public Shader {
+class LineVertex;
+
+class LineShader : public gl::Shader {
public:
LineShader(gl::Context&, Defines defines = None);
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_ratio = {"u_ratio", *this};
- Uniform<float> u_linewidth = {"u_linewidth", *this};
- Uniform<float> u_gapwidth = {"u_gapwidth", *this};
- Uniform<float> u_antialiasing = {"u_antialiasing", *this};
- Uniform<float> u_blur = {"u_blur", *this};
- Uniform<float> u_extra = {"u_extra", *this};
- Uniform<float> u_offset = {"u_offset", *this};
- UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
+ using VertexType = LineVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_ratio = {"u_ratio", *this};
+ gl::Uniform<float> u_linewidth = {"u_linewidth", *this};
+ gl::Uniform<float> u_gapwidth = {"u_gapwidth", *this};
+ gl::Uniform<float> u_antialiasing = {"u_antialiasing", *this};
+ gl::Uniform<float> u_blur = {"u_blur", *this};
+ gl::Uniform<float> u_extra = {"u_extra", *this};
+ gl::Uniform<float> u_offset = {"u_offset", *this};
+ gl::UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
};
diff --git a/src/mbgl/shader/line_vertex.cpp b/src/mbgl/shader/line_vertex.cpp
new file mode 100644
index 0000000000..ad466310d8
--- /dev/null
+++ b/src/mbgl/shader/line_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/line_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(LineVertex) == 8, "expected LineVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_vertex.hpp b/src/mbgl/shader/line_vertex.hpp
new file mode 100644
index 0000000000..086100810e
--- /dev/null
+++ b/src/mbgl/shader/line_vertex.hpp
@@ -0,0 +1,72 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+#include <cmath>
+
+namespace mbgl {
+
+class LineVertex {
+public:
+ /*
+ * @param {number} x vertex position
+ * @param {number} y vertex position
+ * @param {number} ex extrude normal
+ * @param {number} ey extrude normal
+ * @param {number} tx texture normal
+ * @param {number} ty texture normal
+ * @param {number} dir direction of the line cap (-1/0/1)
+ */
+ LineVertex(int16_t x, int16_t y, float ex, float ey, bool tx, bool ty, int8_t dir, int32_t linesofar = 0)
+ : a_pos {
+ static_cast<int16_t>((x * 2) | tx),
+ static_cast<int16_t>((y * 2) | ty)
+ },
+ a_data {
+ // add 128 to store an byte in an unsigned byte
+ static_cast<uint8_t>(::round(extrudeScale * ex) + 128),
+ static_cast<uint8_t>(::round(extrudeScale * ey) + 128),
+
+ // Encode the -1/0/1 direction value into the first two bits of .z of a_data.
+ // Combine it with the lower 6 bits of `linesofar` (shifted by 2 bites to make
+ // room for the direction value). The upper 8 bits of `linesofar` are placed in
+ // the `w` component. `linesofar` is scaled down by `LINE_DISTANCE_SCALE` so that
+ // we can store longer distances while sacrificing precision.
+
+ // Encode the -1/0/1 direction value into .zw coordinates of a_data, which is normally covered
+ // by linesofar, so we need to merge them.
+ // The z component's first bit, as well as the sign bit is reserved for the direction,
+ // so we need to shift the linesofar.
+ static_cast<uint8_t>(((dir == 0 ? 0 : (dir < 0 ? -1 : 1 )) + 1) | ((linesofar & 0x3F) << 2)),
+ static_cast<uint8_t>(linesofar >> 6)
+ } {}
+
+ const int16_t a_pos[2];
+ const uint8_t a_data[4];
+
+ /*
+ * Scale the extrusion vector so that the normal length is this value.
+ * Contains the "texture" normals (-1..1). This is distinct from the extrude
+ * normals for line joins, because the x-value remains 0 for the texture
+ * normal array, while the extrude normal actually moves the vertex to create
+ * the acute/bevelled line join.
+ */
+ static const int8_t extrudeScale = 63;
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, LineVertex> {
+ std::array<AttributeBinding, 2> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(LineVertex, shader, a_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(LineVertex, shader, a_data)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/linepattern_shader.cpp b/src/mbgl/shader/linepattern_shader.cpp
deleted file mode 100644
index 8f755d4140..0000000000
--- a/src/mbgl/shader/linepattern_shader.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <mbgl/shader/linepattern_shader.hpp>
-#include <mbgl/shader/linepattern.vertex.hpp>
-#include <mbgl/shader/linepattern.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-LinepatternShader::LinepatternShader(gl::Context& context, Defines defines)
- : Shader(shaders::linepattern::name,
- shaders::linepattern::vertex,
- shaders::linepattern::fragment,
- context, defines) {
-}
-
-void LinepatternShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, 8, offset + 4));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/linepattern_shader.hpp b/src/mbgl/shader/linepattern_shader.hpp
deleted file mode 100644
index 89f64d3e1f..0000000000
--- a/src/mbgl/shader/linepattern_shader.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-
-namespace mbgl {
-
-class LinepatternShader : public Shader {
-public:
- LinepatternShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<float> u_linewidth = {"u_linewidth", *this};
- Uniform<float> u_gapwidth = {"u_gapwidth", *this};
- Uniform<float> u_antialiasing = {"u_antialiasing", *this};
- Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
- Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
- Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
- Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
- Uniform<float> u_ratio = {"u_ratio", *this};
- Uniform<float> u_point = {"u_point", *this};
- Uniform<float> u_blur = {"u_blur", *this};
- Uniform<float> u_fade = {"u_fade", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_extra = {"u_extra", *this};
- Uniform<float> u_offset = {"u_offset", *this};
- Uniform<int32_t> u_image = {"u_image", *this};
- UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/linesdf_shader.cpp b/src/mbgl/shader/linesdf_shader.cpp
deleted file mode 100644
index 788239459f..0000000000
--- a/src/mbgl/shader/linesdf_shader.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <mbgl/shader/linesdf_shader.hpp>
-#include <mbgl/shader/linesdfpattern.vertex.hpp>
-#include <mbgl/shader/linesdfpattern.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-LineSDFShader::LineSDFShader(gl::Context& context, Defines defines)
- : Shader(shaders::linesdfpattern::name,
- shaders::linesdfpattern::vertex,
- shaders::linesdfpattern::fragment,
- context, defines) {
-}
-
-void LineSDFShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, 8, offset + 4));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/linesdf_shader.hpp b/src/mbgl/shader/linesdf_shader.hpp
deleted file mode 100644
index 4c1fd89635..0000000000
--- a/src/mbgl/shader/linesdf_shader.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
-
-namespace mbgl {
-
-class LineSDFShader : public Shader {
-public:
- LineSDFShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_linewidth = {"u_linewidth", *this};
- Uniform<float> u_gapwidth = {"u_gapwidth", *this};
- Uniform<float> u_antialiasing = {"u_antialiasing", *this};
- Uniform<float> u_ratio = {"u_ratio", *this};
- Uniform<float> u_blur = {"u_blur", *this};
- Uniform<std::array<float, 2>> u_patternscale_a = { "u_patternscale_a", *this};
- Uniform<float> u_tex_y_a = {"u_tex_y_a", *this};
- Uniform<std::array<float, 2>> u_patternscale_b = { "u_patternscale_b", *this};
- Uniform<float> u_tex_y_b = {"u_tex_y_b", *this};
- Uniform<int32_t> u_image = {"u_image", *this};
- Uniform<float> u_sdfgamma = {"u_sdfgamma", *this};
- Uniform<float> u_mix = {"u_mix", *this};
- Uniform<float> u_extra = {"u_extra", *this};
- Uniform<float> u_offset = {"u_offset", *this};
- UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
-};
-
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/outline_shader.cpp b/src/mbgl/shader/outline_shader.cpp
deleted file mode 100644
index 94e981f4a6..0000000000
--- a/src/mbgl/shader/outline_shader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <mbgl/shader/outline_shader.hpp>
-#include <mbgl/shader/outline.vertex.hpp>
-#include <mbgl/shader/outline.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-OutlineShader::OutlineShader(gl::Context& context, Defines defines)
- : Shader(shaders::outline::name,
- shaders::outline::vertex,
- shaders::outline::fragment,
- context, defines) {
-}
-
-void OutlineShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/outline_shader.hpp b/src/mbgl/shader/outline_shader.hpp
deleted file mode 100644
index ccd8dc4303..0000000000
--- a/src/mbgl/shader/outline_shader.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
-
-namespace mbgl {
-
-class OutlineShader : public Shader {
-public:
- OutlineShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<Color> u_outline_color = {"u_outline_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<std::array<float, 2>> u_world = {"u_world", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/outlinepattern_shader.cpp b/src/mbgl/shader/outlinepattern_shader.cpp
deleted file mode 100644
index b33c2b2c1f..0000000000
--- a/src/mbgl/shader/outlinepattern_shader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <mbgl/shader/outlinepattern_shader.hpp>
-#include <mbgl/shader/outlinepattern.vertex.hpp>
-#include <mbgl/shader/outlinepattern.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-OutlinePatternShader::OutlinePatternShader(gl::Context& context, Defines defines)
- : Shader(shaders::outlinepattern::name,
- shaders::outlinepattern::vertex,
- shaders::outlinepattern::fragment,
- context, defines) {
-}
-
-void OutlinePatternShader::bind(GLbyte *offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/outlinepattern_shader.hpp b/src/mbgl/shader/outlinepattern_shader.hpp
deleted file mode 100644
index 795d390f19..0000000000
--- a/src/mbgl/shader/outlinepattern_shader.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-
-namespace mbgl {
-
-class OutlinePatternShader : public Shader {
-public:
- OutlinePatternShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
- Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
- Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_mix = {"u_mix", *this};
- Uniform<float> u_scale_a = {"u_scale_a", *this};
- Uniform<float> u_scale_b = {"u_scale_b", *this};
- Uniform<float> u_tile_units_to_pixels = {"u_tile_units_to_pixels", *this};
- Uniform<int32_t> u_image = {"u_image", *this};
- Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
- Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
- Uniform<std::array<float, 2>> u_pixel_coord_upper = {"u_pixel_coord_upper", *this};
- Uniform<std::array<float, 2>> u_pixel_coord_lower = {"u_pixel_coord_lower", *this};
- Uniform<std::array<float, 2>> u_world = {"u_world", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/pattern_shader.cpp b/src/mbgl/shader/pattern_shader.cpp
deleted file mode 100644
index dba12155f9..0000000000
--- a/src/mbgl/shader/pattern_shader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <mbgl/shader/pattern_shader.hpp>
-#include <mbgl/shader/pattern.vertex.hpp>
-#include <mbgl/shader/pattern.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-PatternShader::PatternShader(gl::Context& context, Defines defines)
- : Shader(shaders::pattern::name,
- shaders::pattern::vertex,
- shaders::pattern::fragment,
- context, defines) {
-}
-
-void PatternShader::bind(GLbyte *offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/pattern_shader.hpp b/src/mbgl/shader/pattern_shader.hpp
deleted file mode 100644
index 6ba141a2cb..0000000000
--- a/src/mbgl/shader/pattern_shader.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-
-namespace mbgl {
-
-class PatternShader : public Shader {
-public:
- PatternShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
- Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
- Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_mix = {"u_mix", *this};
- Uniform<float> u_scale_a = {"u_scale_a", *this};
- Uniform<float> u_scale_b = {"u_scale_b", *this};
- Uniform<float> u_tile_units_to_pixels = {"u_tile_units_to_pixels", *this};
- Uniform<int32_t> u_image = {"u_image", *this};
- Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
- Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
- Uniform<std::array<float, 2>> u_pixel_coord_upper = {"u_pixel_coord_upper", *this};
- Uniform<std::array<float, 2>> u_pixel_coord_lower = {"u_pixel_coord_lower", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/plain_shader.cpp b/src/mbgl/shader/plain_shader.cpp
deleted file mode 100644
index 8ea008c4ec..0000000000
--- a/src/mbgl/shader/plain_shader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <mbgl/shader/plain_shader.hpp>
-#include <mbgl/shader/fill.vertex.hpp>
-#include <mbgl/shader/fill.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-PlainShader::PlainShader(gl::Context& context, Defines defines)
- : Shader(shaders::fill::name,
- shaders::fill::vertex,
- shaders::fill::fragment,
- context, defines) {
-}
-
-void PlainShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/plain_shader.hpp b/src/mbgl/shader/plain_shader.hpp
deleted file mode 100644
index 2611a5a549..0000000000
--- a/src/mbgl/shader/plain_shader.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
-
-namespace mbgl {
-
-class PlainShader : public Shader {
-public:
- PlainShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/raster_shader.cpp b/src/mbgl/shader/raster_shader.cpp
index 8133b396c6..34b2bdf47b 100644
--- a/src/mbgl/shader/raster_shader.cpp
+++ b/src/mbgl/shader/raster_shader.cpp
@@ -1,7 +1,7 @@
#include <mbgl/shader/raster_shader.hpp>
#include <mbgl/shader/raster.vertex.hpp>
#include <mbgl/shader/raster.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/shader/raster_vertex.hpp>
namespace mbgl {
@@ -12,14 +12,4 @@ RasterShader::RasterShader(gl::Context& context, Defines defines)
context, defines) {
}
-void RasterShader::bind(int8_t* offset) {
- const GLint stride = 8;
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_texture_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_texture_pos, 2, GL_SHORT, false, stride, offset + 4));
-}
-
} // namespace mbgl
diff --git a/src/mbgl/shader/raster_shader.hpp b/src/mbgl/shader/raster_shader.hpp
index e583b2337d..9633fd5fa0 100644
--- a/src/mbgl/shader/raster_shader.hpp
+++ b/src/mbgl/shader/raster_shader.hpp
@@ -1,29 +1,35 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
namespace mbgl {
-class RasterShader : public Shader {
+class RasterVertex;
+
+class RasterShader : public gl::Shader {
public:
RasterShader(gl::Context&, Defines defines = None);
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<int32_t> u_image0 = {"u_image0", *this};
- Uniform<int32_t> u_image1 = {"u_image1", *this};
- Uniform<float> u_opacity0 = {"u_opacity0", *this};
- Uniform<float> u_opacity1 = {"u_opacity1", *this};
- Uniform<float> u_buffer_scale = {"u_buffer_scale", *this};
- Uniform<float> u_brightness_low = {"u_brightness_low", *this};
- Uniform<float> u_brightness_high = {"u_brightness_high", *this};
- Uniform<float> u_saturation_factor = {"u_saturation_factor", *this};
- Uniform<float> u_contrast_factor = {"u_contrast_factor", *this};
- Uniform<std::array<float, 3>> u_spin_weights = {"u_spin_weights", *this};
- Uniform<std::array<float, 2>> u_tl_parent = {"u_tl_parent", *this};
- Uniform<float> u_scale_parent = {"u_scale_parent", *this};
+ using VertexType = RasterVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<uint16_t, 2> a_texture_pos = { "a_texture_pos", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<int32_t> u_image0 = {"u_image0", *this};
+ gl::Uniform<int32_t> u_image1 = {"u_image1", *this};
+ gl::Uniform<float> u_opacity0 = {"u_opacity0", *this};
+ gl::Uniform<float> u_opacity1 = {"u_opacity1", *this};
+ gl::Uniform<float> u_buffer_scale = {"u_buffer_scale", *this};
+ gl::Uniform<float> u_brightness_low = {"u_brightness_low", *this};
+ gl::Uniform<float> u_brightness_high = {"u_brightness_high", *this};
+ gl::Uniform<float> u_saturation_factor = {"u_saturation_factor", *this};
+ gl::Uniform<float> u_contrast_factor = {"u_contrast_factor", *this};
+ gl::Uniform<std::array<float, 3>> u_spin_weights = {"u_spin_weights", *this};
+ gl::Uniform<std::array<float, 2>> u_tl_parent = {"u_tl_parent", *this};
+ gl::Uniform<float> u_scale_parent = {"u_scale_parent", *this};
};
} // namespace mbgl
diff --git a/src/mbgl/shader/raster_vertex.cpp b/src/mbgl/shader/raster_vertex.cpp
new file mode 100644
index 0000000000..fc9b1f11c2
--- /dev/null
+++ b/src/mbgl/shader/raster_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/raster_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(RasterVertex) == 8, "expected RasterVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/raster_vertex.hpp b/src/mbgl/shader/raster_vertex.hpp
new file mode 100644
index 0000000000..70e08c609d
--- /dev/null
+++ b/src/mbgl/shader/raster_vertex.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+
+namespace mbgl {
+
+class RasterVertex {
+public:
+ RasterVertex(int16_t x, int16_t y, uint16_t tx, uint16_t ty)
+ : a_pos {
+ x,
+ y
+ },
+ a_texture_pos {
+ tx,
+ ty
+ } {}
+
+ const int16_t a_pos[2];
+ const uint16_t a_texture_pos[2];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, RasterVertex> {
+ std::array<AttributeBinding, 2> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(RasterVertex, shader, a_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(RasterVertex, shader, a_texture_pos)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/sdf_shader.cpp b/src/mbgl/shader/sdf_shader.cpp
deleted file mode 100644
index 3b4aa69535..0000000000
--- a/src/mbgl/shader/sdf_shader.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <mbgl/shader/sdf_shader.hpp>
-#include <mbgl/shader/sdf.vertex.hpp>
-#include <mbgl/shader/sdf.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-SDFShader::SDFShader(gl::Context& context, Defines defines)
- : Shader(shaders::sdf::name,
- shaders::sdf::vertex,
- shaders::sdf::fragment,
- context, defines) {
-}
-
-void SDFShader::bind(int8_t* offset) {
- const int stride = 16;
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_offset));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_offset, 2, GL_SHORT, false, stride, offset + 4));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_texture_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_texture_pos, 2, GL_UNSIGNED_SHORT, false, stride, offset + 8));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, stride, offset + 12));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/sdf_shader.hpp b/src/mbgl/shader/sdf_shader.hpp
deleted file mode 100644
index f7fde3e539..0000000000
--- a/src/mbgl/shader/sdf_shader.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
-
-namespace mbgl {
-
-class SDFShader : public Shader {
-public:
- SDFShader(gl::Context&, Defines defines = None);
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
- Uniform<float> u_buffer = {"u_buffer", *this};
- Uniform<float> u_gamma = {"u_gamma", *this};
- Uniform<float> u_zoom = {"u_zoom", *this};
- Uniform<float> u_pitch = {"u_pitch", *this};
- Uniform<float> u_bearing = {"u_bearing", *this};
- Uniform<float> u_aspect_ratio = {"u_aspect_ratio", *this};
- Uniform<int32_t> u_rotate_with_map = {"u_rotate_with_map", *this};
- Uniform<int32_t> u_pitch_with_map = {"u_pitch_with_map", *this};
- Uniform<int32_t> u_texture = {"u_texture", *this};
- Uniform<int32_t> u_fadetexture = {"u_fadetexture", *this};
-
- void bind(int8_t* offset) final;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/shader.hpp b/src/mbgl/shader/shader.hpp
deleted file mode 100644
index 91dd8ed518..0000000000
--- a/src/mbgl/shader/shader.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/types.hpp>
-#include <mbgl/gl/object.hpp>
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/optional.hpp>
-
-namespace mbgl {
-
-namespace gl {
-class Context;
-} // namespace gl
-
-class Shader : private util::noncopyable {
-public:
- ~Shader();
- const char* name;
-
- gl::ProgramID getID() const {
- return program.get();
- }
-
- gl::UniformLocation getUniformLocation(const char* uniform) const;
-
- virtual void bind(int8_t *offset) = 0;
-
- enum Defines : bool {
- None = false,
- Overdraw = true,
- };
-
-protected:
- Shader(const char* name_,
- const char* vertex,
- const char* fragment,
- gl::Context&,
- Defines defines = Defines::None);
-
- static constexpr gl::AttributeLocation a_pos = 0;
- static constexpr gl::AttributeLocation a_extrude = 1;
- static constexpr gl::AttributeLocation a_offset = 2;
- static constexpr gl::AttributeLocation a_data = 3;
- static constexpr gl::AttributeLocation a_texture_pos = 4;
-
-private:
- bool compileShader(gl::UniqueShader&, const char *source);
-
- gl::UniqueProgram program;
- gl::UniqueShader vertexShader;
- gl::UniqueShader fragmentShader;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/shaders.hpp b/src/mbgl/shader/shaders.hpp
index cf80a00d97..937ee85f44 100644
--- a/src/mbgl/shader/shaders.hpp
+++ b/src/mbgl/shader/shaders.hpp
@@ -1,56 +1,58 @@
#pragma once
-#include <mbgl/shader/pattern_shader.hpp>
-#include <mbgl/shader/plain_shader.hpp>
-#include <mbgl/shader/outline_shader.hpp>
-#include <mbgl/shader/outlinepattern_shader.hpp>
+#include <mbgl/shader/circle_shader.hpp>
+#include <mbgl/shader/fill_shader.hpp>
+#include <mbgl/shader/fill_pattern_shader.hpp>
+#include <mbgl/shader/fill_outline_shader.hpp>
+#include <mbgl/shader/fill_outline_pattern_shader.hpp>
#include <mbgl/shader/line_shader.hpp>
-#include <mbgl/shader/linesdf_shader.hpp>
-#include <mbgl/shader/linepattern_shader.hpp>
-#include <mbgl/shader/icon_shader.hpp>
+#include <mbgl/shader/line_sdf_shader.hpp>
+#include <mbgl/shader/line_pattern_shader.hpp>
#include <mbgl/shader/raster_shader.hpp>
-#include <mbgl/shader/sdf_shader.hpp>
+#include <mbgl/shader/symbol_icon_shader.hpp>
+#include <mbgl/shader/symbol_sdf_shader.hpp>
+
#include <mbgl/shader/collision_box_shader.hpp>
-#include <mbgl/shader/circle_shader.hpp>
namespace mbgl {
class Shaders {
public:
- Shaders(gl::Context& context, Shader::Defines defines = Shader::None)
- : plain(context, defines),
- outline(context, defines),
- outlinePattern(context, defines),
+ Shaders(gl::Context& context, gl::Shader::Defines defines = gl::Shader::None)
+ : circle(context, defines),
+ fill(context, defines),
+ fillPattern(context, defines),
+ fillOutline(context, defines),
+ fillOutlinePattern(context, defines),
line(context, defines),
- linesdf(context, defines),
- linepattern(context, defines),
- pattern(context, defines),
- icon(context, defines),
+ lineSDF(context, defines),
+ linePattern(context, defines),
raster(context, defines),
- sdfGlyph(context, defines),
- sdfIcon(context, defines),
- collisionBox(context),
- circle(context, defines) {
+ symbolIcon(context, defines),
+ symbolIconSDF(context, defines),
+ symbolGlyph(context, defines),
+ collisionBox(context) {
}
- PlainShader plain;
- OutlineShader outline;
- OutlinePatternShader outlinePattern;
+ CircleShader circle;
+ FillShader fill;
+ FillPatternShader fillPattern;
+ FillOutlineShader fillOutline;
+ FillOutlinePatternShader fillOutlinePattern;
LineShader line;
- LineSDFShader linesdf;
- LinepatternShader linepattern;
- PatternShader pattern;
- IconShader icon;
+ LineSDFShader lineSDF;
+ LinePatternShader linePattern;
RasterShader raster;
- SDFShader sdfGlyph;
- SDFShader sdfIcon;
+ SymbolIconShader symbolIcon;
+ SymbolSDFShader symbolIconSDF;
+ SymbolSDFShader symbolGlyph;
+
CollisionBoxShader collisionBox;
- CircleShader circle;
- VertexArrayObject coveringPlainArray;
- VertexArrayObject coveringRasterArray;
- VertexArrayObject backgroundPatternArray;
- VertexArrayObject backgroundArray;
+ gl::VertexArrayObject coveringPlainArray;
+ gl::VertexArrayObject coveringRasterArray;
+ gl::VertexArrayObject backgroundPatternArray;
+ gl::VertexArrayObject backgroundArray;
};
} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_icon_shader.cpp b/src/mbgl/shader/symbol_icon_shader.cpp
new file mode 100644
index 0000000000..2655a1c9b5
--- /dev/null
+++ b/src/mbgl/shader/symbol_icon_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/symbol_icon_shader.hpp>
+#include <mbgl/shader/symbol_icon.vertex.hpp>
+#include <mbgl/shader/symbol_icon.fragment.hpp>
+#include <mbgl/shader/symbol_vertex.hpp>
+
+namespace mbgl {
+
+SymbolIconShader::SymbolIconShader(gl::Context& context, Defines defines)
+ : Shader(shaders::symbol_icon::name,
+ shaders::symbol_icon::vertex,
+ shaders::symbol_icon::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_icon_shader.hpp b/src/mbgl/shader/symbol_icon_shader.hpp
new file mode 100644
index 0000000000..5281beb60c
--- /dev/null
+++ b/src/mbgl/shader/symbol_icon_shader.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+
+namespace mbgl {
+
+class SymbolVertex;
+
+class SymbolIconShader : public gl::Shader {
+public:
+ SymbolIconShader(gl::Context&, Defines defines = None);
+
+ using VertexType = SymbolVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<int16_t, 2> a_offset = { "a_offset", *this };
+ gl::Attribute<uint16_t, 2> a_texture_pos = { "a_texture_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
+ gl::Uniform<float> u_zoom = {"u_zoom", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
+ gl::Uniform<int32_t> u_rotate_with_map = {"u_rotate_with_map", *this};
+ gl::Uniform<int32_t> u_texture = {"u_texture", *this};
+ gl::Uniform<int32_t> u_fadetexture = {"u_fadetexture", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_sdf_shader.cpp b/src/mbgl/shader/symbol_sdf_shader.cpp
new file mode 100644
index 0000000000..63c3bd5a4a
--- /dev/null
+++ b/src/mbgl/shader/symbol_sdf_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/symbol_sdf_shader.hpp>
+#include <mbgl/shader/symbol_sdf.vertex.hpp>
+#include <mbgl/shader/symbol_sdf.fragment.hpp>
+#include <mbgl/shader/symbol_vertex.hpp>
+
+namespace mbgl {
+
+SymbolSDFShader::SymbolSDFShader(gl::Context& context, Defines defines)
+ : Shader(shaders::symbol_sdf::name,
+ shaders::symbol_sdf::vertex,
+ shaders::symbol_sdf::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_sdf_shader.hpp b/src/mbgl/shader/symbol_sdf_shader.hpp
new file mode 100644
index 0000000000..8d3b3df939
--- /dev/null
+++ b/src/mbgl/shader/symbol_sdf_shader.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+
+class SymbolVertex;
+
+class SymbolSDFShader : public gl::Shader {
+public:
+ SymbolSDFShader(gl::Context&, Defines defines = None);
+
+ using VertexType = SymbolVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<int16_t, 2> a_offset = { "a_offset", *this };
+ gl::Attribute<uint16_t, 2> a_texture_pos = { "a_texture_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
+ gl::Uniform<float> u_buffer = {"u_buffer", *this};
+ gl::Uniform<float> u_gamma = {"u_gamma", *this};
+ gl::Uniform<float> u_zoom = {"u_zoom", *this};
+ gl::Uniform<float> u_pitch = {"u_pitch", *this};
+ gl::Uniform<float> u_bearing = {"u_bearing", *this};
+ gl::Uniform<float> u_aspect_ratio = {"u_aspect_ratio", *this};
+ gl::Uniform<int32_t> u_rotate_with_map = {"u_rotate_with_map", *this};
+ gl::Uniform<int32_t> u_pitch_with_map = {"u_pitch_with_map", *this};
+ gl::Uniform<int32_t> u_texture = {"u_texture", *this};
+ gl::Uniform<int32_t> u_fadetexture = {"u_fadetexture", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_vertex.cpp b/src/mbgl/shader/symbol_vertex.cpp
new file mode 100644
index 0000000000..4075d749ea
--- /dev/null
+++ b/src/mbgl/shader/symbol_vertex.cpp
@@ -0,0 +1,9 @@
+#include <mbgl/shader/symbol_vertex.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/gl.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(SymbolVertex) == 16, "expected SymbolVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_vertex.hpp b/src/mbgl/shader/symbol_vertex.hpp
new file mode 100644
index 0000000000..4eba86f946
--- /dev/null
+++ b/src/mbgl/shader/symbol_vertex.hpp
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+#include <cmath>
+
+namespace mbgl {
+
+class SymbolVertex {
+public:
+ SymbolVertex(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle)
+ : a_pos {
+ x,
+ y
+ },
+ a_offset {
+ static_cast<int16_t>(::round(ox * 64)), // use 1/64 pixels for placement
+ static_cast<int16_t>(::round(oy * 64))
+ },
+ a_texture_pos {
+ static_cast<uint16_t>(tx / 4),
+ static_cast<uint16_t>(ty / 4)
+ },
+ a_data {
+ static_cast<uint8_t>(labelminzoom * 10), // 1/10 zoom levels: z16 == 160
+ static_cast<uint8_t>(labelangle),
+ static_cast<uint8_t>(minzoom * 10),
+ static_cast<uint8_t>(::fmin(maxzoom, 25) * 10)
+ } {}
+
+ const int16_t a_pos[2];
+ const int16_t a_offset[2];
+ const uint16_t a_texture_pos[2];
+ const uint8_t a_data[4];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, SymbolVertex> {
+ std::array<AttributeBinding, 4> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(SymbolVertex, shader, a_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(SymbolVertex, shader, a_offset),
+ MBGL_MAKE_ATTRIBUTE_BINDING(SymbolVertex, shader, a_texture_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(SymbolVertex, shader, a_data)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/style/layer_impl.hpp b/src/mbgl/style/layer_impl.hpp
index 55b1ff058c..4bf2956a6d 100644
--- a/src/mbgl/style/layer_impl.hpp
+++ b/src/mbgl/style/layer_impl.hpp
@@ -69,7 +69,7 @@ public:
virtual float getQueryRadius() const { return 0; }
virtual bool queryIntersectsGeometry(
- const GeometryCollection&,
+ const GeometryCoordinates&,
const GeometryCollection&,
const float,
const float) const { return false; };
diff --git a/src/mbgl/style/layers/circle_layer_impl.cpp b/src/mbgl/style/layers/circle_layer_impl.cpp
index e08d9df146..33699b6665 100644
--- a/src/mbgl/style/layers/circle_layer_impl.cpp
+++ b/src/mbgl/style/layers/circle_layer_impl.cpp
@@ -40,7 +40,7 @@ float CircleLayer::Impl::getQueryRadius() const {
}
bool CircleLayer::Impl::queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const {
@@ -50,7 +50,7 @@ bool CircleLayer::Impl::queryIntersectsGeometry(
auto circleRadius = paint.circleRadius * pixelsToTileUnits;
- return util::multiPolygonIntersectsBufferedMultiPoint(
+ return util::polygonIntersectsBufferedMultiPoint(
translatedQueryGeometry.value_or(queryGeometry), geometry, circleRadius);
}
diff --git a/src/mbgl/style/layers/circle_layer_impl.hpp b/src/mbgl/style/layers/circle_layer_impl.hpp
index 555691b6b4..14baaf84e4 100644
--- a/src/mbgl/style/layers/circle_layer_impl.hpp
+++ b/src/mbgl/style/layers/circle_layer_impl.hpp
@@ -19,7 +19,7 @@ public:
float getQueryRadius() const override;
bool queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const override;
diff --git a/src/mbgl/style/layers/fill_layer_impl.cpp b/src/mbgl/style/layers/fill_layer_impl.cpp
index 2992312514..fc439f1cd1 100644
--- a/src/mbgl/style/layers/fill_layer_impl.cpp
+++ b/src/mbgl/style/layers/fill_layer_impl.cpp
@@ -49,7 +49,7 @@ float FillLayer::Impl::getQueryRadius() const {
}
bool FillLayer::Impl::queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const {
@@ -57,7 +57,7 @@ bool FillLayer::Impl::queryIntersectsGeometry(
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
queryGeometry, paint.fillTranslate, paint.fillTranslateAnchor, bearing, pixelsToTileUnits);
- return util::multiPolygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry);
+ return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry);
}
} // namespace style
diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp
index fc6578ecd1..54cfb80c86 100644
--- a/src/mbgl/style/layers/fill_layer_impl.hpp
+++ b/src/mbgl/style/layers/fill_layer_impl.hpp
@@ -19,7 +19,7 @@ public:
float getQueryRadius() const override;
bool queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const override;
diff --git a/src/mbgl/style/layers/line_layer_impl.cpp b/src/mbgl/style/layers/line_layer_impl.cpp
index 3cdd90b7fd..c116af5fc2 100644
--- a/src/mbgl/style/layers/line_layer_impl.cpp
+++ b/src/mbgl/style/layers/line_layer_impl.cpp
@@ -87,7 +87,7 @@ float LineLayer::Impl::getQueryRadius() const {
}
bool LineLayer::Impl::queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const {
@@ -98,7 +98,7 @@ bool LineLayer::Impl::queryIntersectsGeometry(
queryGeometry, paint.lineTranslate, paint.lineTranslateAnchor, bearing, pixelsToTileUnits);
auto offsetGeometry = offsetLine(geometry, paint.lineOffset * pixelsToTileUnits);
- return util::multiPolygonIntersectsBufferedMultiLine(
+ return util::polygonIntersectsBufferedMultiLine(
translatedQueryGeometry.value_or(queryGeometry),
offsetGeometry.value_or(geometry),
halfWidth);
diff --git a/src/mbgl/style/layers/line_layer_impl.hpp b/src/mbgl/style/layers/line_layer_impl.hpp
index e130bc01bc..c6b4be3bec 100644
--- a/src/mbgl/style/layers/line_layer_impl.hpp
+++ b/src/mbgl/style/layers/line_layer_impl.hpp
@@ -19,7 +19,7 @@ public:
float getQueryRadius() const override;
bool queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const override;
diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp
index 58ae3d9f91..1fb6d59f0e 100644
--- a/src/mbgl/style/source_impl.cpp
+++ b/src/mbgl/style/source_impl.cpp
@@ -176,26 +176,13 @@ void Source::Impl::reloadTiles() {
cache.clear();
for (auto& pair : tiles) {
- auto tile = pair.second.get();
- tile->redoLayout();
+ pair.second->redoLayout();
}
}
-static Point<int16_t> coordinateToTilePoint(const UnwrappedTileID& tileID, const Point<double>& p) {
- auto zoomedCoord = TileCoordinate { p, 0 }.zoomTo(tileID.canonical.z);
- return {
- int16_t(util::clamp<int64_t>((zoomedCoord.p.x - tileID.canonical.x - tileID.wrap * std::pow(2, tileID.canonical.z)) * util::EXTENT,
- std::numeric_limits<int16_t>::min(),
- std::numeric_limits<int16_t>::max())),
- int16_t(util::clamp<int64_t>((zoomedCoord.p.y - tileID.canonical.y) * util::EXTENT,
- std::numeric_limits<int16_t>::min(),
- std::numeric_limits<int16_t>::max()))
- };
-}
-
std::unordered_map<std::string, std::vector<Feature>> Source::Impl::queryRenderedFeatures(const QueryParameters& parameters) const {
std::unordered_map<std::string, std::vector<Feature>> result;
- if (renderTiles.empty()) {
+ if (renderTiles.empty() || parameters.geometry.empty()) {
return result;
}
@@ -206,31 +193,30 @@ std::unordered_map<std::string, std::vector<Feature>> Source::Impl::queryRendere
parameters.transformState, 0, { p.x, parameters.transformState.getHeight() - p.y }).p);
}
- if (queryGeometry.empty()) {
- return result;
- }
-
mapbox::geometry::box<double> box = mapbox::geometry::envelope(queryGeometry);
for (const auto& tilePtr : renderTiles) {
- const RenderTile& tile = tilePtr.second;
-
- Point<int16_t> tileSpaceBoundsMin = coordinateToTilePoint(tile.id, box.min);
- Point<int16_t> tileSpaceBoundsMax = coordinateToTilePoint(tile.id, box.max);
+ const RenderTile& renderTile = tilePtr.second;
+ GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min);
+ if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT) {
+ continue;
+ }
- if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT ||
- tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) continue;
+ GeometryCoordinate tileSpaceBoundsMax = TileCoordinate::toGeometryCoordinate(renderTile.id, box.max);
+ if (tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) {
+ continue;
+ }
GeometryCoordinates tileSpaceQueryGeometry;
-
+ tileSpaceQueryGeometry.reserve(queryGeometry.size());
for (const auto& c : queryGeometry) {
- tileSpaceQueryGeometry.push_back(coordinateToTilePoint(tile.id, c));
+ tileSpaceQueryGeometry.push_back(TileCoordinate::toGeometryCoordinate(renderTile.id, c));
}
- tile.tile.queryRenderedFeatures(result,
- tileSpaceQueryGeometry,
- parameters.transformState,
- parameters.layerIDs);
+ renderTile.tile.queryRenderedFeatures(result,
+ tileSpaceQueryGeometry,
+ parameters.transformState,
+ parameters.layerIDs);
}
return result;
@@ -261,8 +247,7 @@ void Source::Impl::dumpDebugLogs() const {
Log::Info(Event::General, "Source::loaded: %d", loaded);
for (const auto& pair : tiles) {
- auto& tile = pair.second;
- tile->dumpDebugLogs();
+ pair.second->dumpDebugLogs();
}
}
diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp
index 32a1a5474a..d6fc1a6ada 100644
--- a/src/mbgl/text/collision_tile.cpp
+++ b/src/mbgl/text/collision_tile.cpp
@@ -2,6 +2,10 @@
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/math.hpp>
+#include <mbgl/math/minmax.hpp>
+
+#include <mapbox/geometry/envelope.hpp>
+#include <mapbox/geometry/multi_point.hpp>
#include <cmath>
@@ -20,7 +24,6 @@ CollisionTile::CollisionTile(PlacementConfig config_) : config(std::move(config_
// bottom
CollisionBox(Point<float>(0, util::EXTENT), -infinity, 0, infinity, 0, infinity),
}}) {
- tree.clear();
// Compute the transformation matrix.
const float angle_sin = std::sin(config.angle);
@@ -51,7 +54,7 @@ float CollisionTile::findPlacementScale(float minPlacementScale, const Point<flo
if (std::isnan(s1) || std::isnan(s2)) s1 = s2 = 1;
if (std::isnan(s3) || std::isnan(s4)) s3 = s4 = 1;
- float collisionFreeScale = ::fmin(::fmax(s1, s2), ::fmax(s3, s4));
+ float collisionFreeScale = util::min(util::max(s1, s2), util::max(s3, s4));
if (collisionFreeScale > blocking.maxScale) {
// After a box's maxScale the label has shrunk enough that the box is no longer needed to cover it,
@@ -104,10 +107,10 @@ float CollisionTile::placeFeature(const CollisionFeature& feature, const bool al
const Point<float> rbl = util::matrixMultiply(reverseRotationMatrix, bl);
const Point<float> rbr = util::matrixMultiply(reverseRotationMatrix, br);
CollisionBox rotatedBox(box.anchor,
- ::fmin(::fmin(rtl.x, rtr.x), ::fmin(rbl.x, rbr.x)),
- ::fmin(::fmin(rtl.y, rtr.y), ::fmin(rbl.y, rbr.y)),
- ::fmax(::fmax(rtl.x, rtr.x), ::fmax(rbl.x, rbr.x)),
- ::fmax(::fmax(rtl.y, rtr.y), ::fmax(rbl.y, rbr.y)),
+ util::min(rtl.x, rtr.x, rbl.x, rbr.x),
+ util::min(rtl.y, rtr.y, rbl.y, rbr.y),
+ util::max(rtl.x, rtr.x, rbl.x, rbr.x),
+ util::max(rtl.y, rtr.y, rbl.y, rbr.y),
box.maxScale);
for (auto& blocking : edges) {
@@ -153,34 +156,49 @@ Box CollisionTile::getTreeBox(const Point<float>& anchor, const CollisionBox& bo
};
}
-std::vector<IndexedSubfeature> CollisionTile::queryRenderedSymbols(const mapbox::geometry::box<int16_t>& box, const float scale) {
+std::vector<IndexedSubfeature> CollisionTile::queryRenderedSymbols(const GeometryCoordinates& queryGeometry, const float scale) {
std::vector<IndexedSubfeature> result;
+ if (queryGeometry.empty()) return result;
+
std::unordered_map<std::string, std::unordered_set<std::size_t>> sourceLayerFeatures;
- auto anchor = util::matrixMultiply(rotationMatrix, convertPoint<float>(box.min));
+ mapbox::geometry::multi_point<float> rotatedPoints {};
+ rotatedPoints.reserve(queryGeometry.size());
+ std::transform(queryGeometry.cbegin(), queryGeometry.cend(), std::back_inserter(rotatedPoints),
+ [&](const auto& c) { return util::matrixMultiply(rotationMatrix, convertPoint<float>(c)); });
+ const auto box = mapbox::geometry::envelope(rotatedPoints);
+
+ const auto& anchor = box.min;
CollisionBox queryBox(anchor, 0, 0, box.max.x - box.min.x, box.max.y - box.min.y, scale);
auto predicates = bgi::intersects(getTreeBox(anchor, queryBox));
- auto fn = [&] (const Tree& tree_) {
+ auto fn = [&] (const Tree& tree_, bool ignorePlacement) {
for (auto it = tree_.qbegin(predicates); it != tree_.qend(); ++it) {
const CollisionBox& blocking = std::get<1>(*it);
const IndexedSubfeature& indexedFeature = std::get<2>(*it);
auto& seenFeatures = sourceLayerFeatures[indexedFeature.sourceLayerName];
if (seenFeatures.find(indexedFeature.index) == seenFeatures.end()) {
- auto blockingAnchor = util::matrixMultiply(rotationMatrix, blocking.anchor);
- float minPlacementScale = findPlacementScale(minScale, anchor, queryBox, blockingAnchor, blocking);
- if (minPlacementScale >= scale) {
+ if (ignorePlacement) {
seenFeatures.insert(indexedFeature.index);
result.push_back(indexedFeature);
+ } else {
+ auto blockingAnchor = util::matrixMultiply(rotationMatrix, blocking.anchor);
+ float minPlacementScale = findPlacementScale(minScale, anchor, queryBox, blockingAnchor, blocking);
+ if (minPlacementScale >= scale) {
+ seenFeatures.insert(indexedFeature.index);
+ result.push_back(indexedFeature);
+ }
}
}
}
};
- fn(tree);
- fn(ignoredTree);
+ bool ignorePlacement = false;
+ fn(tree, ignorePlacement);
+ ignorePlacement = true;
+ fn(ignoredTree, ignorePlacement);
return result;
}
diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp
index 7450fb1b86..dbc23b2a79 100644
--- a/src/mbgl/text/collision_tile.hpp
+++ b/src/mbgl/text/collision_tile.hpp
@@ -2,6 +2,7 @@
#include <mbgl/text/collision_feature.hpp>
#include <mbgl/text/placement_config.hpp>
+#include <mbgl/tile/geometry_tile_data.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
@@ -41,7 +42,7 @@ public:
float placeFeature(const CollisionFeature&, const bool allowOverlap, const bool avoidEdges);
void insertFeature(CollisionFeature&, const float minPlacementScale, const bool ignorePlacement);
- std::vector<IndexedSubfeature> queryRenderedSymbols(const mapbox::geometry::box<int16_t>&, const float scale);
+ std::vector<IndexedSubfeature> queryRenderedSymbols(const GeometryCoordinates&, const float scale);
const PlacementConfig config;
@@ -49,6 +50,10 @@ public:
const float maxScale = 2.0f;
float yStretch;
+ std::array<float, 4> rotationMatrix;
+ std::array<float, 4> reverseRotationMatrix;
+ std::array<CollisionBox, 4> edges;
+
private:
float findPlacementScale(float minPlacementScale,
const Point<float>& anchor, const CollisionBox& box,
@@ -57,9 +62,6 @@ private:
Tree tree;
Tree ignoredTree;
- std::array<float, 4> rotationMatrix;
- std::array<float, 4> reverseRotationMatrix;
- std::array<CollisionBox, 4> edges;
};
} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 1f64b6b6c6..46e2b414fe 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -136,7 +136,7 @@ void GeometryTile::queryRenderedFeatures(
if (!featureIndex || !data) return;
featureIndex->query(result,
- { queryGeometry },
+ queryGeometry,
transformState.getAngle(),
util::tileSize * id.overscaleFactor(),
std::pow(2, transformState.getZoom() - id.overscaledZ),
diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp
index ec0540b1ad..1375263107 100644
--- a/src/mbgl/tile/tile.cpp
+++ b/src/mbgl/tile/tile.cpp
@@ -2,6 +2,7 @@
#include <mbgl/tile/tile_observer.hpp>
#include <mbgl/renderer/debug_bucket.hpp>
#include <mbgl/util/string.hpp>
+#include <mbgl/platform/log.hpp>
namespace mbgl {
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index be03608994..949bc0e334 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -4,6 +4,7 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/feature.hpp>
+#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
diff --git a/src/mbgl/util/intersection_tests.cpp b/src/mbgl/util/intersection_tests.cpp
index 74b3bec388..a0feb8ec37 100644
--- a/src/mbgl/util/intersection_tests.cpp
+++ b/src/mbgl/util/intersection_tests.cpp
@@ -90,54 +90,47 @@ bool lineIntersectsBufferedLine(const GeometryCoordinates& lineA, const Geometry
return false;
}
-bool multiPolygonIntersectsBufferedMultiPoint(const GeometryCollection& multiPolygon, const GeometryCollection& rings, float radius) {
- for (auto& polygon : multiPolygon) {
- for (auto& ring : rings) {
- for (auto& point : ring) {
- if (polygonContainsPoint(polygon, point)) return true;
- if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
- }
+bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates& polygon, const GeometryCollection& rings, float radius) {
+ for (auto& ring : rings) {
+ for (auto& point : ring) {
+ if (polygonContainsPoint(polygon, point)) return true;
+ if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
}
}
return false;
}
-bool multiPolygonIntersectsBufferedMultiLine(const GeometryCollection& multiPolygon, const GeometryCollection& multiLine, float radius) {
+bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates& polygon, const GeometryCollection& multiLine, float radius) {
for (auto& line : multiLine) {
- for (auto& polygon : multiPolygon) {
-
- if (polygon.size() >= 3) {
- for (auto& p : line) {
- if (polygonContainsPoint(polygon, p)) return true;
- }
+ if (polygon.size() >= 3) {
+ for (auto& p : line) {
+ if (polygonContainsPoint(polygon, p)) return true;
}
-
- if (lineIntersectsBufferedLine(polygon, line, radius)) return true;
}
+
+ if (lineIntersectsBufferedLine(polygon, line, radius)) return true;
}
return false;
}
-bool multiPolygonIntersectsMultiPolygon(const GeometryCollection& multiPolygonA, const GeometryCollection& multiPolygonB) {
- if (multiPolygonA.size() == 1 && multiPolygonA.at(0).size() == 1) {
- return multiPolygonContainsPoint(multiPolygonB, multiPolygonA.at(0).at(0));
+bool polygonIntersectsMultiPolygon(const GeometryCoordinates& polygon, const GeometryCollection& multiPolygon) {
+ if (polygon.size() == 1) {
+ return multiPolygonContainsPoint(multiPolygon, polygon.at(0));
}
- for (auto& ring : multiPolygonB) {
+ for (auto& ring : multiPolygon) {
for (auto& p : ring) {
- if (multiPolygonContainsPoint(multiPolygonA, p)) return true;
+ if (polygonContainsPoint(polygon, p)) return true;
}
}
- for (auto& polygon : multiPolygonA) {
- for (auto& p : polygon) {
- if (multiPolygonContainsPoint(multiPolygonB, p)) return true;
- }
+ for (auto& p : polygon) {
+ if (multiPolygonContainsPoint(multiPolygon, p)) return true;
+ }
- for (auto& polygonB : multiPolygonB) {
- if (lineIntersectsLine(polygon, polygonB)) return true;
- }
+ for (auto& polygonB : multiPolygon) {
+ if (lineIntersectsLine(polygon, polygonB)) return true;
}
return false;
diff --git a/src/mbgl/util/intersection_tests.hpp b/src/mbgl/util/intersection_tests.hpp
index be89d14ed6..6adb3b5fdf 100644
--- a/src/mbgl/util/intersection_tests.hpp
+++ b/src/mbgl/util/intersection_tests.hpp
@@ -5,9 +5,9 @@
namespace mbgl {
namespace util {
-bool multiPolygonIntersectsBufferedMultiPoint(const GeometryCollection&, const GeometryCollection&, float radius);
-bool multiPolygonIntersectsBufferedMultiLine(const GeometryCollection&, const GeometryCollection&, float radius);
-bool multiPolygonIntersectsMultiPolygon(const GeometryCollection&, const GeometryCollection&);
+bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates&, const GeometryCollection&, float radius);
+bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates&, const GeometryCollection&, float radius);
+bool polygonIntersectsMultiPolygon(const GeometryCoordinates&, const GeometryCollection&);
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/util/tile_coordinate.hpp b/src/mbgl/util/tile_coordinate.hpp
index df240a50e0..194a62ecef 100644
--- a/src/mbgl/util/tile_coordinate.hpp
+++ b/src/mbgl/util/tile_coordinate.hpp
@@ -1,15 +1,20 @@
#pragma once
-#include <mbgl/util/geometry.hpp>
#include <mbgl/map/transform_state.hpp>
+#include <mbgl/math/clamp.hpp>
+#include <mbgl/tile/geometry_tile_data.hpp>
+#include <mbgl/tile/tile_id.hpp>
+#include <mbgl/util/geometry.hpp>
namespace mbgl {
+using TileCoordinatePoint = Point<double>;
+
// Has floating point x/y coordinates.
// Used for computing the tiles that need to be visible in the viewport.
class TileCoordinate {
public:
- Point<double> p;
+ TileCoordinatePoint p;
double z;
static TileCoordinate fromLatLng(const TransformState& state, double zoom, const LatLng& latLng) {
@@ -17,13 +22,25 @@ public:
return { state.project(latLng) * scale / double(util::tileSize), zoom };
}
- static TileCoordinate fromScreenCoordinate(const TransformState& state, double zoom, const ScreenCoordinate& point) {
- return fromLatLng(state, zoom, state.screenCoordinateToLatLng(point));
+ static TileCoordinate fromScreenCoordinate(const TransformState& state, double zoom, const ScreenCoordinate& screenCoordinate) {
+ return fromLatLng(state, zoom, state.screenCoordinateToLatLng(screenCoordinate));
}
TileCoordinate zoomTo(double zoom) const {
return { p * std::pow(2, zoom - z), zoom };
}
+
+ static GeometryCoordinate toGeometryCoordinate(const UnwrappedTileID& tileID, const TileCoordinatePoint& point) {
+ auto zoomed = TileCoordinate { point, 0 }.zoomTo(tileID.canonical.z);
+ return {
+ int16_t(util::clamp<int64_t>((zoomed.p.x - tileID.canonical.x - tileID.wrap * std::pow(2.0, tileID.canonical.z)) * util::EXTENT,
+ std::numeric_limits<int16_t>::min(),
+ std::numeric_limits<int16_t>::max())),
+ int16_t(util::clamp<int64_t>((zoomed.p.y - tileID.canonical.y) * util::EXTENT,
+ std::numeric_limits<int16_t>::min(),
+ std::numeric_limits<int16_t>::max()))
+ };
+ }
};
} // namespace mbgl