From 9e1156d660cfe220db25c4f21de2aec2ed175487 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Tue, 5 Aug 2014 18:13:02 -0700 Subject: [PATCH] take 2, still not working --- include/mbgl/map/tile_parser.hpp | 2 + include/mbgl/renderer/prerendered_texture.hpp | 5 +- include/mbgl/style/rasterize_properties.hpp | 2 +- include/mbgl/style/style_bucket.hpp | 1 + include/mbgl/style/style_layer.hpp | 5 +- src/map/map.cpp | 68 ++++++++++++++----- src/map/tile_parser.cpp | 14 +++- src/renderer/painter_fill.cpp | 52 +++++++++++++- src/renderer/painter_prerender.cpp | 5 +- src/renderer/prerendered_texture.cpp | 3 +- src/renderer/raster_bucket.cpp | 6 ++ src/style/style_layer.cpp | 5 +- src/style/style_parser.cpp | 31 +++++---- 13 files changed, 152 insertions(+), 47 deletions(-) diff --git a/include/mbgl/map/tile_parser.hpp b/include/mbgl/map/tile_parser.hpp index 9aa0f4dc6..313431c86 100644 --- a/include/mbgl/map/tile_parser.hpp +++ b/include/mbgl/map/tile_parser.hpp @@ -22,6 +22,7 @@ class Sprite; class Style; class StyleBucket; class StyleBucketFill; +class StyleBucketRaster; class StyleBucketLine; class StyleBucketSymbol; class StyleLayerGroup; @@ -45,6 +46,7 @@ private: std::unique_ptr createBucket(std::shared_ptr bucket_desc); std::unique_ptr createFillBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketFill &fill); + std::unique_ptr createRasterBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketRaster &raster); std::unique_ptr createLineBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketLine &line); std::unique_ptr createSymbolBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketSymbol &symbol); diff --git a/include/mbgl/renderer/prerendered_texture.hpp b/include/mbgl/renderer/prerendered_texture.hpp index 9c72e14b8..310375b5e 100644 --- a/include/mbgl/renderer/prerendered_texture.hpp +++ b/include/mbgl/renderer/prerendered_texture.hpp @@ -4,6 +4,7 @@ #include #include #include +//#include namespace mbgl { @@ -11,7 +12,7 @@ class Painter; class PrerenderedTexture : private util::noncopyable { public: - PrerenderedTexture(const RasterizedProperties &properties); + PrerenderedTexture(const RasterBucket &properties); ~PrerenderedTexture(); void bindTexture(); @@ -23,7 +24,7 @@ public: void blur(Painter& painter, uint16_t passes); public: - const RasterizedProperties properties; + const RasterBucket properties; private: GLint previous_fbo = 0; diff --git a/include/mbgl/style/rasterize_properties.hpp b/include/mbgl/style/rasterize_properties.hpp index e1e56d6ec..e156ede77 100644 --- a/include/mbgl/style/rasterize_properties.hpp +++ b/include/mbgl/style/rasterize_properties.hpp @@ -15,7 +15,7 @@ public: class RasterizeProperties { public: -// Function enabled = ConstantFunction(false); // going to need to delete this? or keep ? + Function enabled = ConstantFunction(false); // maybe delete? Function buffer = ConstantFunction(1.0f / 32.0f); Function size = ConstantFunction(256); Function blur = ConstantFunction(0); diff --git a/include/mbgl/style/style_bucket.hpp b/include/mbgl/style/style_bucket.hpp index 25786720b..5cb1b6931 100644 --- a/include/mbgl/style/style_bucket.hpp +++ b/include/mbgl/style/style_bucket.hpp @@ -82,6 +82,7 @@ public: class StyleBucketRaster { public: + bool prerendered = false; uint16_t raster_size = 256; float blur = 0.0f; float buffer = 0.03125f; diff --git a/include/mbgl/style/style_layer.hpp b/include/mbgl/style/style_layer.hpp index 14d60ed9b..bcda9950a 100644 --- a/include/mbgl/style/style_layer.hpp +++ b/include/mbgl/style/style_layer.hpp @@ -20,8 +20,7 @@ class StyleLayerGroup; class StyleLayer { public: - StyleLayer(const std::string &id, std::map &&styles, - std::unique_ptr &&rasterize); + StyleLayer(const std::string &id, std::map &&styles); template const T &getProperties() { if (properties.is()) { @@ -83,7 +82,7 @@ public: // Rasterization properties are used for prerendering the tile to a bitmap, // which is then used as a raster image instead of rendering this layer // directly in every frame. - const std::unique_ptr rasterize; +// const std::unique_ptr rasterize; // Child layer array (if this layer has child layers). std::shared_ptr layers; diff --git a/src/map/map.cpp b/src/map/map.cpp index c5df1f96d..a6e245376 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -649,29 +649,63 @@ void Map::renderLayers(std::shared_ptr group) { } void Map::renderLayer(std::shared_ptr layer_desc, RenderPass pass) { - if (layer_desc->layers && layer_desc->type != StyleLayerType::Raster) { - // This is a layer group. We render them during our translucent render pass. - if (pass == Translucent) { - const CompositeProperties &properties = layer_desc->getProperties(); - if (properties.isVisible()) { - gl::group group(std::string("group: ") + layer_desc->id); + if (layer_desc->layers) { + if (layer_desc->type == StyleLayerType::Raster) { + const RasterProperties &properties = layer_desc->getProperties(); + +// const RasterizedProperties rasterize = layer_desc->getProperties(); +// +// auto prerendered = std::make_unique(rasterize); +// prerendered->bindFramebuffer(); +// +// painter.preparePrerender(*prerendered); +// +// const int buffer = rasterize.buffer * 4096.0f; +// const mat4 vtxMatrix = [&]{ +// mat4 vtxMatrix; +// matrix::ortho(vtxMatrix, -buffer, 4096 + buffer, -4096 - buffer, buffer, 0, 1); +// matrix::translate(vtxMatrix, vtxMatrix, 0, -4096, 0); +// return vtxMatrix; +// }(); +// +// painter.setOpaque(); +// renderLayers(layer_desc->layers); +// painter.setTranslucent(); +// renderLayers(layer_desc->layers); +// +// if (rasterize.blur > 0) { +// prerendered->blur(painter, rasterize.blur); +// } +// +// prerendered->unbindFramebuffer(); +// painter.finishPrerender(*prerendered); +// +// painter.renderPrerenderedTexture(*prerendered, rasterize); + + } else { + // This is a layer group. We render them during our translucent render pass. + if (pass == Translucent) { + const CompositeProperties &properties = layer_desc->getProperties(); + if (properties.isVisible()) { + gl::group group(std::string("group: ") + layer_desc->id); - if (debug::renderTree) { - std::cout << std::string(indent++ * 4, ' ') << "+ " << layer_desc->id - << " (Composite) {" << std::endl; - } + if (debug::renderTree) { + std::cout << std::string(indent++ * 4, ' ') << "+ " << layer_desc->id + << " (Composite) {" << std::endl; + } - painter.pushFramebuffer(); + painter.pushFramebuffer(); - renderLayers(layer_desc->layers); + renderLayers(layer_desc->layers); - GLuint texture = painter.popFramebuffer(); + GLuint texture = painter.popFramebuffer(); - // Render the previous texture onto the screen. - painter.drawComposite(texture, properties); + // Render the previous texture onto the screen. + painter.drawComposite(texture, properties); - if (debug::renderTree) { - std::cout << std::string(--indent * 4, ' ') << "}" << std::endl; + if (debug::renderTree) { + std::cout << std::string(--indent * 4, ' ') << "}" << std::endl; + } } } } diff --git a/src/map/tile_parser.cpp b/src/map/tile_parser.cpp index e32a6068f..ae129b3e7 100644 --- a/src/map/tile_parser.cpp +++ b/src/map/tile_parser.cpp @@ -82,6 +82,7 @@ void TileParser::parseStyleLayers(std::shared_ptr group) { // contain any data that falls into this bucket. tile.buckets[layer_desc->bucket->name] = std::move(bucket); } + // TODO? here, no bucket is being created for prerender raster layers (though buckets are being created for its sublayers)... } } else { fprintf(stderr, "[WARNING] layer '%s' does not have child layers or buckets\n", layer_desc->id.c_str()); @@ -100,8 +101,8 @@ std::unique_ptr TileParser::createBucket(std::shared_ptr bu if (tile.id.z >= std::ceil(bucket_desc->max_zoom)) return nullptr; auto layer_it = vector_data.layers.find(bucket_desc->source_layer); + const VectorTileLayer &layer = layer_it->second; if (layer_it != vector_data.layers.end()) { - const VectorTileLayer &layer = layer_it->second; if (bucket_desc->render.is()) { return createFillBucket(layer, bucket_desc->filter, bucket_desc->render.get()); } else if (bucket_desc->render.is()) { @@ -113,6 +114,9 @@ std::unique_ptr TileParser::createBucket(std::shared_ptr bu } else { fprintf(stderr, "[WARNING] unknown bucket render type for layer '%s' (source layer '%s')\n", bucket_desc->name.c_str(), bucket_desc->source_layer.c_str()); } + } else if (bucket_desc->render.is()) { + // Assume this is a prerendered raster layer -- TODO more thorough checking here?? + return createRasterBucket(layer, bucket_desc->filter, bucket_desc->render.get()); } else { // The layer specified in the bucket does not exist. Do nothing. if (debug::tileParseWarnings) { @@ -148,6 +152,12 @@ std::unique_ptr TileParser::createFillBucket(const VectorTileLayer& laye return obsolete() ? nullptr : std::move(bucket); } +std::unique_ptr TileParser::createRasterBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketRaster &raster) { + std::unique_ptr bucket = std::make_unique(raster); +// addBucketFeatures(bucket, layer, filter); + return obsolete() ? nullptr : std::move(bucket); +} + std::unique_ptr TileParser::createLineBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketLine &line) { std::unique_ptr bucket = std::make_unique(tile.lineVertexBuffer, tile.triangleElementsBuffer, tile.pointElementsBuffer, line); addBucketGeometries(bucket, layer, filter); @@ -158,4 +168,4 @@ std::unique_ptr TileParser::createSymbolBucket(const VectorTileLayer& la std::unique_ptr bucket = std::make_unique(symbol, collision); bucket->addFeatures(layer, filter, tile.id, *spriteAtlas, *sprite, *glyphAtlas, *glyphStore); return obsolete() ? nullptr : std::move(bucket); -} \ No newline at end of file +} diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index d0bfcad83..750aaa465 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -150,6 +150,54 @@ void Painter::renderFill(FillBucket& bucket, std::shared_ptr layer_d // Abort early. if (!bucket.hasData()) return; const FillProperties &properties = layer_desc->getProperties(); - const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); - renderFill(bucket, properties, id, vtxMatrix); + +// if (layer_desc->rasterize && layer_desc->rasterize->isEnabled(id.z)) { +// if (pass == Translucent) { +// const RasterizedProperties rasterize = layer_desc->rasterize->get(id.z); +// // Buffer value around the 0..4096 extent that will be drawn into the 256x256 pixel +// // texture. We later scale the texture so that the actual bounds will align with this +// // tile's bounds. The reason we do this is so that the +// if (!bucket.prerendered) { +// bucket.prerendered = std::make_unique(rasterize); +// bucket.prerendered->bindFramebuffer(); +// +// preparePrerender(*bucket.prerendered); +// +// const FillProperties modifiedProperties = [&]{ +// FillProperties modifiedProperties = properties; +// modifiedProperties.opacity = 1; +// return modifiedProperties; +// }(); +// +// // When drawing the fill, we want to draw a buffer around too, so we +// // essentially downscale everyting, and then upscale it later when rendering. +// const int buffer = rasterize.buffer * 4096.0f; +// const mat4 vtxMatrix = [&]{ +// mat4 vtxMatrix; +// matrix::ortho(vtxMatrix, -buffer, 4096 + buffer, -4096 - buffer, buffer, 0, 1); +// matrix::translate(vtxMatrix, vtxMatrix, 0, -4096, 0); +// return vtxMatrix; +// }(); +// +// setOpaque(); +// renderFill(bucket, modifiedProperties, id, vtxMatrix); +// +// setTranslucent(); +// renderFill(bucket, modifiedProperties, id, vtxMatrix); +// +// if (rasterize.blur > 0) { +// bucket.prerendered->blur(*this, rasterize.blur); +// } +// +// // RESET STATE +// bucket.prerendered->unbindFramebuffer(); +// finishPrerender(*bucket.prerendered); +// } +// +// renderPrerenderedTexture(*bucket.prerendered, properties); +// } +// } else { + const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); + renderFill(bucket, properties, id, vtxMatrix); +// } } diff --git a/src/renderer/painter_prerender.cpp b/src/renderer/painter_prerender.cpp index ad6b56b3c..94ccc7fc4 100644 --- a/src/renderer/painter_prerender.cpp +++ b/src/renderer/painter_prerender.cpp @@ -38,11 +38,12 @@ void Painter::renderPrerenderedTexture(PrerenderedTexture &texture, const Proper glActiveTexture(GL_TEXTURE0); rasterShader->setImage(0); rasterShader->setBuffer(buffer); - rasterShader->setOpacity(properties.opacity); + rasterShader->setOpacity(1); +// rasterShader->setOpacity(properties.opacity); // TODO find a place to pass opacity and change this back texture.bindTexture(); coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); } template void Painter::renderPrerenderedTexture(PrerenderedTexture &, const FillProperties &); -template void Painter::renderPrerenderedTexture(PrerenderedTexture &, const RasterProperties &); +template void Painter::renderPrerenderedTexture(PrerenderedTexture &, const RasterizedProperties &); diff --git a/src/renderer/prerendered_texture.cpp b/src/renderer/prerendered_texture.cpp index 6b08a38a4..78bf2407f 100644 --- a/src/renderer/prerendered_texture.cpp +++ b/src/renderer/prerendered_texture.cpp @@ -40,7 +40,8 @@ void PrerenderedTexture::bindFramebuffer() { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, properties.size, properties.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); +// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, properties.size, properties.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // TODO change this back once i have non-zero size readings glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/src/renderer/raster_bucket.cpp b/src/renderer/raster_bucket.cpp index 0d5bf2122..83289b370 100644 --- a/src/renderer/raster_bucket.cpp +++ b/src/renderer/raster_bucket.cpp @@ -7,6 +7,12 @@ RasterBucket::RasterBucket(const std::shared_ptr &texturepool) : raster(texturepool) { } +//RasterBucket::RasterBucket(const StyleBucketRaster &properties) +// : properties(properties) { +//} + +// TODO ^ Somehow overload with another constructor for prerender? + void RasterBucket::render(Painter &painter, std::shared_ptr layer_desc, const Tile::ID &id) { painter.renderRaster(*this, layer_desc, id); } diff --git a/src/style/style_layer.cpp b/src/style/style_layer.cpp index 1672ad4a8..8ec04d669 100644 --- a/src/style/style_layer.cpp +++ b/src/style/style_layer.cpp @@ -5,9 +5,8 @@ namespace mbgl { -StyleLayer::StyleLayer(const std::string &id, std::map &&styles, - std::unique_ptr &&rasterize) - : id(id), styles(std::move(styles)), rasterize(std::move(rasterize)) {} +StyleLayer::StyleLayer(const std::string &id, std::map &&styles) + : id(id), styles(std::move(styles)) {} bool StyleLayer::isBackground() const { return type == StyleLayerType::Background; diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 3ca874296..60f2195f6 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -493,10 +493,14 @@ std::shared_ptr StyleParser::createLayer(JSVal value) { parseStyles(value, styles); // Parse Rasterization options, as they can't be inherited anyway. - std::unique_ptr rasterize; +// std::unique_ptr rasterize; +// if (value.HasMember("rasterize")) { +// rasterize = parseRasterize(replaceConstant(value["rasterize"])); +// } std::shared_ptr layer = std::make_shared( - layer_id, std::move(styles), std::move(rasterize)); + layer_id, std::move(styles)); +// layer_id, std::move(styles), std::move(rasterize)); if (value.HasMember("layers")) { if (value.HasMember("type")) { @@ -527,12 +531,6 @@ void StyleParser::parseLayer(std::pair> &pair JSVal value = pair.first; std::shared_ptr &layer = pair.second; - if (layer->bucket) { -// if (layer->bucket || layer->layers) { - // Skip parsing this again. We already have a valid layer definition. - return; - } - if (value.HasMember("type")) { JSVal type = value["type"]; if (!type.IsString()) { @@ -542,6 +540,11 @@ void StyleParser::parseLayer(std::pair> &pair } } + if (layer->bucket || (layer->layers && layer->type != StyleLayerType::Raster)) { + // Skip parsing this again. We already have a valid layer definition. + return; + } + // Make sure we have not previously attempted to parse this layer. if (std::find(stack.begin(), stack.end(), layer.get()) != stack.end()) { fprintf(stderr, "[WARNING] layer reference of '%s' is circular\n", layer->id.c_str()); @@ -917,19 +920,19 @@ void StyleParser::parseRender(JSVal value, std::shared_ptr &layer) { parseRenderProperty(value, render.text.ignore_placement, "text-ignore-placement"); parseRenderProperty(value, render.text.optional, "text-optional"); } break; - + case StyleLayerType::Raster: { StyleBucketRaster &render = bucket.render.get(); - auto rasterize = std::make_unique(); +// auto rasterize = std::make_unique(); parseRenderProperty(value, render.raster_size, "raster-size"); parseRenderProperty(value, render.blur, "raster-blur"); parseRenderProperty(value, render.buffer, "raster-buffer"); - -// return rasterize; - + if (layer->layers) { + render.prerendered = true; + } } break; - + default: // There are no render properties for these layer types. break;