diff options
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r-- | src/mbgl/renderer/circle_bucket.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/fill_extrusion_bucket.cpp | 177 | ||||
-rw-r--r-- | src/mbgl/renderer/fill_extrusion_bucket.hpp | 38 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 78 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.hpp | 11 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_background.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_clipping.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_fill_extrusion.cpp | 87 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_raster.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/render_fill_extrusion_layer.cpp | 41 | ||||
-rw-r--r-- | src/mbgl/renderer/render_fill_extrusion_layer.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/renderer/render_item.hpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/render_tile.cpp | 48 | ||||
-rw-r--r-- | src/mbgl/renderer/render_tile.hpp | 14 |
14 files changed, 483 insertions, 37 deletions
diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp index 855565ebf4..b048fd7675 100644 --- a/src/mbgl/renderer/circle_bucket.hpp +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -22,6 +22,7 @@ public: bool hasData() const override; void upload(gl::Context&) override; + void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) override; float getQueryRadius(const RenderLayer&) const override; diff --git a/src/mbgl/renderer/fill_extrusion_bucket.cpp b/src/mbgl/renderer/fill_extrusion_bucket.cpp new file mode 100644 index 0000000000..2b352ab66a --- /dev/null +++ b/src/mbgl/renderer/fill_extrusion_bucket.cpp @@ -0,0 +1,177 @@ +#include <mbgl/renderer/fill_extrusion_bucket.hpp> +#include <mbgl/renderer/painter.hpp> +#include <mbgl/programs/fill_extrusion_program.hpp> +#include <mbgl/renderer/bucket_parameters.hpp> +#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp> +#include <mbgl/renderer/render_fill_extrusion_layer.hpp> +#include <mbgl/util/math.hpp> +#include <mbgl/util/constants.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 {}; + +FillExtrusionBucket::FillExtrusionBucket(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<RenderFillExtrusionLayer>()->evaluated, + parameters.tileID.overscaledZ)); + } +} + +void FillExtrusionBucket::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(); + } + + if (totalVertices == 0) continue; + + std::vector<uint32_t> flatIndices; + flatIndices.reserve(totalVertices); + + std::size_t startVertices = vertices.vertexSize(); + + if (triangleSegments.empty() || + triangleSegments.back().vertexLength + (5 * (totalVertices - 1) + 1) > + 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; + + assert(triangleIndex + (5 * (totalVertices - 1) + 1) <= + std::numeric_limits<uint16_t>::max()); + + for (const auto& ring : polygon) { + std::size_t nVertices = ring.size(); + + if (nVertices == 0) + continue; + + auto edgeDistance = 0; + + for (uint32_t i = 0; i < nVertices; i++) { + const auto& p1 = ring[i]; + + vertices.emplace_back( + FillExtrusionProgram::layoutVertex(p1, 0, 0, 1, 1, edgeDistance)); + flatIndices.emplace_back(triangleIndex); + triangleIndex++; + + if (i != 0) { + const auto& p2 = ring[i - 1]; + + const auto d1 = convertPoint<double>(p1); + const auto d2 = convertPoint<double>(p2); + + const Point<double> perp = util::unit(util::perp(d1 - d2)); + + vertices.emplace_back( + FillExtrusionProgram::layoutVertex(p1, perp.x, perp.y, 0, 0, edgeDistance)); + vertices.emplace_back( + FillExtrusionProgram::layoutVertex(p1, perp.x, perp.y, 0, 1, edgeDistance)); + + edgeDistance += util::dist<int16_t>(d1, d2); + + vertices.emplace_back( + FillExtrusionProgram::layoutVertex(p2, perp.x, perp.y, 0, 0, edgeDistance)); + vertices.emplace_back( + FillExtrusionProgram::layoutVertex(p2, perp.x, perp.y, 0, 1, edgeDistance)); + + triangles.emplace_back(triangleIndex, triangleIndex + 1, triangleIndex + 2); + triangles.emplace_back(triangleIndex + 1, triangleIndex + 2, triangleIndex + 3); + triangleIndex += 4; + triangleSegment.vertexLength += 4; + triangleSegment.indexLength += 6; + } + } + } + + std::vector<uint32_t> indices = mapbox::earcut(polygon); + + std::size_t nIndices = indices.size(); + assert(nIndices % 3 == 0); + + for (uint32_t i = 0; i < nIndices; i += 3) { + triangles.emplace_back(flatIndices[indices[i]], flatIndices[indices[i + 1]], + flatIndices[indices[i + 2]]); + } + + triangleSegment.vertexLength += totalVertices; + triangleSegment.indexLength += nIndices; + } + + for (auto& pair : paintPropertyBinders) { + pair.second.populateVertexVectors(feature, vertices.vertexSize()); + } +} + +void FillExtrusionBucket::upload(gl::Context& context) { + vertexBuffer = context.createVertexBuffer(std::move(vertices)); + indexBuffer = context.createIndexBuffer(std::move(triangles)); + + for (auto& pair : paintPropertyBinders) { + pair.second.upload(context); + } + + uploaded = true; +} + +void FillExtrusionBucket::render(Painter& painter, + PaintParameters& parameters, + const RenderLayer& layer, + const RenderTile& tile) { + painter.renderFillExtrusion(parameters, *this, *layer.as<RenderFillExtrusionLayer>(), tile); +} + +bool FillExtrusionBucket::hasData() const { + return !triangleSegments.empty(); +} + +float FillExtrusionBucket::getQueryRadius(const RenderLayer& layer) const { + if (!layer.is<RenderFillExtrusionLayer>()) { + return 0; + } + + const std::array<float, 2>& translate = layer.as<RenderFillExtrusionLayer>()->evaluated.get<FillExtrusionTranslate>(); + return util::length(translate[0], translate[1]); +} + +} // namespace mbgl diff --git a/src/mbgl/renderer/fill_extrusion_bucket.hpp b/src/mbgl/renderer/fill_extrusion_bucket.hpp new file mode 100644 index 0000000000..c54805d743 --- /dev/null +++ b/src/mbgl/renderer/fill_extrusion_bucket.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include <mbgl/renderer/bucket.hpp> +#include <mbgl/tile/geometry_tile_data.hpp> +#include <mbgl/gl/vertex_buffer.hpp> +#include <mbgl/gl/index_buffer.hpp> +#include <mbgl/gl/segment.hpp> +#include <mbgl/programs/fill_extrusion_program.hpp> +#include <mbgl/style/layers/fill_extrusion_layer_properties.hpp> + +namespace mbgl { + +class BucketParameters; + +class FillExtrusionBucket : public Bucket { +public: + FillExtrusionBucket(const BucketParameters&, const std::vector<const RenderLayer*>&); + + void addFeature(const GeometryTileFeature&, + const GeometryCollection&) override; + bool hasData() const override; + + void upload(gl::Context&) override; + void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) override; + + float getQueryRadius(const RenderLayer&) const override; + + gl::VertexVector<FillExtrusionLayoutVertex> vertices; + gl::IndexVector<gl::Triangles> triangles; + gl::SegmentVector<FillExtrusionAttributes> triangleSegments; + + optional<gl::VertexBuffer<FillExtrusionLayoutVertex>> vertexBuffer; + optional<gl::IndexBuffer<gl::Triangles>> indexBuffer; + + std::unordered_map<std::string, FillExtrusionProgram::PaintPropertyBinders> paintPropertyBinders; +}; + +} // namespace mbgl diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 0c4915d3e9..36dd4a793f 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -16,6 +16,7 @@ #include <mbgl/renderer/render_background_layer.hpp> #include <mbgl/renderer/render_custom_layer.hpp> #include <mbgl/style/layers/custom_layer_impl.hpp> +#include <mbgl/renderer/render_fill_extrusion_layer.hpp> #include <mbgl/sprite/sprite_atlas.hpp> #include <mbgl/geometry/line_atlas.hpp> @@ -53,7 +54,7 @@ static gl::VertexVector<FillLayoutVertex> tileVertices() { return result; } -static gl::IndexVector<gl::Triangles> tileTriangleIndices() { +static gl::IndexVector<gl::Triangles> quadTriangleIndices() { gl::IndexVector<gl::Triangles> result; result.emplace_back(0, 1, 2); result.emplace_back(1, 2, 3); @@ -79,6 +80,16 @@ static gl::VertexVector<RasterLayoutVertex> rasterVertices() { return result; } +static gl::VertexVector<ExtrusionTextureLayoutVertex> extrusionTextureVertices() { + gl::VertexVector<ExtrusionTextureLayoutVertex> result; + result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 0, 0 })); + result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 1, 0 })); + result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 0, 1 })); + result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 1, 1 })); + return result; +} + + Painter::Painter(gl::Context& context_, const TransformState& state_, float pixelRatio, @@ -87,12 +98,14 @@ Painter::Painter(gl::Context& context_, state(state_), tileVertexBuffer(context.createVertexBuffer(tileVertices())), rasterVertexBuffer(context.createVertexBuffer(rasterVertices())), - tileTriangleIndexBuffer(context.createIndexBuffer(tileTriangleIndices())), + extrusionTextureVertexBuffer(context.createVertexBuffer(extrusionTextureVertices())), + quadTriangleIndexBuffer(context.createIndexBuffer(quadTriangleIndices())), tileBorderIndexBuffer(context.createIndexBuffer(tileLineStripIndices())) { tileTriangleSegments.emplace_back(0, 0, 4, 6); tileBorderSegments.emplace_back(0, 0, 4, 5); rasterSegments.emplace_back(0, 0, 4, 6); + extrusionTextureSegments.emplace_back(0, 0, 4, 6); programs = std::make_unique<Programs>(context, ProgramParameters{ pixelRatio, false, programCacheDir }); @@ -131,12 +144,18 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp spriteAtlas = style.spriteAtlas.get(); lineAtlas = style.lineAtlas.get(); + evaluatedLight = style.evaluatedLight; + RenderData renderData = style.getRenderData(frame.debugOptions, state.getAngle()); const std::vector<RenderItem>& order = renderData.order; const std::unordered_set<Source*>& sources = renderData.sources; // Update the default matrices to the current viewport dimensions. state.getProjMatrix(projMatrix); + // Calculate a second projection matrix with the near plane clipped to 100 so as + // not to waste lots of depth buffer precision on very close empty space, for layer + // types (fill-extrusion) that use the depth buffer to emulate real-world space. + state.getProjMatrix(nearClippedProjMatrix, 100); pixelsToGLUnits = {{ 2.0f / state.getSize().width, -2.0f / state.getSize().height }}; if (state.getViewportMode() == ViewportMode::FlippedY) { @@ -160,8 +179,11 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp annotationSpriteAtlas.upload(context, 0); for (const auto& item : order) { - if (item.bucket && item.bucket->needsUpload()) { - item.bucket->upload(context); + for (const auto& tileRef : item.tiles) { + const auto& bucket = tileRef.get().tile.getBucket(item.layer); + if (bucket && bucket->needsUpload()) { + bucket->upload(context); + } } } } @@ -187,7 +209,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp // Update all clipping IDs. algorithm::ClipIDGenerator generator; for (const auto& source : sources) { - source->baseImpl->startRender(generator, projMatrix, state); + source->baseImpl->startRender(generator, projMatrix, nearClippedProjMatrix, state); } MBGL_DEBUG_GROUP(context, "clipping masks"); @@ -208,7 +230,6 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp // Actually render the layers if (debug::renderTree) { Log::Info(Event::Render, "{"); indent++; } - // TODO: Correctly compute the number of layers recursively beforehand. depthRangeSize = 1 - (order.size() + 2) * numSublayers * depthEpsilon; // - OPAQUE PASS ------------------------------------------------------------------------------- @@ -302,9 +323,50 @@ void Painter::renderPass(PaintParameters& parameters, // the viewport or Framebuffer. parameters.view.bind(); context.setDirtyState(); + } else if (layer.is<RenderFillExtrusionLayer>()) { + const auto size = context.viewport.getCurrentValue().size; + + OffscreenTexture texture(context, size); + texture.bindRenderbuffers(1); + + context.setStencilMode(gl::StencilMode::disabled()); + context.setDepthMode(depthModeForSublayer(0, gl::DepthMode::ReadWrite)); + context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, 1.0f, {}); + + for (auto& tileRef : item.tiles) { + auto& tile = tileRef.get(); + + MBGL_DEBUG_GROUP(context, layer.baseImpl.id + " - " + util::toString(tile.id)); + auto bucket = tile.tile.getBucket(layer); + bucket->render(*this, parameters, layer, tile); + } + + parameters.view.bind(); + + mat4 viewportMat; + matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1); + + const PaintProperties<>::Evaluated properties{}; + + parameters.programs.extrusionTexture.draw( + context, gl::Triangles(), gl::DepthMode::disabled(), gl::StencilMode::disabled(), + colorModeForRenderPass(), + ExtrusionTextureProgram::UniformValues{ + uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, + uniforms::u_image::Value{ 1 }, + uniforms::u_opacity::Value{ + layer.as<RenderFillExtrusionLayer>()->evaluated.get<FillExtrusionOpacity>() } }, + extrusionTextureVertexBuffer, quadTriangleIndexBuffer, + extrusionTextureSegments, + ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, properties, + state.getZoom()); } else { - MBGL_DEBUG_GROUP(context, layer.baseImpl.id + " - " + util::toString(item.tile->id)); - item.bucket->render(*this, parameters, layer, *item.tile); + for (auto& tileRef : item.tiles) { + auto& tile = tileRef.get(); + MBGL_DEBUG_GROUP(context, layer.baseImpl.id + " - " + util::toString(tile.id)); + auto bucket = tile.tile.getBucket(layer); + bucket->render(*this, parameters, layer, tile); + } } } diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 9c6dd4505f..7706d2d451 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -12,6 +12,7 @@ #include <mbgl/programs/debug_program.hpp> #include <mbgl/programs/program_parameters.hpp> #include <mbgl/programs/fill_program.hpp> +#include <mbgl/programs/extrusion_texture_program.hpp> #include <mbgl/programs/raster_program.hpp> #include <mbgl/style/style.hpp> @@ -37,12 +38,14 @@ class Tile; class DebugBucket; class FillBucket; +class FillExtrusionBucket; class LineBucket; class CircleBucket; class SymbolBucket; class RasterBucket; class RenderFillLayer; +class RenderFillExtrusionLayer; class RenderLineLayer; class RenderCircleLayer; class RenderSymbolLayer; @@ -82,6 +85,7 @@ public: void renderClippingMask(const UnwrappedTileID&, const ClipID&); void renderTileDebug(const RenderTile&); void renderFill(PaintParameters&, FillBucket&, const RenderFillLayer&, const RenderTile&); + void renderFillExtrusion(PaintParameters&, FillExtrusionBucket&, const RenderFillExtrusionLayer&, const RenderTile&); void renderLine(PaintParameters&, LineBucket&, const RenderLineLayer&, const RenderTile&); void renderCircle(PaintParameters&, CircleBucket&, const RenderCircleLayer&, const RenderTile&); void renderSymbol(PaintParameters&, SymbolBucket&, const RenderSymbolLayer&, const RenderTile&); @@ -126,6 +130,7 @@ private: gl::Context& context; mat4 projMatrix; + mat4 nearClippedProjMatrix; std::array<float, 2> pixelsToGLUnits; @@ -152,6 +157,8 @@ private: GlyphAtlas* glyphAtlas = nullptr; LineAtlas* lineAtlas = nullptr; + style::EvaluatedLight evaluatedLight; + FrameHistory frameHistory; std::unique_ptr<Programs> programs; @@ -161,13 +168,15 @@ private: gl::VertexBuffer<FillLayoutVertex> tileVertexBuffer; gl::VertexBuffer<RasterLayoutVertex> rasterVertexBuffer; + gl::VertexBuffer<ExtrusionTextureLayoutVertex> extrusionTextureVertexBuffer; - gl::IndexBuffer<gl::Triangles> tileTriangleIndexBuffer; + gl::IndexBuffer<gl::Triangles> quadTriangleIndexBuffer; gl::IndexBuffer<gl::LineStrip> tileBorderIndexBuffer; gl::SegmentVector<FillAttributes> tileTriangleSegments; gl::SegmentVector<DebugAttributes> tileBorderSegments; gl::SegmentVector<RasterAttributes> rasterSegments; + gl::SegmentVector<ExtrusionTextureAttributes> extrusionTextureSegments; }; } // namespace mbgl diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index ac16627246..7cd9cbac5f 100644 --- a/src/mbgl/renderer/painter_background.cpp +++ b/src/mbgl/renderer/painter_background.cpp @@ -49,7 +49,7 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou state ), tileVertexBuffer, - tileTriangleIndexBuffer, + quadTriangleIndexBuffer, tileTriangleSegments, paintAttibuteData, properties, @@ -69,7 +69,7 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou uniforms::u_world::Value{ context.viewport.getCurrentValue().size }, }, tileVertexBuffer, - tileTriangleIndexBuffer, + quadTriangleIndexBuffer, tileTriangleSegments, paintAttibuteData, properties, diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index 70df9837e8..0d3b5f1504 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -26,7 +26,7 @@ void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& cl uniforms::u_world::Value{ context.viewport.getCurrentValue().size }, }, tileVertexBuffer, - tileTriangleIndexBuffer, + quadTriangleIndexBuffer, tileTriangleSegments, paintAttibuteData, properties, diff --git a/src/mbgl/renderer/painter_fill_extrusion.cpp b/src/mbgl/renderer/painter_fill_extrusion.cpp new file mode 100644 index 0000000000..af98cae569 --- /dev/null +++ b/src/mbgl/renderer/painter_fill_extrusion.cpp @@ -0,0 +1,87 @@ +#include <mbgl/renderer/painter.hpp> +#include <mbgl/renderer/paint_parameters.hpp> +#include <mbgl/renderer/fill_extrusion_bucket.hpp> +#include <mbgl/renderer/render_tile.hpp> +#include <mbgl/renderer/render_fill_extrusion_layer.hpp> +#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp> +#include <mbgl/sprite/sprite_atlas.hpp> +#include <mbgl/programs/programs.hpp> +#include <mbgl/programs/fill_extrusion_program.hpp> +#include <mbgl/util/constants.hpp> +#include <mbgl/util/convert.hpp> + +namespace mbgl { + +using namespace style; + +void Painter::renderFillExtrusion(PaintParameters& parameters, + FillExtrusionBucket& bucket, + const RenderFillExtrusionLayer& layer, + const RenderTile& tile) { + const FillExtrusionPaintProperties::Evaluated& properties = layer.evaluated; + + if (pass == RenderPass::Opaque) { + return; + } + + if (!properties.get<FillExtrusionPattern>().from.empty()) { + optional<SpriteAtlasElement> imagePosA = + spriteAtlas->getPattern(properties.get<FillExtrusionPattern>().from); + optional<SpriteAtlasElement> imagePosB = + spriteAtlas->getPattern(properties.get<FillExtrusionPattern>().to); + + if (!imagePosA || !imagePosB) { + return; + } + + spriteAtlas->bind(true, context, 0); + + parameters.programs.fillExtrusionPattern.draw( + context, + gl::Triangles(), + depthModeForSublayer(0, gl::DepthMode::ReadWrite), + gl::StencilMode::disabled(), + colorModeForRenderPass(), + FillExtrusionPatternUniforms::values( + tile.translatedClipMatrix(properties.get<FillExtrusionTranslate>(), + properties.get<FillExtrusionTranslateAnchor>(), + state), + *imagePosA, + *imagePosB, + properties.get<FillExtrusionPattern>(), + tile.id, + state, + -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f, + evaluatedLight + ), + *bucket.vertexBuffer, + *bucket.indexBuffer, + bucket.triangleSegments, + bucket.paintPropertyBinders.at(layer.getID()), + properties, + state.getZoom()); + + } else { + parameters.programs.fillExtrusion.draw( + context, + gl::Triangles(), + depthModeForSublayer(0, gl::DepthMode::ReadWrite), + gl::StencilMode::disabled(), + colorModeForRenderPass(), + FillExtrusionUniforms::values( + tile.translatedClipMatrix(properties.get<FillExtrusionTranslate>(), + properties.get<FillExtrusionTranslateAnchor>(), + state), + state, + evaluatedLight + ), + *bucket.vertexBuffer, + *bucket.indexBuffer, + bucket.triangleSegments, + bucket.paintPropertyBinders.at(layer.getID()), + properties, + state.getZoom()); + }; +} + +} // namespace mbgl diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp index 31f10ed3ba..fbe025b5b0 100644 --- a/src/mbgl/renderer/painter_raster.cpp +++ b/src/mbgl/renderer/painter_raster.cpp @@ -77,7 +77,7 @@ void Painter::renderRaster(PaintParameters& parameters, uniforms::u_tl_parent::Value{ std::array<float, 2> {{ 0.0f, 0.0f }} }, }, rasterVertexBuffer, - tileTriangleIndexBuffer, + quadTriangleIndexBuffer, rasterSegments, paintAttributeData, properties, diff --git a/src/mbgl/renderer/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/render_fill_extrusion_layer.cpp index a378f12cf0..8df0d36900 100644 --- a/src/mbgl/renderer/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/render_fill_extrusion_layer.cpp @@ -1,26 +1,53 @@ #include <mbgl/renderer/render_fill_extrusion_layer.hpp> -#include <mbgl/renderer/bucket.hpp> +#include <mbgl/renderer/fill_extrusion_bucket.hpp> #include <mbgl/style/layers/fill_extrusion_layer_impl.hpp> +#include <mbgl/geometry/feature_index.hpp> +#include <mbgl/util/math.hpp> +#include <mbgl/util/intersection_tests.hpp> namespace mbgl { RenderFillExtrusionLayer::RenderFillExtrusionLayer(const style::FillExtrusionLayer::Impl& _impl) - : RenderLayer(style::LayerType::FillExtrusion, _impl) { + : RenderLayer(style::LayerType::FillExtrusion, _impl), + impl(&_impl) { } std::unique_ptr<RenderLayer> RenderFillExtrusionLayer::clone() const { return std::make_unique<RenderFillExtrusionLayer>(*this); } -std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const { - return nullptr; +std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const { + return std::make_unique<FillExtrusionBucket>(parameters, layers); } -void RenderFillExtrusionLayer::cascade(const style::CascadeParameters&) { +void RenderFillExtrusionLayer::cascade(const style::CascadeParameters& parameters) { + unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated)); } -bool RenderFillExtrusionLayer::evaluate(const style::PropertyEvaluationParameters&) { - return false; +bool RenderFillExtrusionLayer::evaluate(const style::PropertyEvaluationParameters& parameters) { + evaluated = unevaluated.evaluate(parameters); + + passes = (evaluated.get<style::FillExtrusionOpacity>() > 0) ? RenderPass::Translucent + : RenderPass::None; + + return unevaluated.hasTransition(); +} + +bool RenderFillExtrusionLayer::queryIntersectsFeature( + const GeometryCoordinates& queryGeometry, + const GeometryTileFeature& feature, + const float, + const float bearing, + const float pixelsToTileUnits) const { + + auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( + queryGeometry, + evaluated.get<style::FillExtrusionTranslate>(), + evaluated.get<style::FillExtrusionTranslateAnchor>(), + bearing, + pixelsToTileUnits); + + return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries()); } } // namespace mbgl diff --git a/src/mbgl/renderer/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/render_fill_extrusion_layer.hpp index 596ba02fee..87b6ad6071 100644 --- a/src/mbgl/renderer/render_fill_extrusion_layer.hpp +++ b/src/mbgl/renderer/render_fill_extrusion_layer.hpp @@ -17,11 +17,20 @@ public: void cascade(const style::CascadeParameters&) override; bool evaluate(const style::PropertyEvaluationParameters&) override; + bool queryIntersectsFeature( + const GeometryCoordinates&, + const GeometryTileFeature&, + const float, + const float, + const float) const override; + std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; // Paint properties style::FillExtrusionPaintProperties::Unevaluated unevaluated; style::FillExtrusionPaintProperties::Evaluated evaluated; + + const style::FillExtrusionLayer::Impl* const impl; }; template <> diff --git a/src/mbgl/renderer/render_item.hpp b/src/mbgl/renderer/render_item.hpp index 575287d9c6..01bb263d1e 100644 --- a/src/mbgl/renderer/render_item.hpp +++ b/src/mbgl/renderer/render_item.hpp @@ -18,14 +18,12 @@ class Source; class RenderItem { public: RenderItem(const RenderLayer& layer_, - const RenderTile* tile_ = nullptr, - Bucket* bucket_ = nullptr) - : tile(tile_), bucket(bucket_), layer(layer_) { + std::vector<std::reference_wrapper<RenderTile>> tiles_ = {}) + : layer(layer_), tiles(std::move(tiles_)) { } - const RenderTile* const tile; - Bucket* const bucket; const RenderLayer& layer; + std::vector<std::reference_wrapper<RenderTile>> tiles; }; class RenderData { diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index 5c7c491be0..ce59186e61 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -5,11 +5,12 @@ namespace mbgl { using namespace style; -mat4 RenderTile::translatedMatrix(const std::array<float, 2>& translation, - TranslateAnchorType anchor, - const TransformState& state) const { +mat4 RenderTile::translateVtxMatrix(const mat4& tileMatrix, + const std::array<float, 2>& translation, + TranslateAnchorType anchor, + const TransformState& state) const { if (translation[0] == 0 && translation[1] == 0) { - return matrix; + return tileMatrix; } mat4 vtxMatrix; @@ -17,18 +18,41 @@ mat4 RenderTile::translatedMatrix(const std::array<float, 2>& translation, if (anchor == TranslateAnchorType::Viewport) { const double sin_a = std::sin(-state.getAngle()); const double cos_a = std::cos(-state.getAngle()); - matrix::translate(vtxMatrix, matrix, - id.pixelsToTileUnits(translation[0] * cos_a - translation[1] * sin_a, state.getZoom()), - id.pixelsToTileUnits(translation[0] * sin_a + translation[1] * cos_a, state.getZoom()), - 0); + matrix::translate(vtxMatrix, tileMatrix, + id.pixelsToTileUnits(translation[0] * cos_a - translation[1] * sin_a, state.getZoom()), + id.pixelsToTileUnits(translation[0] * sin_a + translation[1] * cos_a, state.getZoom()), + 0); } else { - matrix::translate(vtxMatrix, matrix, - id.pixelsToTileUnits(translation[0], state.getZoom()), - id.pixelsToTileUnits(translation[1], state.getZoom()), - 0); + matrix::translate(vtxMatrix, tileMatrix, + id.pixelsToTileUnits(translation[0], state.getZoom()), + id.pixelsToTileUnits(translation[1], state.getZoom()), + 0); } return vtxMatrix; } +mat4 RenderTile::translatedMatrix(const std::array<float, 2>& translation, + TranslateAnchorType anchor, + const TransformState& state) const { + return translateVtxMatrix(matrix, translation, anchor, state); +} + +mat4 RenderTile::translatedClipMatrix(const std::array<float, 2>& translation, + TranslateAnchorType anchor, + const TransformState& state) const { + return translateVtxMatrix(nearClippedMatrix, translation, anchor, state); +} + +void RenderTile::calculateMatrices(const mat4& projMatrix, + const mat4& projClipMatrix, + const TransformState& transform) { + // Calculate two matrices for this tile: matrix is the standard tile matrix; nearClippedMatrix + // clips the near plane to 100 to save depth buffer precision + transform.matrixFor(matrix, id); + transform.matrixFor(nearClippedMatrix, id); + matrix::multiply(matrix, projMatrix, matrix); + matrix::multiply(nearClippedMatrix, projClipMatrix, nearClippedMatrix); +} + } // namespace mbgl diff --git a/src/mbgl/renderer/render_tile.hpp b/src/mbgl/renderer/render_tile.hpp index e2e0c3d656..02e8667eec 100644 --- a/src/mbgl/renderer/render_tile.hpp +++ b/src/mbgl/renderer/render_tile.hpp @@ -24,11 +24,25 @@ public: Tile& tile; ClipID clip; mat4 matrix; + mat4 nearClippedMatrix; bool used = false; mat4 translatedMatrix(const std::array<float, 2>& translate, style::TranslateAnchorType anchor, const TransformState&) const; + + mat4 translatedClipMatrix(const std::array<float, 2>& translate, + style::TranslateAnchorType anchor, + const TransformState&) const; + + void calculateMatrices(const mat4& projMatrix, + const mat4& projClipMatrix, + const TransformState&); +private: + mat4 translateVtxMatrix(const mat4& tileMatrix, + const std::array<float, 2>& translation, + style::TranslateAnchorType anchor, + const TransformState& state) const; }; } // namespace mbgl |