diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 3a5f73270..a465f657f 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -90,7 +90,9 @@ public: void preparePrerender(PrerenderedTexture &texture); void finishPrerender(PrerenderedTexture &texture); -// void renderPrerenderedTexture(PrerenderedTexture &texture, const GenericProperties &properties); + + template + void renderPrerenderedTexture(PrerenderedTexture &texture, const Properties &properties); void resize(); diff --git a/include/llmr/style/rasterize_properties.hpp b/include/llmr/style/rasterize_properties.hpp index 4cfe47289..440f3e530 100644 --- a/include/llmr/style/rasterize_properties.hpp +++ b/include/llmr/style/rasterize_properties.hpp @@ -5,21 +5,32 @@ namespace llmr { +// The calculated properties for a layer in a tile. +class RasterizedProperties { +public: + float buffer = 1.0f / 32.0f; + uint16_t size = 256; + uint8_t blur = 0; +}; + class RasterizeProperties { public: Function enabled = ConstantFunction(false); Function buffer = ConstantFunction(1.0f / 32.0f); Function size = ConstantFunction(256); Function blur = ConstantFunction(0); -}; -// The calculated properties for a layer in a tile. -class RasterizedProperties { -public: - bool enabled = false; - float buffer = 1.0f / 32.0f; - uint16_t size = 256; - uint8_t blur = 0; + inline bool isEnabled(const int8_t z) const { + return util::apply_visitor(FunctionEvaluator(z), enabled); + } + + inline RasterizedProperties get(const int8_t z) const { + RasterizedProperties properties; + properties.buffer = util::apply_visitor(FunctionEvaluator(z), buffer); + properties.size = util::apply_visitor(FunctionEvaluator(z), size); + properties.blur = util::apply_visitor(FunctionEvaluator(z), blur); + return properties; + } }; } diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index e651d3f36..f43ceed9f 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -152,53 +152,53 @@ void Painter::renderFill(FillBucket& bucket, std::shared_ptr layer_d const FillProperties &properties = layer_desc->getProperties(); if (!properties.enabled) return; -// if (properties.prerender && properties.getPrerender(id.z)) { -// if (pass == Translucent) { -// // 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) { -// const PrerenderProperties prerender = properties.getPrerenderProperties(id.z); -// bucket.prerendered = std::make_unique(prerender); -// 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 = prerender.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 (prerender.blur > 0) { -// bucket.prerendered->blur(*this, prerender.blur); -// } -// -// // RESET STATE -// bucket.prerendered->unbindFramebuffer(); -// finishPrerender(*bucket.prerendered); -// } -// -// renderPrerenderedTexture(*bucket.prerendered, properties); -// } -// } else { + 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 3985309df..76fbc74cd 100644 --- a/src/renderer/painter_prerender.cpp +++ b/src/renderer/painter_prerender.cpp @@ -1,4 +1,5 @@ #include +#include using namespace llmr; @@ -23,21 +24,24 @@ void Painter::finishPrerender(PrerenderedTexture &texture) { glViewport(0, 0, gl_viewport[0], gl_viewport[1]); } -//void Painter::renderPrerenderedTexture(PrerenderedTexture &texture, const GenericProperties &properties) { -// const int buffer = texture.properties.buffer * 4096.0f; -// -// // draw the texture on a quad -// useProgram(rasterShader->program); -// rasterShader->setMatrix(matrix); -// rasterShader->setOpacity(1); -// -// glDepthRange(strata, 1.0f); -// -// glActiveTexture(GL_TEXTURE0); -// rasterShader->setImage(0); -// rasterShader->setBuffer(buffer); -// rasterShader->setOpacity(properties.opacity); -// texture.bindTexture(); -// coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); -// glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); -//} +template +void Painter::renderPrerenderedTexture(PrerenderedTexture &texture, const Properties &properties) { + const int buffer = texture.properties.buffer * 4096.0f; + + // draw the texture on a quad + useProgram(rasterShader->program); + rasterShader->setMatrix(matrix); + rasterShader->setOpacity(1); + + glDepthRange(strata, 1.0f); + + glActiveTexture(GL_TEXTURE0); + rasterShader->setImage(0); + rasterShader->setBuffer(buffer); + rasterShader->setOpacity(properties.opacity); + texture.bindTexture(); + coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); +} + +template void Painter::renderPrerenderedTexture(PrerenderedTexture &, const FillProperties &);