summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/layers/render_hillshade_layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer/layers/render_hillshade_layer.cpp')
-rw-r--r--src/mbgl/renderer/layers/render_hillshade_layer.cpp312
1 files changed, 160 insertions, 152 deletions
diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp
index 2cbb77f24b..49fc5eedc5 100644
--- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp
+++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp
@@ -29,194 +29,202 @@ RenderHillshadeLayer::RenderHillshadeLayer(Immutable<style::HillshadeLayer::Impl
RenderHillshadeLayer::~RenderHillshadeLayer() = default;
-const std::array<float, 2> RenderHillshadeLayer::getLatRange(const UnwrappedTileID& id) {
+namespace {
+std::array<float, 2> getLatRange(const UnwrappedTileID& id) {
const LatLng latlng0 = LatLng(id);
const LatLng latlng1 = LatLng(UnwrappedTileID(id.canonical.z, id.canonical.x, id.canonical.y + 1));
return {{ (float)latlng0.latitude(), (float)latlng1.latitude() }};
}
-const std::array<float, 2> RenderHillshadeLayer::getLight(const PaintParameters& parameters) {
- const auto& evaluated = static_cast<const HillshadeLayerProperties&>(*evaluatedProperties).evaluated;
+std::array<float, 2> getLight(const PaintParameters& parameters, const HillshadePaintProperties::PossiblyEvaluated& evaluated) {
float azimuthal = evaluated.get<HillshadeIlluminationDirection>() * util::DEG2RAD;
- if (evaluated.get<HillshadeIlluminationAnchor>() == HillshadeIlluminationAnchorType::Viewport) azimuthal = azimuthal - parameters.state.getBearing();
+ if (evaluated.get<HillshadeIlluminationAnchor>() == HillshadeIlluminationAnchorType::Viewport) {
+ azimuthal = azimuthal - parameters.state.getBearing();
+ }
return {{evaluated.get<HillshadeExaggeration>(), azimuthal}};
}
+} // namespace
-void RenderHillshadeLayer::transition(const TransitionParameters& parameters) {
- unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
-}
+LayerRenderer RenderHillshadeLayer::createRenderer() {
+ return [maxzoom = this->maxzoom](PaintParameters& parameters, const LayerRenderItem& renderItem) {
+ if (parameters.pass != RenderPass::Translucent && parameters.pass != RenderPass::Pass3D) return;
-void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& parameters) {
- auto properties = makeMutable<HillshadeLayerProperties>(
- staticImmutableCast<HillshadeLayer::Impl>(baseImpl),
- unevaluated.evaluate(parameters));
- passes = (properties->evaluated.get<style::HillshadeExaggeration >() > 0)
- ? (RenderPass::Translucent | RenderPass::Pass3D)
- : RenderPass::None;
+ const auto& renderTiles = renderItem.renderTiles;
+ const auto& evaluated = getEvaluated<HillshadeLayerProperties>(renderItem.evaluatedProperties);
+ const auto& baseImpl = *renderItem.evaluatedProperties->baseImpl;
- evaluatedProperties = std::move(properties);
-}
+ auto draw = [&] (const mat4& matrix,
+ const auto& vertexBuffer,
+ const auto& indexBuffer,
+ const auto& segments,
+ const UnwrappedTileID& id,
+ const auto& textureBindings) {
+ auto& programInstance = parameters.programs.getHillshadeLayerPrograms().hillshade;
-bool RenderHillshadeLayer::hasTransition() const {
- return unevaluated.hasTransition();
-}
-
-bool RenderHillshadeLayer::hasCrossfade() const {
- return false;
-}
-
-void RenderHillshadeLayer::prepare(const LayerPrepareParameters& params) {
- RenderLayer::prepare(params);
- maxzoom = params.source->getMaxZoom();
-}
-
-void RenderHillshadeLayer::render(PaintParameters& parameters) {
- if (parameters.pass != RenderPass::Translucent && parameters.pass != RenderPass::Pass3D)
- return;
- const auto& evaluated = static_cast<const HillshadeLayerProperties&>(*evaluatedProperties).evaluated;
- auto draw = [&] (const mat4& matrix,
- const auto& vertexBuffer,
- const auto& indexBuffer,
- const auto& segments,
- const UnwrappedTileID& id,
- const auto& textureBindings) {
- auto& programInstance = parameters.programs.getHillshadeLayerPrograms().hillshade;
-
- const HillshadeProgram::Binders paintAttributeData{ evaluated, 0 };
-
- const auto allUniformValues = programInstance.computeAllUniformValues(
- HillshadeProgram::LayoutUniformValues {
- uniforms::matrix::Value( matrix ),
- uniforms::highlight::Value( evaluated.get<HillshadeHighlightColor>() ),
- uniforms::shadow::Value( evaluated.get<HillshadeShadowColor>() ),
- uniforms::accent::Value( evaluated.get<HillshadeAccentColor>() ),
- uniforms::light::Value( getLight(parameters) ),
- uniforms::latrange::Value( getLatRange(id) ),
- },
- paintAttributeData,
- evaluated,
- parameters.state.getZoom()
- );
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- vertexBuffer,
- paintAttributeData,
- evaluated
- );
-
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- indexBuffer,
- segments,
- allUniformValues,
- allAttributeBindings,
- textureBindings,
- getID() + "/" + util::toString(id)
- );
- };
-
- mat4 mat;
- matrix::ortho(mat, 0, util::EXTENT, -util::EXTENT, 0, 0, 1);
- matrix::translate(mat, mat, 0, -util::EXTENT, 0);
-
- for (const RenderTile& tile : renderTiles) {
- auto* bucket_ = tile.getBucket(*baseImpl);
- if (!bucket_) {
- continue;
- }
- auto& bucket = static_cast<HillshadeBucket&>(*bucket_);
-
- if (!bucket.hasData()){
- continue;
- }
-
- if (!bucket.isPrepared() && parameters.pass == RenderPass::Pass3D) {
- assert(bucket.dem);
- const uint16_t stride = bucket.getDEMData().stride;
- const uint16_t tilesize = bucket.getDEMData().dim;
- auto view = parameters.context.createOffscreenTexture({ tilesize, tilesize });
-
- auto renderPass = parameters.encoder->createRenderPass(
- "hillshade prepare", { *view, Color{ 0.0f, 0.0f, 0.0f, 0.0f }, {}, {} });
-
- const Properties<>::PossiblyEvaluated properties;
- const HillshadePrepareProgram::Binders paintAttributeData{ properties, 0 };
-
- auto& programInstance = parameters.programs.getHillshadeLayerPrograms().hillshadePrepare;
+ const HillshadeProgram::Binders paintAttributeData{ evaluated, 0 };
const auto allUniformValues = programInstance.computeAllUniformValues(
- HillshadePrepareProgram::LayoutUniformValues {
- uniforms::matrix::Value( mat ),
- uniforms::dimension::Value( {{stride, stride}} ),
- uniforms::zoom::Value( float(tile.id.canonical.z) ),
- uniforms::maxzoom::Value( float(maxzoom) ),
+ HillshadeProgram::LayoutUniformValues {
+ uniforms::matrix::Value( matrix ),
+ uniforms::highlight::Value( evaluated.get<HillshadeHighlightColor>() ),
+ uniforms::shadow::Value( evaluated.get<HillshadeShadowColor>() ),
+ uniforms::accent::Value( evaluated.get<HillshadeAccentColor>() ),
+ uniforms::light::Value( getLight(parameters, evaluated) ),
+ uniforms::latrange::Value( getLatRange(id) ),
},
paintAttributeData,
- properties,
+ evaluated,
parameters.state.getZoom()
);
const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- *parameters.staticData.rasterVertexBuffer,
+ vertexBuffer,
paintAttributeData,
- properties
+ evaluated
);
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
programInstance.draw(
parameters.context,
- *renderPass,
+ *parameters.renderPass,
gfx::Triangles(),
parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
gfx::StencilMode::disabled(),
parameters.colorModeForRenderPass(),
gfx::CullFaceMode::disabled(),
- *parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.rasterSegments,
+ indexBuffer,
+ segments,
allUniformValues,
allAttributeBindings,
- HillshadePrepareProgram::TextureBindings{
- textures::image::Value{ bucket.dem->getResource() },
- },
- getID() + "/p/" + util::toString(tile.id)
+ textureBindings,
+ baseImpl.id + "/" + util::toString(id)
);
- bucket.texture = std::move(view->getTexture());
- bucket.setPrepared(true);
- } else if (parameters.pass == RenderPass::Translucent) {
- assert(bucket.texture);
-
- if (bucket.vertexBuffer && bucket.indexBuffer && !bucket.segments.empty()) {
- // Draw only the parts of the tile that aren't drawn by another tile in the layer.
- draw(parameters.matrixForTile(tile.id, true),
- *bucket.vertexBuffer,
- *bucket.indexBuffer,
- bucket.segments,
- tile.id,
- HillshadeProgram::TextureBindings{
- textures::image::Value{ bucket.texture->getResource(), gfx::TextureFilterType::Linear },
- });
- } else {
- // Draw the full tile.
- draw(parameters.matrixForTile(tile.id, true),
- *parameters.staticData.rasterVertexBuffer,
- *parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.rasterSegments,
- tile.id,
- HillshadeProgram::TextureBindings{
- textures::image::Value{ bucket.texture->getResource(), gfx::TextureFilterType::Linear },
- });
+ };
+
+ mat4 mat;
+ matrix::ortho(mat, 0, util::EXTENT, -util::EXTENT, 0, 0, 1);
+ matrix::translate(mat, mat, 0, -util::EXTENT, 0);
+
+ for (const RenderTile& tile : renderTiles) {
+ auto* bucket_ = tile.getBucket(baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ auto& bucket = static_cast<HillshadeBucket&>(*bucket_);
+
+ if (!bucket.hasData()) {
+ continue;
+ }
+
+ if (!bucket.isPrepared() && parameters.pass == RenderPass::Pass3D) {
+ assert(bucket.dem);
+ const uint16_t stride = bucket.getDEMData().stride;
+ const uint16_t tilesize = bucket.getDEMData().dim;
+ auto view = parameters.context.createOffscreenTexture({ tilesize, tilesize });
+
+ auto renderPass = parameters.encoder->createRenderPass(
+ "hillshade prepare", { *view, Color{ 0.0f, 0.0f, 0.0f, 0.0f }, {}, {} });
+
+ const Properties<>::PossiblyEvaluated properties;
+ const HillshadePrepareProgram::Binders paintAttributeData{ properties, 0 };
+
+ auto& programInstance = parameters.programs.getHillshadeLayerPrograms().hillshadePrepare;
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ HillshadePrepareProgram::LayoutUniformValues {
+ uniforms::matrix::Value( mat ),
+ uniforms::dimension::Value( {{stride, stride}} ),
+ uniforms::zoom::Value( float(tile.id.canonical.z) ),
+ uniforms::maxzoom::Value( float(maxzoom) ),
+ },
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *parameters.staticData.rasterVertexBuffer,
+ paintAttributeData,
+ properties
+ );
+
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ *renderPass,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
+ gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ *parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.rasterSegments,
+ allUniformValues,
+ allAttributeBindings,
+ HillshadePrepareProgram::TextureBindings{
+ textures::image::Value{ bucket.dem->getResource() },
+ },
+ baseImpl.id + "/p/" + util::toString(tile.id)
+ );
+ bucket.texture = std::move(view->getTexture());
+ bucket.setPrepared(true);
+ } else if (parameters.pass == RenderPass::Translucent) {
+ assert(bucket.texture);
+
+ if (bucket.vertexBuffer && bucket.indexBuffer && !bucket.segments.empty()) {
+ // Draw only the parts of the tile that aren't drawn by another tile in the layer.
+ draw(parameters.matrixForTile(tile.id, true),
+ *bucket.vertexBuffer,
+ *bucket.indexBuffer,
+ bucket.segments,
+ tile.id,
+ HillshadeProgram::TextureBindings{
+ textures::image::Value{ bucket.texture->getResource(), gfx::TextureFilterType::Linear },
+ });
+ } else {
+ // Draw the full tile.
+ draw(parameters.matrixForTile(tile.id, true),
+ *parameters.staticData.rasterVertexBuffer,
+ *parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.rasterSegments,
+ tile.id,
+ HillshadeProgram::TextureBindings{
+ textures::image::Value{ bucket.texture->getResource(), gfx::TextureFilterType::Linear },
+ });
+ }
}
+
+
}
-
+ };
+}
- }
+void RenderHillshadeLayer::transition(const TransitionParameters& parameters) {
+ unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
+}
+
+void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& parameters) {
+ auto properties = makeMutable<HillshadeLayerProperties>(
+ staticImmutableCast<HillshadeLayer::Impl>(baseImpl),
+ unevaluated.evaluate(parameters));
+ passes = (properties->evaluated.get<style::HillshadeExaggeration >() > 0)
+ ? (RenderPass::Translucent | RenderPass::Pass3D)
+ : RenderPass::None;
+
+ evaluatedProperties = std::move(properties);
+}
+
+bool RenderHillshadeLayer::hasTransition() const {
+ return unevaluated.hasTransition();
+}
+
+bool RenderHillshadeLayer::hasCrossfade() const {
+ return false;
+}
+
+void RenderHillshadeLayer::prepare(const LayerPrepareParameters& params) {
+ RenderLayer::prepare(params);
+ maxzoom = params.source->getMaxZoom();
}
} // namespace mbgl