diff options
Diffstat (limited to 'src')
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 |