Allow property functions for prerender properties, but tie them to the tile's zoom level instead of the map zoom level

fixes #253
This commit is contained in:
Konstantin Käfer
2014-06-01 17:43:12 +02:00
parent 2dc03c733c
commit 1be972eb15
9 changed files with 75 additions and 66 deletions

View File

@@ -152,18 +152,19 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
: defaultFillProperties;
if (!properties.enabled) return;
if (properties.prerender) {
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) {
bucket.prerendered = std::make_unique<PrerenderedTexture>(properties.prerenderSize);
const PrerenderProperties prerender = properties.getPrerenderProperties(id.z);
bucket.prerendered = std::make_unique<PrerenderedTexture>(prerender);
bucket.prerendered->bindFramebuffer();
preparePrerender(properties);
preparePrerender(*bucket.prerendered);
const FillProperties modifiedProperties = [&]{
FillProperties modifiedProperties = properties;
@@ -173,7 +174,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
// 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 = 4096 * properties.prerenderBuffer;
const int buffer = prerender.buffer * 4096.0f;
const mat4 vtxMatrix = [&]{
mat4 vtxMatrix;
matrix::ortho(vtxMatrix, -buffer, 4096 + buffer, -4096 - buffer, buffer, 0, 1);
@@ -187,17 +188,16 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
setTranslucent();
renderFill(bucket, modifiedProperties, id, vtxMatrix);
if (properties.prerenderBlur > 0) {
bucket.prerendered->blur(*this, properties.prerenderBlur);
if (prerender.blur > 0) {
bucket.prerendered->blur(*this, prerender.blur);
}
// RESET STATE
bucket.prerendered->unbindFramebuffer();
finishPrerender(properties);
finishPrerender(*bucket.prerendered);
}
renderPrerenderedTexture(bucket, properties);
renderPrerenderedTexture(*bucket.prerendered, properties);
}
} else {
const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor);

View File

@@ -2,7 +2,7 @@
using namespace llmr;
void Painter::preparePrerender(const GenericProperties &properties) {
void Painter::preparePrerender(PrerenderedTexture &texture) {
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
@@ -13,18 +13,18 @@ void Painter::preparePrerender(const GenericProperties &properties) {
#endif
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, properties.prerenderSize, properties.prerenderSize);
glViewport(0, 0, texture.properties.size, texture.properties.size);
}
void Painter::finishPrerender(const GenericProperties &properties) {
void Painter::finishPrerender(PrerenderedTexture &texture) {
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glViewport(0, 0, gl_viewport[0], gl_viewport[1]);
}
void Painter::renderPrerenderedTexture(Bucket &bucket, const GenericProperties &properties) {
const int buffer = 4096 * properties.prerenderBuffer;
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);
@@ -37,7 +37,7 @@ void Painter::renderPrerenderedTexture(Bucket &bucket, const GenericProperties &
rasterShader->setImage(0);
rasterShader->setBuffer(buffer);
rasterShader->setOpacity(properties.opacity);
bucket.prerendered->bindTexture();
texture.bindTexture();
coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index());
}

View File

@@ -4,8 +4,8 @@
using namespace llmr;
PrerenderedTexture::PrerenderedTexture(uint16_t size)
: size(size) {
PrerenderedTexture::PrerenderedTexture(const PrerenderProperties &properties)
: properties(properties) {
}
PrerenderedTexture::~PrerenderedTexture() {
@@ -28,11 +28,6 @@ void PrerenderedTexture::bindTexture() {
}
glBindTexture(GL_TEXTURE_2D, texture);
// if (!mipmapped) {
// glGenerateMipmap(GL_TEXTURE_2D);
// mipmapped = true;
// }
}
void PrerenderedTexture::bindFramebuffer() {
@@ -45,7 +40,7 @@ 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, size, size, 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);
glBindTexture(GL_TEXTURE_2D, 0);
}
@@ -95,7 +90,7 @@ void PrerenderedTexture::blur(Painter& painter, uint16_t passes) {
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, size, size, 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);
glBindTexture(GL_TEXTURE_2D, 0);
@@ -113,7 +108,7 @@ void PrerenderedTexture::blur(Painter& painter, uint16_t passes) {
#endif
glClear(GL_COLOR_BUFFER_BIT);
painter.gaussianShader->setOffset({{ 1.0f / float(size), 0 }});
painter.gaussianShader->setOffset({{ 1.0f / float(properties.size), 0 }});
glBindTexture(GL_TEXTURE_2D, original_texture);
painter.coveringGaussianArray.bind(*painter.gaussianShader, painter.tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)painter.tileStencilBuffer.index());
@@ -127,7 +122,7 @@ void PrerenderedTexture::blur(Painter& painter, uint16_t passes) {
#endif
glClear(GL_COLOR_BUFFER_BIT);
painter.gaussianShader->setOffset({{ 0, 1.0f / float(size) }});
painter.gaussianShader->setOffset({{ 0, 1.0f / float(properties.size) }});
glBindTexture(GL_TEXTURE_2D, secondary_texture);
painter.coveringGaussianArray.bind(*painter.gaussianShader, painter.tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)painter.tileStencilBuffer.index());

View File

@@ -51,21 +51,10 @@ void Style::cascadeProperties(GenericProperties &properties, const GenericClass&
}
}
if (klass.prerender) {
properties.prerender = klass.prerender.get();
}
if (klass.prerenderBuffer) {
properties.prerenderBuffer = klass.prerenderBuffer.get();
}
if (klass.prerenderSize) {
properties.prerenderSize = klass.prerenderSize.get();
}
if (klass.prerenderBlur) {
properties.prerenderBlur = klass.prerenderBlur.get();
}
properties.prerender = klass.prerender;
properties.prerenderBuffer = klass.prerenderBuffer;
properties.prerenderSize = klass.prerenderSize;
properties.prerenderBlur = klass.prerenderBlur;
}

View File

@@ -561,15 +561,15 @@ void StyleParser::parseGenericClass(GenericClass &klass, JSVal value) {
}
if (value.HasMember("prerender-buffer")) {
klass.prerenderBuffer = toNumber<double>(parseValue(value["prerender-buffer"]));
klass.prerenderBuffer = parseFunction(value["prerender-buffer"]);
}
if (value.HasMember("prerender-size")) {
klass.prerenderSize = toNumber<uint64_t>(parseValue(value["prerender-size"]));
klass.prerenderSize = parseFunction(value["prerender-size"]);
}
if (value.HasMember("prerender-blur")) {
klass.prerenderBlur = toNumber<uint64_t>(parseValue(value["prerender-blur"]));
klass.prerenderBlur = parseFunction(value["prerender-blur"]);
}
}