summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/painter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer/painter.cpp')
-rw-r--r--src/mbgl/renderer/painter.cpp78
1 files changed, 70 insertions, 8 deletions
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);
+ }
}
}