summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/layers/render_heatmap_layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer/layers/render_heatmap_layer.cpp')
-rw-r--r--src/mbgl/renderer/layers/render_heatmap_layer.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
new file mode 100644
index 0000000000..54a3cb89f1
--- /dev/null
+++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
@@ -0,0 +1,164 @@
+#include <mbgl/renderer/layers/render_heatmap_layer.hpp>
+#include <mbgl/renderer/buckets/heatmap_bucket.hpp>
+#include <mbgl/renderer/render_tile.hpp>
+#include <mbgl/renderer/paint_parameters.hpp>
+#include <mbgl/renderer/render_static_data.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/heatmap_program.hpp>
+#include <mbgl/tile/tile.hpp>
+#include <mbgl/style/layers/heatmap_layer.hpp>
+#include <mbgl/style/layers/heatmap_layer_impl.hpp>
+#include <mbgl/geometry/feature_index.hpp>
+#include <mbgl/util/math.hpp>
+#include <mbgl/util/intersection_tests.hpp>
+
+namespace mbgl {
+
+using namespace style;
+
+RenderHeatmapLayer::RenderHeatmapLayer(Immutable<style::HeatmapLayer::Impl> _impl)
+ : RenderLayer(style::LayerType::Heatmap, _impl),
+ unevaluated(impl().paint.untransitioned()) {
+}
+
+const style::HeatmapLayer::Impl& RenderHeatmapLayer::impl() const {
+ return static_cast<const style::HeatmapLayer::Impl&>(*baseImpl);
+}
+
+std::unique_ptr<Bucket> RenderHeatmapLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const {
+ return std::make_unique<HeatmapBucket>(parameters, layers);
+}
+
+void RenderHeatmapLayer::transition(const TransitionParameters& parameters) {
+ unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated));
+}
+
+void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters) {
+ evaluated = unevaluated.evaluate(parameters);
+
+ passes = (evaluated.get<style::HeatmapOpacity>() > 0)
+ ? (RenderPass::Translucent | RenderPass::Pass3D)
+ : RenderPass::None;
+}
+
+bool RenderHeatmapLayer::hasTransition() const {
+ return unevaluated.hasTransition();
+}
+
+void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) {
+ if (parameters.pass == RenderPass::Opaque) {
+ return;
+ }
+
+ if (parameters.pass == RenderPass::Pass3D) {
+ const auto& viewportSize = parameters.staticData.backendSize;
+ const auto size = Size{viewportSize.width / 4, viewportSize.height / 4};
+
+ if (!renderTexture || renderTexture->getSize() != size) {
+ renderTexture = OffscreenTexture(parameters.context, size);
+ }
+
+ if (!colorRampTexture) {
+ const auto colorRampSize = Size{256, 1};
+ colorRampTexture = gl::Texture{colorRampSize, parameters.context.createTexture(colorRampSize, colorRamp.data(), gl::TextureFormat::RGBA, 1)};
+ }
+
+ renderTexture->bind();
+
+ parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 1.0f }, {}, {});
+
+ for (const RenderTile& tile : renderTiles) {
+ assert(dynamic_cast<HeatmapBucket*>(tile.tile.getBucket(*baseImpl)));
+ HeatmapBucket& bucket = *reinterpret_cast<HeatmapBucket*>(tile.tile.getBucket(*baseImpl));
+
+ const auto extrudeScale = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
+
+ const auto stencilMode = parameters.mapMode != MapMode::Continuous
+ ? parameters.stencilModeForClipping(tile.clip)
+ : gl::StencilMode::disabled();
+
+ parameters.programs.heatmap.get(evaluated).draw(
+ parameters.context,
+ gl::Triangles(),
+ parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ stencilMode,
+ gl::ColorMode::additive(),
+ HeatmapProgram::UniformValues {
+ uniforms::u_radius::Value{evaluated.get<style::HeatmapRadius>()},
+ uniforms::u_intensity::Value{evaluated.get<style::HeatmapIntensity>()},
+ uniforms::u_matrix::Value{tile.matrix},
+ uniforms::heatmap::u_extrude_scale::Value{extrudeScale}
+ },
+ *bucket.vertexBuffer,
+ *bucket.indexBuffer,
+ bucket.segments,
+ bucket.paintPropertyBinders.at(getID()),
+ evaluated,
+ parameters.state.getZoom(),
+ getID()
+ );
+ }
+
+ } else if (parameters.pass == RenderPass::Translucent) {
+ parameters.context.bindTexture(renderTexture->getTexture(), 0, gl::TextureFilter::Linear);
+ parameters.context.bindTexture(*colorRampTexture, 1, gl::TextureFilter::Linear);
+
+ const auto& size = parameters.staticData.backendSize;
+
+ mat4 viewportMat;
+ matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
+
+ const Properties<>::PossiblyEvaluated properties;
+
+ parameters.programs.heatmapTexture.draw(
+ parameters.context, gl::Triangles(), gl::DepthMode::disabled(),
+ gl::StencilMode::disabled(), parameters.colorModeForRenderPass(),
+ HeatmapTextureProgram::UniformValues{
+ uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size },
+ uniforms::u_image::Value{ 0 },
+ uniforms::u_color_ramp::Value{ 1 },
+ uniforms::u_opacity::Value{ evaluated.get<HeatmapOpacity>() } },
+ parameters.staticData.extrusionTextureVertexBuffer,
+ parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.extrusionTextureSegments,
+ HeatmapTextureProgram::PaintPropertyBinders{ properties, 0 }, properties,
+ parameters.state.getZoom(), getID());
+ }
+}
+
+void RenderHeatmapLayer::updateColorRamp() {
+ auto colorValue = unevaluated.get<HeatmapColor>().getValue();
+ if (colorValue.isUndefined()) {
+ colorValue = HeatmapLayer::getDefaultHeatmapColor();
+ }
+
+ const auto size = colorRamp.size();
+
+ for (uint32_t i = 0; i < size; i += 4) {
+ const auto color = colorValue.evaluate(static_cast<double>(i) / size);
+ colorRamp[i + 0] = std::floor(color.r * 255);
+ colorRamp[i + 1] = std::floor(color.g * 255);
+ colorRamp[i + 2] = std::floor(color.b * 255);
+ colorRamp[i + 3] = std::floor(color.a * 255);
+ }
+
+ if (colorRampTexture) {
+ colorRampTexture = nullopt;
+ }
+}
+
+bool RenderHeatmapLayer::queryIntersectsFeature(
+ const GeometryCoordinates& queryGeometry,
+ const GeometryTileFeature& feature,
+ const float zoom,
+ const float bearing,
+ const float pixelsToTileUnits) const {
+ (void) queryGeometry;
+ (void) feature;
+ (void) zoom;
+ (void) bearing;
+ (void) pixelsToTileUnits;
+ return false;
+}
+
+} // namespace mbgl