diff options
author | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-05-12 17:07:48 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-12 17:07:48 -0700 |
commit | 84e39611a096058826dbdb89dccbd1affad05f76 (patch) | |
tree | 97ac706e6a1300ad8d2e2293328e693cff10fbb9 /src/mbgl/renderer/buckets/fill_bucket.cpp | |
parent | 83d9226e4f23c630cb0a78bd54783e35ed11fa81 (diff) | |
download | qtlocation-mapboxgl-84e39611a096058826dbdb89dccbd1affad05f76.tar.gz |
[core] Move renderer/* files into sub-folders (#8983)
Move renderer/* files into sub-folders
Diffstat (limited to 'src/mbgl/renderer/buckets/fill_bucket.cpp')
-rw-r--r-- | src/mbgl/renderer/buckets/fill_bucket.cpp | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp new file mode 100644 index 0000000000..042d7b7506 --- /dev/null +++ b/src/mbgl/renderer/buckets/fill_bucket.cpp @@ -0,0 +1,145 @@ +#include <mbgl/renderer/buckets/fill_bucket.hpp> +#include <mbgl/renderer/painter.hpp> +#include <mbgl/programs/fill_program.hpp> +#include <mbgl/renderer/bucket_parameters.hpp> +#include <mbgl/style/layers/fill_layer_impl.hpp> +#include <mbgl/renderer/layers/render_fill_layer.hpp> +#include <mbgl/util/math.hpp> + +#include <mapbox/earcut.hpp> + +#include <cassert> + +namespace mapbox { +namespace util { +template <> struct nth<0, mbgl::GeometryCoordinate> { + static int64_t get(const mbgl::GeometryCoordinate& t) { return t.x; }; +}; + +template <> struct nth<1, mbgl::GeometryCoordinate> { + static int64_t get(const mbgl::GeometryCoordinate& t) { return t.y; }; +}; +} // namespace util +} // namespace mapbox + +namespace mbgl { + +using namespace style; + +struct GeometryTooLongException : std::exception {}; + +FillBucket::FillBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) { + for (const auto& layer : layers) { + paintPropertyBinders.emplace( + std::piecewise_construct, + std::forward_as_tuple(layer->getID()), + std::forward_as_tuple( + layer->as<RenderFillLayer>()->evaluated, + parameters.tileID.overscaledZ)); + } +} + +void FillBucket::addFeature(const GeometryTileFeature& feature, + const GeometryCollection& geometry) { + for (auto& polygon : classifyRings(geometry)) { + // Optimize polygons with many interior rings for earcut tesselation. + limitHoles(polygon, 500); + + std::size_t totalVertices = 0; + + for (const auto& ring : polygon) { + totalVertices += ring.size(); + if (totalVertices > std::numeric_limits<uint16_t>::max()) + throw GeometryTooLongException(); + } + + std::size_t startVertices = vertices.vertexSize(); + + for (const auto& ring : polygon) { + std::size_t nVertices = ring.size(); + + if (nVertices == 0) + continue; + + if (lineSegments.empty() || lineSegments.back().vertexLength + nVertices > std::numeric_limits<uint16_t>::max()) { + lineSegments.emplace_back(vertices.vertexSize(), lines.indexSize()); + } + + auto& lineSegment = lineSegments.back(); + assert(lineSegment.vertexLength <= std::numeric_limits<uint16_t>::max()); + uint16_t lineIndex = lineSegment.vertexLength; + + vertices.emplace_back(FillProgram::layoutVertex(ring[0])); + lines.emplace_back(lineIndex + nVertices - 1, lineIndex); + + for (uint32_t i = 1; i < nVertices; i++) { + vertices.emplace_back(FillProgram::layoutVertex(ring[i])); + lines.emplace_back(lineIndex + i - 1, lineIndex + i); + } + + lineSegment.vertexLength += nVertices; + lineSegment.indexLength += nVertices * 2; + } + + std::vector<uint32_t> indices = mapbox::earcut(polygon); + + std::size_t nIndicies = indices.size(); + assert(nIndicies % 3 == 0); + + if (triangleSegments.empty() || triangleSegments.back().vertexLength + totalVertices > std::numeric_limits<uint16_t>::max()) { + triangleSegments.emplace_back(startVertices, triangles.indexSize()); + } + + auto& triangleSegment = triangleSegments.back(); + assert(triangleSegment.vertexLength <= std::numeric_limits<uint16_t>::max()); + uint16_t triangleIndex = triangleSegment.vertexLength; + + for (uint32_t i = 0; i < nIndicies; i += 3) { + triangles.emplace_back(triangleIndex + indices[i], + triangleIndex + indices[i + 1], + triangleIndex + indices[i + 2]); + } + + triangleSegment.vertexLength += totalVertices; + triangleSegment.indexLength += nIndicies; + } + + for (auto& pair : paintPropertyBinders) { + pair.second.populateVertexVectors(feature, vertices.vertexSize()); + } +} + +void FillBucket::upload(gl::Context& context) { + vertexBuffer = context.createVertexBuffer(std::move(vertices)); + lineIndexBuffer = context.createIndexBuffer(std::move(lines)); + triangleIndexBuffer = context.createIndexBuffer(std::move(triangles)); + + for (auto& pair : paintPropertyBinders) { + pair.second.upload(context); + } + + uploaded = true; +} + +void FillBucket::render(Painter& painter, + PaintParameters& parameters, + const RenderLayer& layer, + const RenderTile& tile) { + painter.renderFill(parameters, *this, *layer.as<RenderFillLayer>(), tile); +} + +bool FillBucket::hasData() const { + return !triangleSegments.empty() || !lineSegments.empty(); +} + +float FillBucket::getQueryRadius(const RenderLayer& layer) const { + if (!layer.is<RenderFillLayer>()) { + return 0; + } + + const std::array<float, 2>& translate = layer.as<RenderFillLayer>()->evaluated.get<FillTranslate>(); + return util::length(translate[0], translate[1]); + +} + +} // namespace mbgl |