draw by layer, not by tile

This is needed for correctly compositing raster imagery into the map

fixes #122
fixes #157
This commit is contained in:
Konstantin Käfer
2014-05-12 17:13:26 +02:00
parent 16e8d8137b
commit 6136ab6d21
8 changed files with 148 additions and 85 deletions

View File

@@ -423,14 +423,16 @@ void Map::render() {
painter.finishClippingMask();
// Render per layer in the stylesheet.
renderLayers(style.layers);
// Then, render each source's tiles. TODO: handle more than one
// vector source.
// Finalize the rendering, e.g. by calling debug render calls per tile.
// This guarantees that we have at least one function per tile called.
// When only rendering layers via the stylesheet, it's possible that we don't
// ever visit a tile during rendering.
for (auto &pair : sources) {
Source &source = *pair.second;
painter.setCurrentSourceName(pair.first);
source.render();
source.finishRender();
}
painter.renderMatte();
@@ -442,3 +444,55 @@ void Map::render() {
update();
}
}
void Map::renderLayers(const std::vector<LayerDescription>& layers) {
// TODO: Correctly compute the number of layers recursively beforehand.
float strata_thickness = 1.0f / (layers.size() + 1);
// - FIRST PASS ------------------------------------------------------------
// Render everything top-to-bottom by using reverse iterators. Render opaque
// objects first.
painter.startOpaquePass();
typedef std::vector<LayerDescription>::const_reverse_iterator riterator;
int i = 0;
for (riterator it = layers.rbegin(), end = layers.rend(); it != end; ++it, ++i) {
painter.setStrata(i * strata_thickness);
renderLayer(*it);
}
painter.endPass();
// - SECOND PASS -----------------------------------------------------------
// Make a second pass, rendering translucent objects. This time, we render
// bottom-to-top.
painter.startTranslucentPass();
typedef std::vector<LayerDescription>::const_iterator iterator;
--i;
for (iterator it = layers.begin(), end = layers.end(); it != end; ++it, --i) {
painter.setStrata(i * strata_thickness);
renderLayer(*it);
}
painter.endPass();
}
void Map::renderLayer(const LayerDescription& layer_desc) {
if (layer_desc.child_layer.size()) {
// This is a layer group.
// TODO: create framebuffer
renderLayers(layer_desc.child_layer);
// TODO: render framebuffer on previous framebuffer
} else {
// This is a singular layer. Try to find the bucket associated with
// this layer and render it.
auto bucket_it = style.buckets.find(layer_desc.bucket_name);
if (bucket_it != style.buckets.end()) {
const BucketDescription &bucket_desc = bucket_it->second;
// Find the source and render all tiles in it.
auto source_it = sources.find(bucket_desc.source_name);
if (source_it != sources.end()) {
const std::unique_ptr<Source> &source = source_it->second;
source->render(layer_desc, bucket_desc);
}
}
}
}