diff options
Diffstat (limited to 'src/mbgl/renderer/buckets')
-rw-r--r-- | src/mbgl/renderer/buckets/raster_bucket.cpp | 65 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/raster_bucket.hpp | 4 |
2 files changed, 68 insertions, 1 deletions
diff --git a/src/mbgl/renderer/buckets/raster_bucket.cpp b/src/mbgl/renderer/buckets/raster_bucket.cpp index 3f5879262d..1a0409f456 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.cpp +++ b/src/mbgl/renderer/buckets/raster_bucket.cpp @@ -22,7 +22,7 @@ void RasterBucket::upload(gl::Context& context) { if (!texture) { texture = context.createTexture(*image); } - if (!vertices.empty()) { + if (!segments.empty()) { vertexBuffer = context.createVertexBuffer(std::move(vertices)); indexBuffer = context.createIndexBuffer(std::move(indices)); } @@ -45,6 +45,69 @@ void RasterBucket::setImage(std::shared_ptr<PremultipliedImage> image_) { uploaded = false; } +void RasterBucket::setMask(TileMask&& mask_) { + if (mask == mask_) { + return; + } + + mask = std::move(mask_); + clear(); + + if (mask == TileMask{ { 0, 0, 0 } }) { + // We want to render the full tile, and keeping the segments/vertices/indices empty means + // using the global shared buffers for covering the entire tile. + return; + } + + // Create a new segment so that we will upload (empty) buffers even when there is nothing to + // draw for this tile. + segments.emplace_back(0, 0); + + constexpr const uint16_t vertexLength = 4; + + // Create the vertex buffer for the specified tile mask. + for (const auto& id : mask) { + // Create a quad for every masked tile. + const int32_t vertexExtent = util::EXTENT >> id.z; + const int32_t textureExtent = 32768 >> id.z; + + const Point<int16_t> tlVertex = { static_cast<int16_t>(id.x * vertexExtent), + static_cast<int16_t>(id.y * vertexExtent) }; + const Point<int16_t> brVertex = { static_cast<int16_t>(tlVertex.x + vertexExtent), + static_cast<int16_t>(tlVertex.y + vertexExtent) }; + const Point<uint16_t> tlTexture = { static_cast<uint16_t>(id.x * textureExtent), + static_cast<uint16_t>(id.y * textureExtent) }; + const Point<uint16_t> brTexture = { static_cast<uint16_t>(tlTexture.x + textureExtent), + static_cast<uint16_t>(tlTexture.y + textureExtent) }; + + if (segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) { + // Move to a new segments because the old one can't hold the geometry. + segments.emplace_back(vertices.vertexSize(), indices.indexSize()); + } + + vertices.emplace_back( + RasterProgram::layoutVertex({ tlVertex.x, tlVertex.y }, { tlTexture.x, tlTexture.y })); + vertices.emplace_back( + RasterProgram::layoutVertex({ brVertex.x, tlVertex.y }, { brTexture.x, tlTexture.y })); + vertices.emplace_back( + RasterProgram::layoutVertex({ tlVertex.x, brVertex.y }, { tlTexture.x, brTexture.y })); + vertices.emplace_back( + RasterProgram::layoutVertex({ brVertex.x, brVertex.y }, { brTexture.x, brTexture.y })); + + auto& segment = segments.back(); + assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max()); + const uint16_t offset = segment.vertexLength; + + // 0, 1, 2 + // 1, 2, 3 + indices.emplace_back(offset, offset + 1, offset + 2); + indices.emplace_back(offset + 1, offset + 2, offset + 3); + + segment.vertexLength += vertexLength; + segment.indexLength += 6; + } +} + bool RasterBucket::hasData() const { return !!image; } diff --git a/src/mbgl/renderer/buckets/raster_bucket.hpp b/src/mbgl/renderer/buckets/raster_bucket.hpp index 0b8432eaaf..3800eadec8 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.hpp +++ b/src/mbgl/renderer/buckets/raster_bucket.hpp @@ -5,6 +5,7 @@ #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/programs/raster_program.hpp> #include <mbgl/renderer/bucket.hpp> +#include <mbgl/renderer/tile_mask.hpp> #include <mbgl/util/image.hpp> #include <mbgl/util/mat4.hpp> #include <mbgl/util/optional.hpp> @@ -21,8 +22,11 @@ public: void clear(); void setImage(std::shared_ptr<PremultipliedImage>); + void setMask(TileMask&&); + std::shared_ptr<PremultipliedImage> image; optional<gl::Texture> texture; + TileMask mask{ { 0, 0, 0 } }; // Bucket specific vertices are used for Image Sources only // Raster Tile Sources use the default buffers from Painter |