From 7d767f518b62ddb00ba0c526b3d52d140c36197c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 23 May 2014 12:40:15 +0200 Subject: [PATCH 01/21] add keys to stylesheet --- include/llmr/style/properties.hpp | 4 ++++ src/style/style.cpp | 8 ++++++++ src/style/style_parser.cpp | 8 ++++++++ 3 files changed, 20 insertions(+) diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index ba0979cb9..616936ea8 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -155,6 +155,8 @@ struct FillClass { boost::optional opacity; boost::optional opacity_transition; boost::optional image; + boost::optional prerendered; + boost::optional blur; }; struct FillProperties { @@ -166,6 +168,8 @@ struct FillProperties { Color fill_color = {{ 0, 0, 0, 1 }}; Color stroke_color = {{ 0, 0, 0, 1 }}; float opacity = 1.0; + bool prerendered = false; + float blur = 0.0f; std::string image; }; diff --git a/src/style/style.cpp b/src/style/style.cpp index 918709924..fce70eade 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -114,6 +114,14 @@ void Style::cascade(float z) { if (layer.image) { fill.image = layer.image.get(); } + + if (layer.prerendered) { + fill.prerendered = layer.prerendered.get().evaluate(z); + } + + if (layer.blur) { + fill.blur = layer.blur.get().evaluate(z); + } } // Cascade line classes. diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index c299f1fd9..52ef85f1d 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -537,6 +537,14 @@ FillClass StyleParser::parseFillClass(JSVal value) { klass.antialias = parseBoolean(value["antialias"]); } + if (value.HasMember("prerendered")) { + klass.prerendered = parseBoolean(value["prerendered"]); + } + + if (value.HasMember("blur")) { + klass.blur = parseFunction(value["blur"]); + } + if (value.HasMember("image")) { klass.image = parseString(value["image"]); } From 889ef68b5b9d3c794aade48ed829b9ba2fcfac2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 23 May 2014 18:30:49 +0200 Subject: [PATCH 02/21] first draft at blurring --- include/llmr/renderer/bucket.hpp | 3 + include/llmr/renderer/painter.hpp | 4 + include/llmr/renderer/prerendered_texture.hpp | 28 +++ include/llmr/shader/gaussian_shader.hpp | 29 ++++ include/llmr/shader/raster_shader.hpp | 4 + src/map/map.cpp | 2 +- src/renderer/painter.cpp | 2 + src/renderer/painter_fill.cpp | 163 ++++++++++++++++-- src/renderer/painter_raster.cpp | 1 + src/renderer/prerendered_texture.cpp | 80 +++++++++ src/shader/gaussian.fragment.glsl | 14 ++ src/shader/gaussian.vertex.glsl | 17 ++ src/shader/gaussian_shader.cpp | 48 ++++++ src/shader/raster.fragment.glsl | 2 +- src/shader/raster.vertex.glsl | 5 +- src/shader/raster_shader.cpp | 9 + src/shader/shaders_gl.cpp | 8 +- src/shader/shaders_gles2.cpp | 8 +- 18 files changed, 410 insertions(+), 17 deletions(-) create mode 100644 include/llmr/renderer/prerendered_texture.hpp create mode 100644 include/llmr/shader/gaussian_shader.hpp create mode 100644 src/renderer/prerendered_texture.cpp create mode 100644 src/shader/gaussian.fragment.glsl create mode 100644 src/shader/gaussian.vertex.glsl create mode 100644 src/shader/gaussian_shader.cpp diff --git a/include/llmr/renderer/bucket.hpp b/include/llmr/renderer/bucket.hpp index 283a2c94b..f8447be89 100644 --- a/include/llmr/renderer/bucket.hpp +++ b/include/llmr/renderer/bucket.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace llmr { @@ -14,6 +15,8 @@ public: virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id) = 0; virtual bool hasData() const = 0; virtual ~Bucket() {} + + std::unique_ptr prerendered; }; } diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index a1db116b6..10f706880 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -77,6 +78,7 @@ public: void renderDebugText(DebugBucket& bucket); void renderDebugText(const std::vector &strings); + void renderFill(FillBucket& bucket, const FillProperties& properties, const Tile::ID& id, const mat4 &mat); void renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderIcon(IconBucket& bucket, const std::string& layer_name, const Tile::ID& id); @@ -148,6 +150,7 @@ private: std::unique_ptr textShader; std::unique_ptr dotShader; std::unique_ptr compositeShader; + std::unique_ptr gaussianShader; // Set up the stencil quad we're using to generate the stencil mask. VertexBuffer tileStencilBuffer = { @@ -165,6 +168,7 @@ private: VertexArrayObject coveringPlainArray; VertexArrayObject coveringPatternArray; VertexArrayObject coveringRasterArray; + VertexArrayObject coveringGaussianArray; VertexArrayObject compositeArray; VertexArrayObject matteArray; diff --git a/include/llmr/renderer/prerendered_texture.hpp b/include/llmr/renderer/prerendered_texture.hpp new file mode 100644 index 000000000..f74fe1d11 --- /dev/null +++ b/include/llmr/renderer/prerendered_texture.hpp @@ -0,0 +1,28 @@ +#ifndef LLMR_RENDERER_PRERENDERED_TEXTURE +#define LLMR_RENDERER_PRERENDERED_TEXTURE + +#include +#include + +namespace llmr { + +class PrerenderedTexture : private util::noncopyable { +public: + ~PrerenderedTexture(); + + void bindTexture(); + void bindFramebuffer(); + void unbindFramebuffer(); + + inline GLuint getTexture() const { return texture; } + +private: + GLint previous_fbo = 0; + GLuint fbo = 0; + GLuint texture = 0; + bool mipmapped = false; +}; + +} + +#endif diff --git a/include/llmr/shader/gaussian_shader.hpp b/include/llmr/shader/gaussian_shader.hpp new file mode 100644 index 000000000..c3589c153 --- /dev/null +++ b/include/llmr/shader/gaussian_shader.hpp @@ -0,0 +1,29 @@ +#ifndef LLMR_RENDERER_SHADER_GAUSSIAN +#define LLMR_RENDERER_SHADER_GAUSSIAN + +#include + +namespace llmr { + +class GaussianShader : public Shader { +public: + GaussianShader(); + + void bind(char *offset); + + void setImage(int32_t image); + void setOffset(const std::array& offset); + +private: + int32_t a_pos = -1; + + int32_t image = 0; + int32_t u_image = -1; + + std::array offset = {{}}; + int32_t u_offset = -1; +}; + +} + +#endif diff --git a/include/llmr/shader/raster_shader.hpp b/include/llmr/shader/raster_shader.hpp index d037b6e80..adc945e46 100644 --- a/include/llmr/shader/raster_shader.hpp +++ b/include/llmr/shader/raster_shader.hpp @@ -13,6 +13,7 @@ public: void setImage(int32_t image); void setOpacity(float opacity); + void setBuffer(float buffer); private: int32_t a_pos = -1; @@ -22,6 +23,9 @@ private: float opacity = 0; int32_t u_opacity = -1; + + float buffer = 0; + int32_t u_buffer = -1; }; } diff --git a/src/map/map.cpp b/src/map/map.cpp index 3c0fbbcbb..13e42727d 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -132,10 +132,10 @@ void Map::cleanup(uv_async_t *async) { void Map::render(uv_async_t *async) { Map *map = static_cast(async->data); - map->prepare(); if (map->state.hasSize()) { if (map->is_rendered.test_and_set() == false) { + map->prepare(); if (map->is_clean.test_and_set() == false) { map->render(); map->is_swapped.clear(); diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 8f609d881..1c568073a 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -43,6 +43,7 @@ void Painter::setup() { assert(textShader); assert(dotShader); assert(compositeShader); + assert(gaussianShader); // Blending @@ -73,6 +74,7 @@ void Painter::setupShaders() { textShader = std::make_unique(); dotShader = std::make_unique(); compositeShader = std::make_unique(); + gaussianShader = std::make_unique(); } void Painter::cleanup() { diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 289e85dfb..18f84ad58 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -3,20 +3,13 @@ #include #include #include +#include using namespace llmr; -void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id) { - // Abort early. - if (!bucket.hasData()) return; - auto fill_properties = map.getStyle().computed.fills; - auto fill_properties_it = fill_properties.find(layer_name); - if (fill_properties_it == fill_properties.end()) return; - - const FillProperties& properties = fill_properties_it->second; - if (!properties.enabled) return; +void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, const Tile::ID& id, const mat4 &vtxMatrix) { Color fill_color = properties.fill_color; fill_color[0] *= properties.opacity; fill_color[1] *= properties.opacity; @@ -36,7 +29,6 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons stroke_color = fill_color; } - const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); // Because we're drawing top-to-bottom, and we update the stencil mask // below, we have to draw the outline first (!) @@ -147,3 +139,154 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons bucket.drawVertices(*outlineShader); } } + +void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id) { + // Abort early. + if (!bucket.hasData()) return; + + auto fill_properties = map.getStyle().computed.fills; + auto fill_properties_it = fill_properties.find(layer_name); + if (fill_properties_it == fill_properties.end()) return; + + const FillProperties& properties = fill_properties_it->second; + if (!properties.enabled) return; + + + if (properties.prerendered) { + if (pass == Translucent) { + // Buffer value around the 0..4096 extent that will be drawn into the 256x256 pixel + // texture. We later scale + const int buffer = 256; + + if (!bucket.prerendered) { + bucket.prerendered = std::make_unique(); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + + bucket.prerendered->bindFramebuffer(); + // Render the actual tile. +#if GL_EXT_discard_framebuffer + const GLenum discards[] = { GL_COLOR_ATTACHMENT0 }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); +#endif + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, 256, 256); + + + // When drawing the fill, we want to draw a 16.66% buffer around too, so we + // essentially downscale everyting, and then upscale it later when rendering. + + mat4 vtxMatrix; + matrix::ortho(vtxMatrix, -buffer, 4096 + buffer, -4096 - buffer, buffer, 0, 1); + matrix::translate(vtxMatrix, vtxMatrix, 0, -4096, 0); + + pass = Opaque; + renderFill(bucket, properties, id, vtxMatrix); + pass = Translucent; + renderFill(bucket, properties, id, vtxMatrix); + + + + // BLUR + + GLuint original_texture = bucket.prerendered->getTexture(); + + GLuint secondary_texture; + glGenTextures(1, &secondary_texture); + glBindTexture(GL_TEXTURE_2D, secondary_texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + 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, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + + useProgram(gaussianShader->program); + gaussianShader->setMatrix(vtxMatrix); + gaussianShader->setImage(0); + glActiveTexture(GL_TEXTURE0); + + const GLenum discards[] = { GL_COLOR_ATTACHMENT0 }; + + for (int i = 0; i < 1 ; i++) { + // Render horizontal + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, secondary_texture, 0); +#if GL_EXT_discard_framebuffer + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); +#endif + glClear(GL_COLOR_BUFFER_BIT); + + gaussianShader->setOffset({{ 1.0f / 256.0f, 0 }}); + glBindTexture(GL_TEXTURE_2D, original_texture); + coveringGaussianArray.bind(*gaussianShader, tileStencilBuffer, BUFFER_OFFSET(0)); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); + + + + // Render vertical + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, original_texture, 0); +#if GL_EXT_discard_framebuffer + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); +#endif + glClear(GL_COLOR_BUFFER_BIT); + + gaussianShader->setOffset({{ 0, 1.0f / 256.0f }}); + glBindTexture(GL_TEXTURE_2D, secondary_texture); + coveringGaussianArray.bind(*gaussianShader, tileStencilBuffer, BUFFER_OFFSET(0)); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); + } + + glDeleteTextures(1, &secondary_texture); + + + + + + // RENDER DEBUG FRAME + useProgram(plainShader->program); + + plainShader->setMatrix(vtxMatrix); + + // draw tile outline + tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0)); + plainShader->setColor(0, 1, 1, 1); + lineWidth(2); + glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index()); + + + + // RESET STATE + + + bucket.prerendered->unbindFramebuffer(); + glEnable(GL_DEPTH_TEST); + glEnable(GL_STENCIL_TEST); + + glViewport(0, 0, gl_viewport[0], gl_viewport[1]); + } + + // draw the texture on a quad + depthMask(false); + + useProgram(rasterShader->program); + rasterShader->setMatrix(matrix); + rasterShader->setOpacity(1); + + glDepthRange(strata, 1.0f); + + glActiveTexture(GL_TEXTURE0); + rasterShader->setImage(0); + rasterShader->setBuffer(0); + bucket.prerendered->bindTexture(); + coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); + + depthMask(true); + } + } else { + const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); + renderFill(bucket, properties, id, vtxMatrix); + } +} diff --git a/src/renderer/painter_raster.cpp b/src/renderer/painter_raster.cpp index 410f1a000..b877496e0 100644 --- a/src/renderer/painter_raster.cpp +++ b/src/renderer/painter_raster.cpp @@ -18,6 +18,7 @@ void Painter::renderRaster(RasterBucket& bucket, const std::string& layer_name, useProgram(rasterShader->program); rasterShader->setMatrix(matrix); + rasterShader->setBuffer(0); rasterShader->setOpacity(1); // rasterShader->setOpacity(properties.opacity * tile_data->raster->opacity); diff --git a/src/renderer/prerendered_texture.cpp b/src/renderer/prerendered_texture.cpp new file mode 100644 index 000000000..3fd81ccdf --- /dev/null +++ b/src/renderer/prerendered_texture.cpp @@ -0,0 +1,80 @@ +#include + + +using namespace llmr; + +PrerenderedTexture::~PrerenderedTexture() { + if (texture != 0) { + glDeleteTextures(1, &texture); + texture = 0; + } + + if (fbo != 0) { + glDeleteFramebuffers(1, &fbo); + fbo = 0; + } +} + + +void PrerenderedTexture::bindTexture() { + if (texture == 0) { + bindFramebuffer(); + unbindFramebuffer(); + } + + glBindTexture(GL_TEXTURE_2D, texture); + + // if (!mipmapped) { + // glGenerateMipmap(GL_TEXTURE_2D); + // mipmapped = true; + // } +} + +void PrerenderedTexture::bindFramebuffer() { + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previous_fbo); + + if (texture == 0) { + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + 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, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glBindTexture(GL_TEXTURE_2D, 0); + } + + if (fbo == 0) { + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + fprintf(stderr, "Couldn't create framebuffer: "); + switch (status) { + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: fprintf(stderr, "incomplete attachment\n"); break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: fprintf(stderr, "incomplete missing attachment\n"); break; +#ifdef GL_ES_VERSION_2_0 + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: fprintf(stderr, "incomplete dimensions\n"); break; +#else + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: fprintf(stderr, "incomplete draw buffer\n"); break; +#endif + case GL_FRAMEBUFFER_UNSUPPORTED: fprintf(stderr, "unsupported\n"); break; + default: fprintf(stderr, "other\n"); break; + } + return; + } + } else { + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + } +} + +void PrerenderedTexture::unbindFramebuffer() { + glBindFramebuffer(GL_FRAMEBUFFER, previous_fbo); + + if (fbo != 0) { + glDeleteFramebuffers(1, &fbo); + fbo = 0; + } +} diff --git a/src/shader/gaussian.fragment.glsl b/src/shader/gaussian.fragment.glsl new file mode 100644 index 000000000..b7b193b26 --- /dev/null +++ b/src/shader/gaussian.fragment.glsl @@ -0,0 +1,14 @@ +uniform sampler2D u_image; + +varying vec2 v_coords[5]; + +void main() +{ + vec4 sum = vec4(0.0); + sum += texture2D(u_image, v_coords[0]) * 0.204164; + sum += texture2D(u_image, v_coords[1]) * 0.304005; + sum += texture2D(u_image, v_coords[2]) * 0.304005; + sum += texture2D(u_image, v_coords[3]) * 0.093913; + sum += texture2D(u_image, v_coords[4]) * 0.093913; + gl_FragColor = sum; +} \ No newline at end of file diff --git a/src/shader/gaussian.vertex.glsl b/src/shader/gaussian.vertex.glsl new file mode 100644 index 000000000..4f60e2a11 --- /dev/null +++ b/src/shader/gaussian.vertex.glsl @@ -0,0 +1,17 @@ +attribute vec2 a_pos; + +uniform mat4 u_matrix; +uniform vec2 u_offset; + +varying vec2 v_coords[5]; + +void main() { + gl_Position = u_matrix * vec4(a_pos, 0, 1); + + vec2 tex = (gl_Position.xy + 1.0) / 2.0; + v_coords[0] = tex; + v_coords[1] = tex + u_offset * 1.407333; + v_coords[2] = tex - u_offset * 1.407333; + v_coords[3] = tex + u_offset * 3.294215; + v_coords[4] = tex - u_offset * 3.294215; +} diff --git a/src/shader/gaussian_shader.cpp b/src/shader/gaussian_shader.cpp new file mode 100644 index 000000000..450ce331a --- /dev/null +++ b/src/shader/gaussian_shader.cpp @@ -0,0 +1,48 @@ +#include +#include +#include + +#include + +using namespace llmr; + +GaussianShader::GaussianShader() + : Shader( + shaders[GAUSSIAN_SHADER].vertex, + shaders[GAUSSIAN_SHADER].fragment + ) { + if (!valid) { + fprintf(stderr, "invalid raster shader\n"); + return; + } + + a_pos = glGetAttribLocation(program, "a_pos"); + + u_matrix = glGetUniformLocation(program, "u_matrix"); + u_image = glGetUniformLocation(program, "u_image"); + u_offset = glGetUniformLocation(program, "u_offset"); + + // fprintf(stderr, "GaussianShader:\n"); + // fprintf(stderr, " - u_matrix: %d\n", u_matrix); + // fprintf(stderr, " - u_image: %d\n", u_image); + // fprintf(stderr, " - u_gaussian: %f\n", u_gaussian); +} + +void GaussianShader::bind(char *offset) { + glEnableVertexAttribArray(a_pos); + glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset); +} + +void GaussianShader::setImage(int32_t new_image) { + if (image != new_image) { + glUniform1i(u_image, new_image); + image = new_image; + } +} + +void GaussianShader::setOffset(const std::array& new_offset) { + if (offset != new_offset) { + glUniform2fv(u_offset, 1, new_offset.data()); + offset = new_offset; + } +} diff --git a/src/shader/raster.fragment.glsl b/src/shader/raster.fragment.glsl index feb0a58f0..11be6d336 100644 --- a/src/shader/raster.fragment.glsl +++ b/src/shader/raster.fragment.glsl @@ -4,5 +4,5 @@ uniform float u_opacity; varying vec2 v_pos; void main() { - gl_FragColor = texture2D(u_image, v_pos) * u_opacity; + gl_FragColor = texture2D(u_image, v_pos, 2) * u_opacity; } diff --git a/src/shader/raster.vertex.glsl b/src/shader/raster.vertex.glsl index 75d6c8d14..97e563f58 100644 --- a/src/shader/raster.vertex.glsl +++ b/src/shader/raster.vertex.glsl @@ -1,10 +1,13 @@ uniform mat4 u_matrix; +uniform float u_buffer; attribute vec2 a_pos; varying vec2 v_pos; + void main() { gl_Position = u_matrix * vec4(a_pos, 0, 1); - v_pos = a_pos / 4096.0; + float dimension = (4096.0 + 2.0 * u_buffer); + v_pos = (a_pos / dimension) + (u_buffer / dimension); } diff --git a/src/shader/raster_shader.cpp b/src/shader/raster_shader.cpp index 718fa9c35..eaf45ea2b 100644 --- a/src/shader/raster_shader.cpp +++ b/src/shader/raster_shader.cpp @@ -21,11 +21,13 @@ RasterShader::RasterShader() u_matrix = glGetUniformLocation(program, "u_matrix"); u_image = glGetUniformLocation(program, "u_image"); u_opacity = glGetUniformLocation(program, "u_opacity"); + u_buffer = glGetUniformLocation(program, "u_buffer"); // fprintf(stderr, "RasterShader:\n"); // fprintf(stderr, " - u_matrix: %d\n", u_matrix); // fprintf(stderr, " - u_image: %d\n", u_image); // fprintf(stderr, " - u_opacity: %f\n", u_opacity); + // fprintf(stderr, " - u_buffer: %f\n", u_buffer); } void RasterShader::bind(char *offset) { @@ -46,3 +48,10 @@ void RasterShader::setOpacity(float new_opacity) { opacity = new_opacity; } } + +void RasterShader::setBuffer(float new_buffer) { + if (buffer != new_buffer) { + glUniform1f(u_buffer, new_buffer); + buffer = new_buffer; + } +} diff --git a/src/shader/shaders_gl.cpp b/src/shader/shaders_gl.cpp index 1cd6da1b1..84fc539b4 100644 --- a/src/shader/shaders_gl.cpp +++ b/src/shader/shaders_gl.cpp @@ -14,6 +14,10 @@ const shader_source llmr::shaders[SHADER_COUNT] = { "#version 120\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform float u_size;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n}\n\n", "#version 120\nuniform vec4 u_color;\nuniform float u_blur;\nvoid main ()\n{\n vec2 x_1;\n x_1 = (gl_PointCoord - 0.5);\n float tmpvar_2;\n tmpvar_2 = clamp (((\n sqrt(dot (x_1, x_1))\n - 0.5) / (\n (0.5 - u_blur)\n - 0.5)), 0.0, 1.0);\n gl_FragColor = (u_color * (tmpvar_2 * (tmpvar_2 * \n (3.0 - (2.0 * tmpvar_2))\n )));\n}\n\n", }, + { + "#version 120\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform vec2 u_offset;\nvarying vec2 v_coords[5];\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n vec4 tmpvar_2;\n tmpvar_2 = (u_matrix * tmpvar_1);\n gl_Position = tmpvar_2;\n vec2 tmpvar_3;\n tmpvar_3 = ((tmpvar_2.xy + 1.0) / 2.0);\n v_coords[0] = tmpvar_3;\n vec2 cse_4;\n cse_4 = (u_offset * 1.40733);\n v_coords[1] = (tmpvar_3 + cse_4);\n v_coords[2] = (tmpvar_3 - cse_4);\n vec2 cse_5;\n cse_5 = (u_offset * 3.29421);\n v_coords[3] = (tmpvar_3 + cse_5);\n v_coords[4] = (tmpvar_3 - cse_5);\n}\n\n", + "#version 120\nuniform sampler2D u_image;\nvarying vec2 v_coords[5];\nvoid main ()\n{\n gl_FragColor = (((\n ((texture2D (u_image, v_coords[0]) * 0.204164) + (texture2D (u_image, v_coords[1]) * 0.304005))\n + \n (texture2D (u_image, v_coords[2]) * 0.304005)\n ) + (texture2D (u_image, v_coords[3]) * 0.093913)) + (texture2D (u_image, v_coords[4]) * 0.093913));\n}\n\n", + }, { "#version 120\nattribute vec2 a_pos;\nattribute vec2 a_tex;\nuniform mat4 u_matrix;\nuniform float u_size;\nuniform float u_ratio;\nvarying vec2 v_tex;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n v_tex = (a_tex * u_ratio);\n}\n\n", "#version 120\nuniform sampler2D u_image;\nuniform vec2 u_dimension;\nuniform vec4 u_color;\nuniform float u_size;\nvarying vec2 v_tex;\nvoid main ()\n{\n gl_FragColor = (u_color * texture2D (u_image, ((v_tex + \n ((gl_PointCoord - 0.5) * u_size)\n ) / u_dimension)));\n}\n\n", @@ -39,8 +43,8 @@ const shader_source llmr::shaders[SHADER_COUNT] = { "#version 120\nuniform vec4 u_color;\nvoid main ()\n{\n gl_FragColor = u_color;\n}\n\n", }, { - "#version 120\nuniform mat4 u_matrix;\nattribute vec2 a_pos;\nvarying vec2 v_pos;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n v_pos = (a_pos / 4096.0);\n}\n\n", - "#version 120\nuniform sampler2D u_image;\nuniform float u_opacity;\nvarying vec2 v_pos;\nvoid main ()\n{\n gl_FragColor = (texture2D (u_image, v_pos) * u_opacity);\n}\n\n", + "#version 120\nuniform mat4 u_matrix;\nuniform float u_buffer;\nattribute vec2 a_pos;\nvarying vec2 v_pos;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n float tmpvar_2;\n tmpvar_2 = (4096.0 + (2.0 * u_buffer));\n v_pos = ((a_pos / tmpvar_2) + (u_buffer / tmpvar_2));\n}\n\n", + "#version 120\nuniform sampler2D u_image;\nuniform float u_opacity;\nvarying vec2 v_pos;\nvoid main ()\n{\n gl_FragColor = (texture2D (u_image, v_pos, 2.0) * u_opacity);\n}\n\n", }, { "#version 120\nattribute vec2 a_pos;\nattribute vec2 a_offset;\nattribute vec4 a_data1;\nattribute vec4 a_data2;\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\nuniform float u_angle;\nuniform float u_zoom;\nuniform float u_flip;\nuniform float u_fadedist;\nuniform float u_minfadezoom;\nuniform float u_maxfadezoom;\nuniform float u_fadezoom;\nuniform vec2 u_texsize;\nvarying vec2 v_tex;\nvarying float v_alpha;\nvoid main ()\n{\n float rev_1;\n rev_1 = 0.0;\n float tmpvar_2;\n tmpvar_2 = (float(mod ((a_data1.w + u_angle), 256.0)));\n if ((((u_flip > 0.0) && (tmpvar_2 >= 64.0)) && (tmpvar_2 < 192.0))) {\n rev_1 = 1.0;\n };\n float tmpvar_3;\n tmpvar_3 = (((2.0 - \n float((u_zoom >= a_data2.x))\n ) - (1.0 - \n float((u_zoom >= a_data2.y))\n )) + rev_1);\n float tmpvar_4;\n tmpvar_4 = clamp (((u_fadezoom - a_data1.z) / u_fadedist), 0.0, 1.0);\n if ((u_fadedist >= 0.0)) {\n v_alpha = tmpvar_4;\n } else {\n v_alpha = (1.0 - tmpvar_4);\n };\n if ((u_maxfadezoom < a_data1.z)) {\n v_alpha = 0.0;\n };\n if ((u_minfadezoom >= a_data1.z)) {\n v_alpha = 1.0;\n };\n vec4 tmpvar_5;\n tmpvar_5.zw = vec2(0.0, 1.0);\n tmpvar_5.xy = a_pos;\n vec4 tmpvar_6;\n tmpvar_6.w = 0.0;\n tmpvar_6.xy = (a_offset / 64.0);\n tmpvar_6.z = ((tmpvar_3 + float(\n (0.0 >= v_alpha)\n )) + (float(\n (u_angle >= a_data2.z)\n ) * (1.0 - \n float((u_angle >= a_data2.w))\n )));\n gl_Position = ((u_matrix * tmpvar_5) + (u_exmatrix * tmpvar_6));\n v_tex = ((a_data1.xy * 4.0) / u_texsize);\n}\n\n", diff --git a/src/shader/shaders_gles2.cpp b/src/shader/shaders_gles2.cpp index 5dd8df43d..6dad644e7 100644 --- a/src/shader/shaders_gles2.cpp +++ b/src/shader/shaders_gles2.cpp @@ -14,6 +14,10 @@ const shader_source llmr::shaders[SHADER_COUNT] = { "precision highp float;\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform float u_size;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n}\n\n", "precision highp float;\nuniform vec4 u_color;\nuniform float u_blur;\nvoid main ()\n{\n mediump vec2 x_1;\n x_1 = (gl_PointCoord - 0.5);\n mediump float tmpvar_2;\n tmpvar_2 = clamp (((\n sqrt(dot (x_1, x_1))\n - 0.5) / (\n (0.5 - u_blur)\n - 0.5)), 0.0, 1.0);\n gl_FragColor = (u_color * (tmpvar_2 * (tmpvar_2 * \n (3.0 - (2.0 * tmpvar_2))\n )));\n}\n\n", }, + { + "precision highp float;\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform vec2 u_offset;\nvarying highp vec2 v_coords[5];\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n vec4 tmpvar_2;\n tmpvar_2 = (u_matrix * tmpvar_1);\n gl_Position = tmpvar_2;\n highp vec2 tmpvar_3;\n tmpvar_3 = ((tmpvar_2.xy + 1.0) / 2.0);\n v_coords[0] = tmpvar_3;\n vec2 cse_4;\n cse_4 = (u_offset * 1.40733);\n v_coords[1] = (tmpvar_3 + cse_4);\n v_coords[2] = (tmpvar_3 - cse_4);\n vec2 cse_5;\n cse_5 = (u_offset * 3.29421);\n v_coords[3] = (tmpvar_3 + cse_5);\n v_coords[4] = (tmpvar_3 - cse_5);\n}\n\n", + "precision highp float;\nuniform sampler2D u_image;\nvarying vec2 v_coords[5];\nvoid main ()\n{\n lowp vec4 tmpvar_1;\n tmpvar_1 = (((\n ((texture2D (u_image, v_coords[0]) * 0.204164) + (texture2D (u_image, v_coords[1]) * 0.304005))\n + \n (texture2D (u_image, v_coords[2]) * 0.304005)\n ) + (texture2D (u_image, v_coords[3]) * 0.093913)) + (texture2D (u_image, v_coords[4]) * 0.093913));\n gl_FragColor = tmpvar_1;\n}\n\n", + }, { "precision highp float;\nattribute vec2 a_pos;\nattribute vec2 a_tex;\nuniform mat4 u_matrix;\nuniform float u_size;\nuniform float u_ratio;\nvarying vec2 v_tex;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n v_tex = (a_tex * u_ratio);\n}\n\n", "precision highp float;\nuniform sampler2D u_image;\nuniform vec2 u_dimension;\nuniform vec4 u_color;\nuniform float u_size;\nvarying vec2 v_tex;\nvoid main ()\n{\n mediump vec2 tmpvar_1;\n tmpvar_1 = ((v_tex + (\n (gl_PointCoord - 0.5)\n * u_size)) / u_dimension);\n lowp vec4 tmpvar_2;\n tmpvar_2 = (u_color * texture2D (u_image, tmpvar_1));\n gl_FragColor = tmpvar_2;\n}\n\n", @@ -39,8 +43,8 @@ const shader_source llmr::shaders[SHADER_COUNT] = { "precision highp float;\nuniform vec4 u_color;\nvoid main ()\n{\n gl_FragColor = u_color;\n}\n\n", }, { - "precision highp float;\nuniform mat4 u_matrix;\nattribute vec2 a_pos;\nvarying vec2 v_pos;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n v_pos = (a_pos / 4096.0);\n}\n\n", - "precision highp float;\nuniform sampler2D u_image;\nuniform float u_opacity;\nvarying vec2 v_pos;\nvoid main ()\n{\n lowp vec4 tmpvar_1;\n tmpvar_1 = (texture2D (u_image, v_pos) * u_opacity);\n gl_FragColor = tmpvar_1;\n}\n\n", + "precision highp float;\nuniform mat4 u_matrix;\nuniform float u_buffer;\nattribute vec2 a_pos;\nvarying vec2 v_pos;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n float tmpvar_2;\n tmpvar_2 = (4096.0 + (2.0 * u_buffer));\n v_pos = ((a_pos / tmpvar_2) + (u_buffer / tmpvar_2));\n}\n\n", + "precision highp float;\nuniform sampler2D u_image;\nuniform float u_opacity;\nvarying vec2 v_pos;\nvoid main ()\n{\n lowp vec4 tmpvar_1;\n tmpvar_1 = (texture2D (u_image, v_pos, 2.0) * u_opacity);\n gl_FragColor = tmpvar_1;\n}\n\n", }, { "precision highp float;\nattribute vec2 a_pos;\nattribute vec2 a_offset;\nattribute vec4 a_data1;\nattribute vec4 a_data2;\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\nuniform float u_angle;\nuniform float u_zoom;\nuniform float u_flip;\nuniform float u_fadedist;\nuniform float u_minfadezoom;\nuniform float u_maxfadezoom;\nuniform float u_fadezoom;\nuniform vec2 u_texsize;\nvarying vec2 v_tex;\nvarying float v_alpha;\nvoid main ()\n{\n float rev_1;\n rev_1 = 0.0;\n float tmpvar_2;\n tmpvar_2 = (float(mod ((a_data1.w + u_angle), 256.0)));\n if ((((u_flip > 0.0) && (tmpvar_2 >= 64.0)) && (tmpvar_2 < 192.0))) {\n rev_1 = 1.0;\n };\n float tmpvar_3;\n tmpvar_3 = (((2.0 - \n float((u_zoom >= a_data2.x))\n ) - (1.0 - \n float((u_zoom >= a_data2.y))\n )) + rev_1);\n float tmpvar_4;\n tmpvar_4 = clamp (((u_fadezoom - a_data1.z) / u_fadedist), 0.0, 1.0);\n if ((u_fadedist >= 0.0)) {\n v_alpha = tmpvar_4;\n } else {\n v_alpha = (1.0 - tmpvar_4);\n };\n if ((u_maxfadezoom < a_data1.z)) {\n v_alpha = 0.0;\n };\n if ((u_minfadezoom >= a_data1.z)) {\n v_alpha = 1.0;\n };\n vec4 tmpvar_5;\n tmpvar_5.zw = vec2(0.0, 1.0);\n tmpvar_5.xy = a_pos;\n vec4 tmpvar_6;\n tmpvar_6.w = 0.0;\n tmpvar_6.xy = (a_offset / 64.0);\n tmpvar_6.z = ((tmpvar_3 + float(\n (0.0 >= v_alpha)\n )) + (float(\n (u_angle >= a_data2.z)\n ) * (1.0 - \n float((u_angle >= a_data2.w))\n )));\n gl_Position = ((u_matrix * tmpvar_5) + (u_exmatrix * tmpvar_6));\n v_tex = ((a_data1.xy * 4.0) / u_texsize);\n}\n\n", From 7e94462747a0710654676763cbbb586b6be59482 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 23 May 2014 16:38:26 -0700 Subject: [PATCH 03/21] correct namespace usage --- src/util/transition.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/util/transition.cpp b/src/util/transition.cpp index d15e3ef66..37177a935 100644 --- a/src/util/transition.cpp +++ b/src/util/transition.cpp @@ -2,7 +2,7 @@ #include #include -using namespace llmr::util; +namespace llmr { namespace util { UnitBezier ease(0.25, 0.1, 0.25, 1); @@ -74,3 +74,5 @@ transition::state ease_transition>::update(llmr::time now) return running; } } + +}} From 9e7ee02fcdef3077bf3769fbed8748bef8b7ce1f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 23 May 2014 16:41:08 -0700 Subject: [PATCH 04/21] remove generated shaders from git - Closes #241 --- .gitignore | 2 ++ src/shader/shaders_gl.cpp | 50 ------------------------------------ src/shader/shaders_gles2.cpp | 50 ------------------------------------ 3 files changed, 2 insertions(+), 100 deletions(-) delete mode 100644 src/shader/shaders_gl.cpp delete mode 100644 src/shader/shaders_gles2.cpp diff --git a/.gitignore b/.gitignore index b8cbcf58e..a85ec0014 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ /include/llmr/shader/shaders.hpp /include/llmr/style/resources.hpp /src/style/resources.cpp +/src/shader/shaders_gl.cpp +/src/shader/shaders_gles2.cpp \ No newline at end of file diff --git a/src/shader/shaders_gl.cpp b/src/shader/shaders_gl.cpp deleted file mode 100644 index 8ed5eb3d3..000000000 --- a/src/shader/shaders_gl.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. -#include -#ifndef GL_ES_VERSION_2_0 -#include - -using namespace llmr; - -const shader_source llmr::shaders[SHADER_COUNT] = { - { - "#version 120\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = (gl_Position.xy + 1.0) / 2.0;\n}\n", - "#version 120\nuniform sampler2D u_image;\nuniform float u_opacity;\n\nvarying vec2 v_pos;\n\nvoid main() {\n vec4 color = texture2D(u_image, v_pos);\n gl_FragColor = color * u_opacity;\n}\n", - }, - { - "#version 120\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform float u_size;\n\nvoid main(void) {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n gl_PointSize = u_size;\n}\n", - "#version 120\nuniform vec4 u_color;\nuniform float u_blur;\n\nvoid main() {\n\tfloat dist = length(gl_PointCoord - 0.5);\n\tfloat t = smoothstep(0.5, 0.5 - u_blur, dist);\n\n gl_FragColor = u_color * t;\n}\n", - }, - { - "#version 120\nattribute vec2 a_pos;\nattribute vec2 a_tex;\n\nuniform mat4 u_matrix;\nuniform float u_size;\nuniform float u_ratio;\n\nvarying vec2 v_tex;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n gl_PointSize = u_size;\n v_tex = a_tex * u_ratio;\n}\n", - "#version 120\nuniform sampler2D u_image;\nuniform vec2 u_dimension;\nuniform vec4 u_color;\nuniform float u_size;\n\nvarying vec2 v_tex;\n\nvoid main() {\n vec2 pos = (v_tex + (gl_PointCoord - 0.5) * u_size) / u_dimension;\n gl_FragColor = u_color * texture2D(u_image, pos);\n}\n", - }, - { - "#version 120\n// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\nattribute vec2 a_pos;\nattribute vec2 a_extrude;\nattribute float a_linesofar;\n\n// posmatrix is for the vertex position, exmatrix is for rotating and projecting\n// the extrusion vector.\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\n\n// shared\nuniform float u_ratio;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\n\nvarying vec2 v_normal;\nvarying float v_linesofar;\n\nvoid main() {\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n vec4 dist = vec4(u_linewidth.s * a_extrude * scale, 0.0, 0.0);\n\n // Remove the texture normal bit of the position before scaling it with the\n // model/view matrix. Add the extrusion vector *after* the model/view matrix\n // because we're extruding the line in pixel space, regardless of the current\n // tile's zoom level.\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0.0, 1.0) + u_exmatrix * dist;\n v_linesofar = a_linesofar * u_ratio;\n}", - "#version 120\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\n\nuniform vec2 u_dasharray;\n\nvarying vec2 v_normal;\nvarying float v_linesofar;\n\nvoid main() {\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * u_linewidth.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist), 0.0, 1.0);\n\n // Calculate the antialiasing fade factor based on distance to the dash.\n // Only affects alpha when line is dashed\n float pos = mod(v_linesofar, u_dasharray.x + u_dasharray.y);\n alpha *= max(step(0.0, -u_dasharray.y), clamp(min(pos, u_dasharray.x - pos), 0.0, 1.0));\n\n gl_FragColor = u_color * alpha;\n}", - }, - { - "#version 120\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform vec2 u_world;\nuniform float u_size;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(floor(a_pos / 2.0), 0.0, 1.0);\n v_pos = (gl_Position.xy + 1.0) * u_world;\n gl_PointSize = u_size;\n}\n", - "#version 120\nuniform vec4 u_color;\nuniform vec2 u_linewidth;\n\nvarying vec2 v_pos;\n\nvoid main() {\n float dist = length(v_pos - gl_FragCoord.xy);\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist), 0.0, 1.0);\n gl_FragColor = u_color * alpha;\n}\n", - }, - { - "#version 120\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform vec2 u_world;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = (gl_Position.xy + 1.0) / 2.0 * u_world;\n}\n", - "#version 120\nuniform vec4 u_color;\n\nvarying vec2 v_pos;\n\nvoid main() {\n float dist = length(v_pos - gl_FragCoord.xy);\n float alpha = smoothstep(1.0, 0.0, dist);\n gl_FragColor = u_color * alpha;\n}\n", - }, - { - "#version 120\nuniform mat4 u_matrix;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos;\n\nvoid main() {\n v_pos = a_pos;\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n", - "#version 120\nuniform vec4 u_color;\n\nuniform vec2 u_offset;\nuniform vec2 u_pattern_size;\nuniform vec2 u_pattern_tl;\nuniform vec2 u_pattern_br;\nuniform float u_mix;\n\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos;\n\nvoid main() {\n\n vec2 imagecoord = mod((v_pos + u_offset) / u_pattern_size, 1.0);\n vec2 pos = mix(u_pattern_tl, u_pattern_br, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord2 = mod(imagecoord * 2.0, 1.0);\n vec2 pos2 = mix(u_pattern_tl, u_pattern_br, imagecoord2);\n vec4 color2 = texture2D(u_image, pos2);\n\n vec4 color = mix(color1, color2, u_mix);\n gl_FragColor = color + u_color * (1.0 - color.a);\n}\n", - }, - { - "#version 120\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n", - "#version 120\nuniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n", - }, - { - "#version 120\nuniform mat4 u_matrix;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = a_pos / 4096.0;\n}\n", - "#version 120\nuniform sampler2D u_image;\nuniform float u_opacity;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_FragColor = texture2D(u_image, v_pos) * u_opacity;\n}\n", - }, - { - "#version 120\nattribute vec2 a_pos;\nattribute vec2 a_offset;\nattribute vec4 a_data1;\nattribute vec4 a_data2;\n\n\n// posmatrix is for the vertex position, exmatrix is for rotating and projecting\n// the extrusion vector.\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\nuniform float u_angle;\nuniform float u_zoom;\nuniform float u_flip;\nuniform float u_fadedist;\nuniform float u_minfadezoom;\nuniform float u_maxfadezoom;\nuniform float u_fadezoom;\n\nuniform vec2 u_texsize;\n\nvarying vec2 v_tex;\nvarying float v_alpha;\n\nvoid main() {\n vec2 a_tex = a_data1.xy;\n float a_labelminzoom = a_data1[2];\n float a_angle = a_data1[3];\n vec2 a_zoom = a_data2.st;\n vec2 a_range = a_data2.pq;\n\n float rev = 0.0;\n\n // u_angle is angle of the map, -128..128 representing 0..2PI\n // a_angle is angle of the label, 0..256 representing 0..2PI, where 0 is horizontal text\n float rotated = mod(a_angle + u_angle, 256.0);\n // if the label rotates with the map, and if the rotated label is upside down, hide it\n if (u_flip > 0.0 && rotated >= 64.0 && rotated < 192.0) rev = 1.0;\n\n // If the label should be invisible, we move the vertex outside\n // of the view plane so that the triangle gets clipped. This makes it easier\n // for us to create degenerate triangle strips.\n // u_zoom is the current zoom level adjusted for the change in font size\n float z = 2.0 - step(a_zoom[0], u_zoom) - (1.0 - step(a_zoom[1], u_zoom)) + rev;\n\n // fade out labels\n float alpha = clamp((u_fadezoom - a_labelminzoom) / u_fadedist, 0.0, 1.0);\n\n if (u_fadedist >= 0.0) {\n v_alpha = alpha;\n } else {\n v_alpha = 1.0 - alpha;\n }\n if (u_maxfadezoom < a_labelminzoom) {\n v_alpha = 0.0;\n }\n if (u_minfadezoom >= a_labelminzoom) {\n v_alpha = 1.0;\n }\n\n // if label has been faded out, clip it\n z += step(v_alpha, 0.0);\n\n // all the angles are 0..256 representing 0..2PI\n // hide if (angle >= a_rangeend && angle < rangestart)\n z += step(a_range[0], u_angle) * (1.0 - step(a_range[1], u_angle));\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1) + u_exmatrix * vec4(a_offset / 64.0, z, 0);\n v_tex = a_tex * 4.0 / u_texsize;\n}\n", - "#version 120\nuniform sampler2D u_texture;\nuniform vec4 u_color;\nuniform float u_buffer;\nuniform float u_gamma;\n\nvarying vec2 v_tex;\nvarying float v_alpha;\n\nvoid main() {\n float dist = texture2D(u_texture, v_tex).a;\n float alpha = smoothstep(u_buffer - u_gamma, u_buffer + u_gamma, dist) * v_alpha;\n gl_FragColor = u_color * alpha;\n}\n", - } -}; -#endif diff --git a/src/shader/shaders_gles2.cpp b/src/shader/shaders_gles2.cpp deleted file mode 100644 index 87eb66486..000000000 --- a/src/shader/shaders_gles2.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. -#include -#ifdef GL_ES_VERSION_2_0 -#include - -using namespace llmr; - -const shader_source llmr::shaders[SHADER_COUNT] = { - { - "precision highp float;\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = (gl_Position.xy + 1.0) / 2.0;\n}\n", - "precision highp float;\nuniform sampler2D u_image;\nuniform float u_opacity;\n\nvarying vec2 v_pos;\n\nvoid main() {\n vec4 color = texture2D(u_image, v_pos);\n gl_FragColor = color * u_opacity;\n}\n", - }, - { - "precision highp float;\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform float u_size;\n\nvoid main(void) {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n gl_PointSize = u_size;\n}\n", - "precision highp float;\nuniform vec4 u_color;\nuniform float u_blur;\n\nvoid main() {\n\tfloat dist = length(gl_PointCoord - 0.5);\n\tfloat t = smoothstep(0.5, 0.5 - u_blur, dist);\n\n gl_FragColor = u_color * t;\n}\n", - }, - { - "precision highp float;\nattribute vec2 a_pos;\nattribute vec2 a_tex;\n\nuniform mat4 u_matrix;\nuniform float u_size;\nuniform float u_ratio;\n\nvarying vec2 v_tex;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n gl_PointSize = u_size;\n v_tex = a_tex * u_ratio;\n}\n", - "precision highp float;\nuniform sampler2D u_image;\nuniform vec2 u_dimension;\nuniform vec4 u_color;\nuniform float u_size;\n\nvarying vec2 v_tex;\n\nvoid main() {\n vec2 pos = (v_tex + (gl_PointCoord - 0.5) * u_size) / u_dimension;\n gl_FragColor = u_color * texture2D(u_image, pos);\n}\n", - }, - { - "precision highp float;\n// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\nattribute vec2 a_pos;\nattribute vec2 a_extrude;\nattribute float a_linesofar;\n\n// posmatrix is for the vertex position, exmatrix is for rotating and projecting\n// the extrusion vector.\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\n\n// shared\nuniform float u_ratio;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\n\nvarying vec2 v_normal;\nvarying float v_linesofar;\n\nvoid main() {\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n vec4 dist = vec4(u_linewidth.s * a_extrude * scale, 0.0, 0.0);\n\n // Remove the texture normal bit of the position before scaling it with the\n // model/view matrix. Add the extrusion vector *after* the model/view matrix\n // because we're extruding the line in pixel space, regardless of the current\n // tile's zoom level.\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0.0, 1.0) + u_exmatrix * dist;\n v_linesofar = a_linesofar * u_ratio;\n}", - "precision highp float;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\n\nuniform vec2 u_dasharray;\n\nvarying vec2 v_normal;\nvarying float v_linesofar;\n\nvoid main() {\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * u_linewidth.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist), 0.0, 1.0);\n\n // Calculate the antialiasing fade factor based on distance to the dash.\n // Only affects alpha when line is dashed\n float pos = mod(v_linesofar, u_dasharray.x + u_dasharray.y);\n alpha *= max(step(0.0, -u_dasharray.y), clamp(min(pos, u_dasharray.x - pos), 0.0, 1.0));\n\n gl_FragColor = u_color * alpha;\n}", - }, - { - "precision highp float;\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform vec2 u_world;\nuniform float u_size;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(floor(a_pos / 2.0), 0.0, 1.0);\n v_pos = (gl_Position.xy + 1.0) * u_world;\n gl_PointSize = u_size;\n}\n", - "precision highp float;\nuniform vec4 u_color;\nuniform vec2 u_linewidth;\n\nvarying vec2 v_pos;\n\nvoid main() {\n float dist = length(v_pos - gl_FragCoord.xy);\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist), 0.0, 1.0);\n gl_FragColor = u_color * alpha;\n}\n", - }, - { - "precision highp float;\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform vec2 u_world;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = (gl_Position.xy + 1.0) / 2.0 * u_world;\n}\n", - "precision highp float;\nuniform vec4 u_color;\n\nvarying vec2 v_pos;\n\nvoid main() {\n float dist = length(v_pos - gl_FragCoord.xy);\n float alpha = smoothstep(1.0, 0.0, dist);\n gl_FragColor = u_color * alpha;\n}\n", - }, - { - "precision highp float;\nuniform mat4 u_matrix;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos;\n\nvoid main() {\n v_pos = a_pos;\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n", - "precision highp float;\nuniform vec4 u_color;\n\nuniform vec2 u_offset;\nuniform vec2 u_pattern_size;\nuniform vec2 u_pattern_tl;\nuniform vec2 u_pattern_br;\nuniform float u_mix;\n\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos;\n\nvoid main() {\n\n vec2 imagecoord = mod((v_pos + u_offset) / u_pattern_size, 1.0);\n vec2 pos = mix(u_pattern_tl, u_pattern_br, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord2 = mod(imagecoord * 2.0, 1.0);\n vec2 pos2 = mix(u_pattern_tl, u_pattern_br, imagecoord2);\n vec4 color2 = texture2D(u_image, pos2);\n\n vec4 color = mix(color1, color2, u_mix);\n gl_FragColor = color + u_color * (1.0 - color.a);\n}\n", - }, - { - "precision highp float;\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n", - "precision highp float;\nuniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n", - }, - { - "precision highp float;\nuniform mat4 u_matrix;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = a_pos / 4096.0;\n}\n", - "precision highp float;\nuniform sampler2D u_image;\nuniform float u_opacity;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_FragColor = texture2D(u_image, v_pos) * u_opacity;\n}\n", - }, - { - "precision highp float;\nattribute vec2 a_pos;\nattribute vec2 a_offset;\nattribute vec4 a_data1;\nattribute vec4 a_data2;\n\n\n// posmatrix is for the vertex position, exmatrix is for rotating and projecting\n// the extrusion vector.\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\nuniform float u_angle;\nuniform float u_zoom;\nuniform float u_flip;\nuniform float u_fadedist;\nuniform float u_minfadezoom;\nuniform float u_maxfadezoom;\nuniform float u_fadezoom;\n\nuniform vec2 u_texsize;\n\nvarying vec2 v_tex;\nvarying float v_alpha;\n\nvoid main() {\n vec2 a_tex = a_data1.xy;\n float a_labelminzoom = a_data1[2];\n float a_angle = a_data1[3];\n vec2 a_zoom = a_data2.st;\n vec2 a_range = a_data2.pq;\n\n float rev = 0.0;\n\n // u_angle is angle of the map, -128..128 representing 0..2PI\n // a_angle is angle of the label, 0..256 representing 0..2PI, where 0 is horizontal text\n float rotated = mod(a_angle + u_angle, 256.0);\n // if the label rotates with the map, and if the rotated label is upside down, hide it\n if (u_flip > 0.0 && rotated >= 64.0 && rotated < 192.0) rev = 1.0;\n\n // If the label should be invisible, we move the vertex outside\n // of the view plane so that the triangle gets clipped. This makes it easier\n // for us to create degenerate triangle strips.\n // u_zoom is the current zoom level adjusted for the change in font size\n float z = 2.0 - step(a_zoom[0], u_zoom) - (1.0 - step(a_zoom[1], u_zoom)) + rev;\n\n // fade out labels\n float alpha = clamp((u_fadezoom - a_labelminzoom) / u_fadedist, 0.0, 1.0);\n\n if (u_fadedist >= 0.0) {\n v_alpha = alpha;\n } else {\n v_alpha = 1.0 - alpha;\n }\n if (u_maxfadezoom < a_labelminzoom) {\n v_alpha = 0.0;\n }\n if (u_minfadezoom >= a_labelminzoom) {\n v_alpha = 1.0;\n }\n\n // if label has been faded out, clip it\n z += step(v_alpha, 0.0);\n\n // all the angles are 0..256 representing 0..2PI\n // hide if (angle >= a_rangeend && angle < rangestart)\n z += step(a_range[0], u_angle) * (1.0 - step(a_range[1], u_angle));\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1) + u_exmatrix * vec4(a_offset / 64.0, z, 0);\n v_tex = a_tex * 4.0 / u_texsize;\n}\n", - "precision highp float;\nuniform sampler2D u_texture;\nuniform vec4 u_color;\nuniform float u_buffer;\nuniform float u_gamma;\n\nvarying vec2 v_tex;\nvarying float v_alpha;\n\nvoid main() {\n float dist = texture2D(u_texture, v_tex).a;\n float alpha = smoothstep(u_buffer - u_gamma, u_buffer + u_gamma, dist) * v_alpha;\n gl_FragColor = u_color * alpha;\n}\n", - } -}; -#endif From 7f592ac2e715fc7c0d6e4c206144f03e4af18947 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 23 May 2014 17:14:19 -0700 Subject: [PATCH 05/21] Address #151 at the same time --- bin/build-shaders.js | 10 +++-- bin/build-style.js | 14 ++++--- bin/mkdirp.js | 97 ++++++++++++++++++++++++++++++++++++++++++++ llmr.gyp | 23 +++++++---- 4 files changed, 127 insertions(+), 17 deletions(-) create mode 100644 bin/mkdirp.js diff --git a/bin/build-shaders.js b/bin/build-shaders.js index 445006633..b5072c370 100755 --- a/bin/build-shaders.js +++ b/bin/build-shaders.js @@ -3,7 +3,7 @@ var fs = require('fs'); var path = require('path'); -var lazy_update = require('./lazy-update'); +var mkdirp = require('./mkdirp'); try { var glsl = require('glsl-optimizer'); } catch(err) {} @@ -117,9 +117,13 @@ module.exports = function(shader_type, prefix, suffix) { code += '\n};\n'; code += suffix + '\n'; + var file_path = path.join(process.argv[2], 'include/llmr/shader/shaders.hpp'); + mkdirp.sync(path.dirname(file_path)); + fs.writeFileSync(file_path, header); + var header_path = path.join(process.argv[2], 'src/shader/shaders_' + shader_type + '.cpp'); + mkdirp.sync(path.dirname(header_path)); + fs.writeFileSync(header_path, code); - lazy_update('include/llmr/shader/shaders.hpp', header); - lazy_update('src/shader/shaders_' + shader_type + '.cpp', code); }; module.exports('gl', '#ifndef GL_ES_VERSION_2_0', '#endif'); diff --git a/bin/build-style.js b/bin/build-style.js index bd86d5bda..932287b89 100755 --- a/bin/build-style.js +++ b/bin/build-style.js @@ -2,9 +2,8 @@ 'use strict'; var path = require('path'); - -var lazy_update = require('./lazy-update'); - +var fs = require('fs'); +var mkdirp = require('./mkdirp'); var name = 'style'; var data = JSON.stringify(require(path.join(process.cwd(), process.argv[2]))); @@ -26,7 +25,9 @@ header += '}\n'; header += '\n'; header += '#endif\n'; -lazy_update('include/llmr/style/resources.hpp', header); +var header_path = path.join(process.argv[3], 'include/llmr/style/resources.hpp'); +mkdirp.sync(path.dirname(header_path)); +fs.writeFileSync(header_path, header); var code = '// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.\n'; code += '#include \n'; @@ -36,5 +37,6 @@ code += '\n'; code += 'const unsigned char resources::' + name + '[] = R"JSON(' + data + ')JSON";\n'; code += 'const unsigned long resources::' + name + '_size = sizeof(resources::' + name + ');\n'; -lazy_update('src/style/resources.cpp', code); - +var file_path = path.join(process.argv[3], 'src/style/resources.cpp'); +mkdirp.sync(path.dirname(file_path)); +fs.writeFileSync(file_path, code); diff --git a/bin/mkdirp.js b/bin/mkdirp.js new file mode 100644 index 000000000..a1742b206 --- /dev/null +++ b/bin/mkdirp.js @@ -0,0 +1,97 @@ +var path = require('path'); +var fs = require('fs'); + +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + +function mkdirP (p, opts, f, made) { + if (typeof opts === 'function') { + f = opts; + opts = {}; + } + else if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = 0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + p = path.resolve(p); + + xfs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), opts, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, opts, cb, made); + }); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + xfs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); +} + +mkdirP.sync = function sync (p, opts, made) { + if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = 0777 & (~process.umask()); + } + if (!made) made = null; + + p = path.resolve(p); + + try { + xfs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), opts, made); + sync(p, opts, made); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = xfs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } + + return made; +}; diff --git a/llmr.gyp b/llmr.gyp index a76ef225c..a32a598f5 100644 --- a/llmr.gyp +++ b/llmr.gyp @@ -19,14 +19,17 @@ 'src/shader/shaders_gl.cpp', 'src/shader/shaders_gles2.cpp', ], - 'action': ['<@(node)', 'bin/build-shaders.js'], + 'action': ['<@(node)', 'bin/build-shaders.js', '<(SHARED_INTERMEDIATE_DIR)'], } ], 'direct_dependent_settings': { 'sources': [ - 'include/llmr/shader/shaders.hpp', - 'src/shader/shaders_gl.cpp', - 'src/shader/shaders_gles2.cpp' + '<(SHARED_INTERMEDIATE_DIR)/include/llmr/shader/shaders.hpp', + '<(SHARED_INTERMEDIATE_DIR)/src/shader/shaders_gl.cpp', + '<(SHARED_INTERMEDIATE_DIR)/src/shader/shaders_gles2.cpp' + ], + 'include_dirs':[ + '<(SHARED_INTERMEDIATE_DIR)/include/', ] } }, @@ -41,15 +44,19 @@ 'bin/style.js', ], 'outputs': [ - 'include/llmr/style/resources.hpp', - 'src/style/resources.cpp' + '<(SHARED_INTERMEDIATE_DIR)/include/llmr/style/resources.hpp', + '<(SHARED_INTERMEDIATE_DIR)/src/style/resources.cpp' ], - 'action': ['<@(node)', 'bin/build-style.js', '<@(_inputs)'] + 'action': ['<@(node)', 'bin/build-style.js', '<@(_inputs)', '<(SHARED_INTERMEDIATE_DIR)'] } ], 'direct_dependent_settings': { 'sources': [ - 'src/style/resources.cpp' + '<(SHARED_INTERMEDIATE_DIR)/include/llmr/style/resources.hpp', + '<(SHARED_INTERMEDIATE_DIR)/src/style/resources.cpp' + ], + 'include_dirs':[ + '<(SHARED_INTERMEDIATE_DIR)/include/', ] } }, From 991eeaf24e6c7ff59ce8121d6f7df34458961283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 10:59:00 +0200 Subject: [PATCH 06/21] fix blur fringes --- src/renderer/painter_fill.cpp | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 18f84ad58..6f28b6c0c 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -155,8 +155,9 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons if (properties.prerendered) { if (pass == Translucent) { // Buffer value around the 0..4096 extent that will be drawn into the 256x256 pixel - // texture. We later scale - const int buffer = 256; + // 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 + const int buffer = 128; if (!bucket.prerendered) { bucket.prerendered = std::make_unique(); @@ -188,6 +189,11 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons + mat4 regularMatrix; + matrix::ortho(regularMatrix, 0, 4096, -4096, 0, 0, 1); + matrix::translate(regularMatrix, regularMatrix, 0, -4096, 0); + + // BLUR GLuint original_texture = bucket.prerendered->getTexture(); @@ -204,16 +210,16 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons useProgram(gaussianShader->program); - gaussianShader->setMatrix(vtxMatrix); + gaussianShader->setMatrix(regularMatrix); gaussianShader->setImage(0); glActiveTexture(GL_TEXTURE0); - const GLenum discards[] = { GL_COLOR_ATTACHMENT0 }; - for (int i = 0; i < 1 ; i++) { + for (int i = 0; i < 1; i++) { // Render horizontal glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, secondary_texture, 0); #if GL_EXT_discard_framebuffer + const GLenum discards[] = { GL_COLOR_ATTACHMENT0 }; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); #endif glClear(GL_COLOR_BUFFER_BIT); @@ -241,22 +247,6 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons glDeleteTextures(1, &secondary_texture); - - - - // RENDER DEBUG FRAME - useProgram(plainShader->program); - - plainShader->setMatrix(vtxMatrix); - - // draw tile outline - tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0)); - plainShader->setColor(0, 1, 1, 1); - lineWidth(2); - glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index()); - - - // RESET STATE @@ -278,7 +268,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons glActiveTexture(GL_TEXTURE0); rasterShader->setImage(0); - rasterShader->setBuffer(0); + rasterShader->setBuffer(buffer); bucket.prerendered->bindTexture(); coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); From b6561dd342aac571e3a42bf057e1cbdd8d062b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 10:59:15 +0200 Subject: [PATCH 07/21] increase http timeout --- common/foundation_request.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/foundation_request.mm b/common/foundation_request.mm index d18834946..ca32706ba 100644 --- a/common/foundation_request.mm +++ b/common/foundation_request.mm @@ -24,7 +24,7 @@ std::atomic active_tasks; void request_initialize_cb() { NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; - sessionConfig.timeoutIntervalForResource = 6; + sessionConfig.timeoutIntervalForResource = 30; sessionConfig.HTTPMaximumConnectionsPerHost = 8; sessionConfig.requestCachePolicy = NSURLRequestUseProtocolCachePolicy; From a7c3b8b6f589cbe78744ac5eb4e1c1b2214c0c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 11:58:37 +0200 Subject: [PATCH 08/21] derive properties from a generic class --- include/llmr/style/properties.hpp | 96 ++++++++++--------------------- 1 file changed, 29 insertions(+), 67 deletions(-) diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index 616936ea8..f96c2cec9 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -84,16 +84,26 @@ struct FunctionProperty { template inline T evaluate(float z) const { return function(z, values); } }; -struct IconClass { +struct GenericClass { boost::optional enabled; boost::optional> translate; boost::optional translate_transition; boost::optional translateAnchor; + boost::optional opacity; + boost::optional opacity_transition; +}; + +struct GenericProperties { + bool enabled = true; + std::array translate = {{ 0, 0 }}; + TranslateAnchor translateAnchor = TranslateAnchor::Map; + float opacity = 1.0; +}; + +struct IconClass : public GenericClass { boost::optional size; boost::optional color; boost::optional color_transition; - boost::optional opacity; - boost::optional opacity_transition; boost::optional image; boost::optional radius; boost::optional radius_transition; @@ -101,23 +111,15 @@ struct IconClass { boost::optional blur_transition; }; -struct IconProperties { - bool enabled = true; - std::array translate = {{ 0, 0 }}; - TranslateAnchor translateAnchor = TranslateAnchor::Map; +struct IconProperties : public GenericProperties { float size = 0; Color color = {{ 1, 1, 1, 1 }}; - float opacity = 1.0; std::string image; float radius = 0; float blur = 0; }; -struct LineClass { - boost::optional enabled; - boost::optional> translate; - boost::optional translate_transition; - boost::optional translateAnchor; +struct LineClass : public GenericClass { boost::optional width; boost::optional width_transition; boost::optional offset; @@ -126,58 +128,40 @@ struct LineClass { boost::optional color_transition; boost::optional> dash_array; boost::optional dash_array_transition; - boost::optional opacity; - boost::optional opacity_transition; }; -struct LineProperties { - bool enabled = true; - std::array translate = {{ 0, 0 }}; - TranslateAnchor translateAnchor = TranslateAnchor::Map; +struct LineProperties : public GenericProperties { float width = 0; float offset = 0; Color color = {{ 0, 0, 0, 1 }}; std::array dash_array = {{ 1, -1 }}; - float opacity = 1.0; }; -struct FillClass { - boost::optional enabled; - boost::optional> translate; - boost::optional translate_transition; - boost::optional translateAnchor; +struct FillClass : public GenericClass { boost::optional winding; boost::optional antialias; boost::optional fill_color; boost::optional fill_color_transition; boost::optional stroke_color; boost::optional stroke_color_transition; - boost::optional opacity; - boost::optional opacity_transition; boost::optional image; boost::optional prerendered; boost::optional blur; }; -struct FillProperties { - bool enabled = true; - std::array translate = {{ 0, 0 }}; - TranslateAnchor translateAnchor = TranslateAnchor::Map; +struct FillProperties : public GenericProperties { Winding winding = Winding::NonZero; bool antialias = true; Color fill_color = {{ 0, 0, 0, 1 }}; Color stroke_color = {{ 0, 0, 0, 1 }}; - float opacity = 1.0; bool prerendered = false; + float prerenderBuffer = 1.0f / 32.0f; + uint16_t prerenderSize = 256; float blur = 0.0f; std::string image; }; -struct TextClass { - boost::optional enabled; - boost::optional> translate; - boost::optional translate_transition; - boost::optional translateAnchor; +struct TextClass : public GenericClass { boost::optional color; boost::optional color_transition; boost::optional halo; @@ -189,14 +173,9 @@ struct TextClass { boost::optional size; boost::optional rotate; boost::optional always_visible; - boost::optional opacity; - boost::optional opacity_transition; }; -struct TextProperties { - bool enabled = true; - std::array translate = {{ 0, 0 }}; - TranslateAnchor translateAnchor = TranslateAnchor::Map; +struct TextProperties : public GenericProperties { Color color = {{ 0, 0, 0, 1 }}; Color halo = {{ 1, 1, 1, 0.75 }}; float halo_radius = 0.25f; @@ -204,45 +183,28 @@ struct TextProperties { float size = 12.0f; float rotate = 0.0f; bool always_visible = false; - float opacity = 1.0; }; -struct BackgroundClass { +struct BackgroundClass : public GenericClass { boost::optional color; boost::optional color_transition; - boost::optional opacity; - boost::optional opacity_transition; }; -struct BackgroundProperties { +struct BackgroundProperties : public GenericProperties { Color color = {{ 1, 1, 1, 1 }}; - float opacity = 1.0; }; -struct RasterClass { - boost::optional enabled; - boost::optional> translate; - boost::optional translate_transition; - boost::optional opacity; - boost::optional opacity_transition; +struct RasterClass : public GenericClass { }; -struct RasterProperties { - bool enabled = true; - std::array translate = {{ 0, 0 }}; - float opacity = 1.0; +struct RasterProperties : public GenericProperties { }; -struct CompositeClass { - boost::optional enabled; - boost::optional opacity; - boost::optional opacity_transition; +struct CompositeClass : public GenericClass { }; -struct CompositeProperties { - inline CompositeProperties() {} - bool enabled = true; - float opacity = 1.0; +struct CompositeProperties : public GenericProperties { + inline CompositeProperties() : GenericProperties() {} }; From e506d6bcdddc2cda548e7e1dd064519b0856d534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 12:30:27 +0200 Subject: [PATCH 09/21] generalize stylesheet parse function --- include/llmr/style/properties.hpp | 13 +-- include/llmr/style/style_parser.hpp | 1 + include/llmr/style/value.hpp | 12 +++ src/renderer/painter_fill.cpp | 2 +- src/style/style.cpp | 8 +- src/style/style_parser.cpp | 128 ++++++++-------------------- 6 files changed, 62 insertions(+), 102 deletions(-) diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index f96c2cec9..aeb3e32c9 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -91,6 +91,10 @@ struct GenericClass { boost::optional translateAnchor; boost::optional opacity; boost::optional opacity_transition; + boost::optional prerender; + boost::optional prerenderBuffer; + boost::optional prerenderSize; + boost::optional prerenderBlur; }; struct GenericProperties { @@ -98,6 +102,10 @@ struct GenericProperties { std::array translate = {{ 0, 0 }}; TranslateAnchor translateAnchor = TranslateAnchor::Map; float opacity = 1.0; + bool prerender = false; + float prerenderBuffer = 1.0f / 32.0f; + uint16_t prerenderSize = 256; + bool prerenderBlur = false; }; struct IconClass : public GenericClass { @@ -145,8 +153,6 @@ struct FillClass : public GenericClass { boost::optional stroke_color; boost::optional stroke_color_transition; boost::optional image; - boost::optional prerendered; - boost::optional blur; }; struct FillProperties : public GenericProperties { @@ -154,9 +160,6 @@ struct FillProperties : public GenericProperties { bool antialias = true; Color fill_color = {{ 0, 0, 0, 1 }}; Color stroke_color = {{ 0, 0, 0, 1 }}; - bool prerendered = false; - float prerenderBuffer = 1.0f / 32.0f; - uint16_t prerenderSize = 256; float blur = 0.0f; std::string image; }; diff --git a/include/llmr/style/style_parser.hpp b/include/llmr/style/style_parser.hpp index 6668048ff..109b94f1f 100644 --- a/include/llmr/style/style_parser.hpp +++ b/include/llmr/style/style_parser.hpp @@ -30,6 +30,7 @@ private: const std::map &buckets, const std::map &layerBuckets); + void parseGenericClass(GenericClass &klass, JSVal value); FillClass parseFillClass(JSVal value); LineClass parseLineClass(JSVal value); IconClass parseIconClass(JSVal value); diff --git a/include/llmr/style/value.hpp b/include/llmr/style/value.hpp index 0dc53248b..f29590363 100644 --- a/include/llmr/style/value.hpp +++ b/include/llmr/style/value.hpp @@ -85,6 +85,18 @@ struct relaxed_equal { Value const &lhs; }; } + + +template +T toNumber(const Value &value) { + if (value.is()) return util::string_to_number()(value.get()); + else if (value.is()) return value.get(); + else if (value.is()) return value.get(); + else if (value.is()) return value.get(); + else if (value.is()) return value.get(); + else return 0; +} + } #endif diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 6f28b6c0c..76f510c7d 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -152,7 +152,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons if (!properties.enabled) return; - if (properties.prerendered) { + 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 diff --git a/src/style/style.cpp b/src/style/style.cpp index fce70eade..e3adc3c89 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -115,12 +115,12 @@ void Style::cascade(float z) { fill.image = layer.image.get(); } - if (layer.prerendered) { - fill.prerendered = layer.prerendered.get().evaluate(z); + if (layer.prerender) { + fill.prerender = layer.prerender.get(); } - if (layer.blur) { - fill.blur = layer.blur.get().evaluate(z); + if (layer.prerenderBlur) { + fill.prerenderBlur = layer.prerenderBlur.get(); } } diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 52ef85f1d..b6e73147d 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -500,10 +500,8 @@ PropertyTransition StyleParser::parseTransition(JSVal value, std::string propert return transition; } -FillClass StyleParser::parseFillClass(JSVal value) { - FillClass klass; - - if (value.HasMember("enabled")) { +void StyleParser::parseGenericClass(GenericClass &klass, JSVal value) { + if (value.HasMember("enabled")) { klass.enabled = parseFunction(value["enabled"]); } @@ -517,6 +515,33 @@ FillClass StyleParser::parseFillClass(JSVal value) { klass.translateAnchor = parseTranslateAnchor(value["translate-anchor"]); } + if (value.HasMember("opacity")) { + klass.opacity = parseFunction(value["opacity"]); + klass.opacity_transition = parseTransition(value, "opacity"); + } + + if (value.HasMember("prerender")) { + klass.prerender = parseBoolean(value["prerender"]); + } + + if (value.HasMember("prerender-buffer")) { + klass.prerenderBuffer = toNumber(parseValue(value["prerender-buffer"])); + } + + if (value.HasMember("prerender-size")) { + klass.prerenderBuffer = toNumber(parseValue(value["prerender-size"])); + } + + if (value.HasMember("prerender-blur")) { + klass.prerenderBlur = parseBoolean(value["prerender-blur"]); + } +} + +FillClass StyleParser::parseFillClass(JSVal value) { + FillClass klass; + + parseGenericClass(klass, value); + if (value.HasMember("winding")) { throw std::runtime_error("winding in stylesheets not yet supported"); } @@ -537,42 +562,17 @@ FillClass StyleParser::parseFillClass(JSVal value) { klass.antialias = parseBoolean(value["antialias"]); } - if (value.HasMember("prerendered")) { - klass.prerendered = parseBoolean(value["prerendered"]); - } - - if (value.HasMember("blur")) { - klass.blur = parseFunction(value["blur"]); - } - if (value.HasMember("image")) { klass.image = parseString(value["image"]); } - if (value.HasMember("opacity")) { - klass.opacity = parseFunction(value["opacity"]); - klass.opacity_transition = parseTransition(value, "opacity"); - } - return klass; } LineClass StyleParser::parseLineClass(JSVal value) { LineClass klass; - if (value.HasMember("enabled")) { - klass.enabled = parseFunction(value["enabled"]); - } - - if (value.HasMember("translate")) { - std::vector values = parseArray(value["translate"], 2); - klass.translate = std::array {{ values[0], values[1] }}; - klass.translate_transition = parseTransition(value, "translate"); - } - - if (value.HasMember("translate-anchor")) { - klass.translateAnchor = parseTranslateAnchor(value["translate-anchor"]); - } + parseGenericClass(klass, value); if (value.HasMember("color")) { klass.color = parseColor(value["color"]); @@ -584,11 +584,6 @@ LineClass StyleParser::parseLineClass(JSVal value) { klass.width_transition = parseTransition(value, "width"); } - if (value.HasMember("opacity")) { - klass.opacity = parseFunction(value["opacity"]); - klass.opacity_transition = parseTransition(value, "opacity"); - } - if (value.HasMember("dasharray")) { std::vector values = parseArray(value["dasharray"], 2); klass.dash_array = std::array {{ values[0], values[1] }}; @@ -601,30 +596,13 @@ LineClass StyleParser::parseLineClass(JSVal value) { IconClass StyleParser::parseIconClass(JSVal value) { IconClass klass; - if (value.HasMember("enabled")) { - klass.enabled = parseFunction(value["enabled"]); - } - - if (value.HasMember("translate")) { - std::vector values = parseArray(value["translate"], 2); - klass.translate = std::array {{ values[0], values[1] }}; - klass.translate_transition = parseTransition(value, "translate"); - } - - if (value.HasMember("translate-anchor")) { - klass.translateAnchor = parseTranslateAnchor(value["translate-anchor"]); - } + parseGenericClass(klass, value); if (value.HasMember("color")) { klass.color = parseColor(value["color"]); klass.color_transition = parseTransition(value, "color"); } - if (value.HasMember("opacity")) { - klass.opacity = parseFunction(value["opacity"]); - klass.opacity_transition = parseTransition(value, "opacity"); - } - if (value.HasMember("image")) { klass.image = parseString(value["image"]); } @@ -649,19 +627,7 @@ IconClass StyleParser::parseIconClass(JSVal value) { TextClass StyleParser::parseTextClass(JSVal value) { TextClass klass; - if (value.HasMember("enabled")) { - klass.enabled = parseFunction(value["enabled"]); - } - - if (value.HasMember("translate")) { - std::vector values = parseArray(value["translate"], 2); - klass.translate = std::array {{ values[0], values[1] }}; - klass.translate_transition = parseTransition(value, "translate"); - } - - if (value.HasMember("translate-anchor")) { - klass.translateAnchor = parseTranslateAnchor(value["translate-anchor"]); - } + parseGenericClass(klass, value); if (value.HasMember("color")) { klass.color = parseColor(value["color"]); @@ -695,25 +661,13 @@ TextClass StyleParser::parseTextClass(JSVal value) { klass.always_visible = parseFunction(value["alwaysVisible"]); } - if (value.HasMember("opacity")) { - klass.opacity = parseFunction(value["opacity"]); - klass.opacity_transition = parseTransition(value, "opacity"); - } - return klass; } RasterClass StyleParser::parseRasterClass(JSVal value) { RasterClass klass; - if (value.HasMember("enabled")) { - klass.enabled = parseFunction(value["enabled"]); - } - - if (value.HasMember("opacity")) { - klass.opacity = parseFunction(value["opacity"]); - klass.opacity_transition = parseTransition(value, "opacity"); - } + parseGenericClass(klass, value); return klass; } @@ -721,14 +675,7 @@ RasterClass StyleParser::parseRasterClass(JSVal value) { CompositeClass StyleParser::parseCompositeClass(JSVal value) { CompositeClass klass; - if (value.HasMember("enabled")) { - klass.enabled = parseFunction(value["enabled"]); - } - - if (value.HasMember("opacity")) { - klass.opacity = parseFunction(value["opacity"]); - klass.opacity_transition = parseTransition(value, "opacity"); - } + parseGenericClass(klass, value); return klass; } @@ -736,16 +683,13 @@ CompositeClass StyleParser::parseCompositeClass(JSVal value) { BackgroundClass StyleParser::parseBackgroundClass(JSVal value) { BackgroundClass klass; + parseGenericClass(klass, value); + if (value.HasMember("color")) { klass.color = parseColor(value["color"]); klass.color_transition = parseTransition(value, "color"); } - if (value.HasMember("opacity")) { - klass.opacity = parseFunction(value["opacity"]); - klass.opacity_transition = parseTransition(value, "opacity"); - } - return klass; } From 4b8e3faa707e764d4d971b7efcca4c2414bb27df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 12:43:49 +0200 Subject: [PATCH 10/21] consolidate stylesheet cascading --- include/llmr/style/properties.hpp | 4 +- include/llmr/style/style.hpp | 2 + src/style/style.cpp | 185 +++++++++--------------------- src/style/style_parser.cpp | 2 +- 4 files changed, 57 insertions(+), 136 deletions(-) diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index aeb3e32c9..d44579b48 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -94,7 +94,7 @@ struct GenericClass { boost::optional prerender; boost::optional prerenderBuffer; boost::optional prerenderSize; - boost::optional prerenderBlur; + boost::optional prerenderBlur; }; struct GenericProperties { @@ -105,7 +105,7 @@ struct GenericProperties { bool prerender = false; float prerenderBuffer = 1.0f / 32.0f; uint16_t prerenderSize = 256; - bool prerenderBlur = false; + uint16_t prerenderBlur = 0; }; struct IconClass : public GenericClass { diff --git a/include/llmr/style/style.hpp b/include/llmr/style/style.hpp index 256ff4d6b..4aa4b748b 100644 --- a/include/llmr/style/style.hpp +++ b/include/llmr/style/style.hpp @@ -68,6 +68,8 @@ private: uint64_t transitionDuration(std::string layer_name, TransitionablePropertyKey key); uint64_t transitionDelay(std::string layer_name, TransitionablePropertyKey key); + void cascadeProperties(GenericProperties &properties, const GenericClass& klass, const std::string& layer_name, const std::string& class_name, float z); + private: // Last applied settings. struct { diff --git a/src/style/style.cpp b/src/style/style.cpp index e3adc3c89..7f9b6ba78 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -25,6 +25,50 @@ void Style::reset() { properties_to_transition.clear(); } +void Style::cascadeProperties(GenericProperties &properties, const GenericClass& klass, const std::string& layer_name, const std::string& class_name, float z) { + if (klass.enabled) { + properties.enabled = klass.enabled.get().evaluate(z); + } + + if (klass.translate) { + properties.translate = {{ klass.translate.get()[0].evaluate(z), + klass.translate.get()[1].evaluate(z) }}; + computed.effective_classes[layer_name][TransitionablePropertyKey::Translate] = class_name; + if (klass.translate_transition && klass.translate_transition.get().duration) { + properties_to_transition[layer_name][TransitionablePropertyKey::Translate] = klass.translate_transition.get(); + } + } + + if (klass.translateAnchor) { + properties.translateAnchor = klass.translateAnchor.get(); + } + + if (klass.opacity) { + properties.opacity = klass.opacity.get().evaluate(z); + computed.effective_classes[layer_name][TransitionablePropertyKey::Opacity] = class_name; + if (klass.opacity_transition && klass.opacity_transition.get().duration) { + properties_to_transition[layer_name][TransitionablePropertyKey::Opacity] = klass.opacity_transition.get(); + } + } + + 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(); + } +} + + void Style::cascade(float z) { uv::writelock lock(mtx); @@ -62,22 +106,7 @@ void Style::cascade(float z) { llmr::FillProperties& fill = computed.fills[layer_name]; - if (layer.enabled) { - fill.enabled = layer.enabled.get().evaluate(z); - } - - if (layer.translate) { - fill.translate = {{ layer.translate.get()[0].evaluate(z), - layer.translate.get()[1].evaluate(z) }}; - computed.effective_classes[layer_name][TransitionablePropertyKey::Translate] = class_name; - if (layer.translate_transition && layer.translate_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Translate] = layer.translate_transition.get(); - } - } - - if (layer.translateAnchor) { - fill.translateAnchor = layer.translateAnchor.get(); - } + cascadeProperties(fill, layer, layer_name, class_name, z); if (layer.winding) { fill.winding = layer.winding.get(); @@ -103,25 +132,9 @@ void Style::cascade(float z) { } } - if (layer.opacity) { - fill.opacity = layer.opacity.get().evaluate(z); - computed.effective_classes[layer_name][TransitionablePropertyKey::Opacity] = class_name; - if (layer.opacity_transition && layer.opacity_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Opacity] = layer.opacity_transition.get(); - } - } - if (layer.image) { fill.image = layer.image.get(); } - - if (layer.prerender) { - fill.prerender = layer.prerender.get(); - } - - if (layer.prerenderBlur) { - fill.prerenderBlur = layer.prerenderBlur.get(); - } } // Cascade line classes. @@ -131,22 +144,7 @@ void Style::cascade(float z) { llmr::LineProperties& stroke = computed.lines[layer_name]; - if (layer.enabled) { - stroke.enabled = layer.enabled.get().evaluate(z); - } - - if (layer.translate) { - stroke.translate = {{ layer.translate.get()[0].evaluate(z), - layer.translate.get()[1].evaluate(z) }}; - computed.effective_classes[layer_name][TransitionablePropertyKey::Translate] = class_name; - if (layer.translate_transition && layer.translate_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Translate] = layer.translate_transition.get(); - } - } - - if (layer.translateAnchor) { - stroke.translateAnchor = layer.translateAnchor.get(); - } + cascadeProperties(stroke, layer, layer_name, class_name, z); if (layer.width) { stroke.width = layer.width.get().evaluate(z); @@ -181,14 +179,6 @@ void Style::cascade(float z) { properties_to_transition[layer_name][TransitionablePropertyKey::DashArray] = layer.dash_array_transition.get(); } } - - if (layer.opacity) { - stroke.opacity = layer.opacity.get().evaluate(z); - computed.effective_classes[layer_name][TransitionablePropertyKey::Opacity] = class_name; - if (layer.opacity_transition && layer.opacity_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Opacity] = layer.opacity_transition.get(); - } - } } // Cascade icon classes. @@ -198,22 +188,7 @@ void Style::cascade(float z) { llmr::IconProperties& icon = computed.icons[layer_name]; - if (layer.enabled) { - icon.enabled = layer.enabled.get().evaluate(z); - } - - if (layer.translate) { - icon.translate = {{ layer.translate.get()[0].evaluate(z), - layer.translate.get()[1].evaluate(z) }}; - computed.effective_classes[layer_name][TransitionablePropertyKey::Translate] = class_name; - if (layer.translate_transition && layer.translate_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Translate] = layer.translate_transition.get(); - } - } - - if (layer.translateAnchor) { - icon.translateAnchor = layer.translateAnchor.get(); - } + cascadeProperties(icon, layer, layer_name, class_name, z); if (layer.color) { icon.color = layer.color.get(); @@ -227,14 +202,6 @@ void Style::cascade(float z) { icon.size = layer.size.get().evaluate(z); } - if (layer.opacity) { - icon.opacity = layer.opacity.get().evaluate(z); - computed.effective_classes[layer_name][TransitionablePropertyKey::Opacity] = class_name; - if (layer.opacity_transition && layer.opacity_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Opacity] = layer.opacity_transition.get(); - } - } - if (layer.image) { icon.image = layer.image.get(); } @@ -263,22 +230,7 @@ void Style::cascade(float z) { llmr::TextProperties& text = computed.texts[layer_name]; - if (layer.enabled) { - text.enabled = layer.enabled.get().evaluate(z); - } - - if (layer.translate) { - text.translate = {{ layer.translate.get()[0].evaluate(z), - layer.translate.get()[1].evaluate(z) }}; - computed.effective_classes[layer_name][TransitionablePropertyKey::Translate] = class_name; - if (layer.translate_transition && layer.translate_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Translate] = layer.translate_transition.get(); - } - } - - if (layer.translateAnchor) { - text.translateAnchor = layer.translateAnchor.get(); - } + cascadeProperties(text, layer, layer_name, class_name, z); if (layer.color) { text.color = layer.color.get(); @@ -323,14 +275,6 @@ void Style::cascade(float z) { if (layer.always_visible) { text.always_visible = layer.always_visible.get().evaluate(z); } - - if (layer.opacity) { - text.opacity = layer.opacity.get().evaluate(z); - computed.effective_classes[layer_name][TransitionablePropertyKey::Opacity] = class_name; - if (layer.opacity_transition && layer.opacity_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Opacity] = layer.opacity_transition.get(); - } - } } // Cascade raster classes. @@ -340,17 +284,7 @@ void Style::cascade(float z) { llmr::RasterProperties& raster = computed.rasters[layer_name]; - if (layer.enabled) { - raster.enabled = layer.enabled.get().evaluate(z); - } - - if (layer.opacity) { - raster.opacity = layer.opacity.get().evaluate(z); - computed.effective_classes[layer_name][TransitionablePropertyKey::Opacity] = class_name; - if (layer.opacity_transition && layer.opacity_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Opacity] = layer.opacity_transition.get(); - } - } + cascadeProperties(raster, layer, layer_name, class_name, z); } // Cascade composite classes. @@ -360,21 +294,13 @@ void Style::cascade(float z) { llmr::CompositeProperties& composite = computed.composites[layer_name]; - if (layer.enabled) { - composite.enabled = layer.enabled.get().evaluate(z); - } - - if (layer.opacity) { - composite.opacity = layer.opacity.get().evaluate(z); - computed.effective_classes[layer_name][TransitionablePropertyKey::Opacity] = class_name; - if (layer.opacity_transition && layer.opacity_transition.get().duration) { - properties_to_transition[layer_name][TransitionablePropertyKey::Opacity] = layer.opacity_transition.get(); - } - } + cascadeProperties(composite, layer, layer_name, class_name, z); } // Cascade background. { + cascadeProperties(computed.background, sheetClass.background, "background", class_name, z); + if (sheetClass.background.color) { computed.background.color = sheetClass.background.color.get(); computed.effective_classes["background"][TransitionablePropertyKey::Color] = class_name; @@ -382,13 +308,6 @@ void Style::cascade(float z) { properties_to_transition["background"][TransitionablePropertyKey::Color] = sheetClass.background.color_transition.get(); } } - if (sheetClass.background.opacity) { - computed.background.opacity = sheetClass.background.opacity.get().evaluate(z); - computed.effective_classes["background"][TransitionablePropertyKey::Opacity] = class_name; - if (sheetClass.background.opacity_transition && sheetClass.background.opacity_transition.get().duration) { - properties_to_transition["background"][TransitionablePropertyKey::Opacity] = sheetClass.background.opacity_transition.get(); - } - } } } diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index b6e73147d..56e28350b 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -533,7 +533,7 @@ void StyleParser::parseGenericClass(GenericClass &klass, JSVal value) { } if (value.HasMember("prerender-blur")) { - klass.prerenderBlur = parseBoolean(value["prerender-blur"]); + klass.prerenderBlur = toNumber(parseValue(value["prerender-blur"])); } } From e3e982acd8e0edbad3813dbcaa1d0428c2002ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 12:44:35 +0200 Subject: [PATCH 11/21] respect the prerendered-* stylesheet values --- src/renderer/painter_fill.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 76f510c7d..858377047 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -157,7 +157,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // 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 - const int buffer = 128; + const int buffer = 4096 * properties.prerenderBuffer; if (!bucket.prerendered) { bucket.prerendered = std::make_unique(); @@ -172,7 +172,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons #endif glClear(GL_COLOR_BUFFER_BIT); - glViewport(0, 0, 256, 256); + glViewport(0, 0, properties.prerenderSize, properties.prerenderSize); // When drawing the fill, we want to draw a 16.66% buffer around too, so we @@ -205,7 +205,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons 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, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, properties.prerenderSize, properties.prerenderSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); @@ -215,7 +215,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons glActiveTexture(GL_TEXTURE0); - for (int i = 0; i < 1; i++) { + for (int i = 0; i < properties.prerenderBlur; i++) { // Render horizontal glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, secondary_texture, 0); #if GL_EXT_discard_framebuffer @@ -224,7 +224,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons #endif glClear(GL_COLOR_BUFFER_BIT); - gaussianShader->setOffset({{ 1.0f / 256.0f, 0 }}); + gaussianShader->setOffset({{ 1.0f / float(properties.prerenderSize), 0 }}); glBindTexture(GL_TEXTURE_2D, original_texture); coveringGaussianArray.bind(*gaussianShader, tileStencilBuffer, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); @@ -238,7 +238,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons #endif glClear(GL_COLOR_BUFFER_BIT); - gaussianShader->setOffset({{ 0, 1.0f / 256.0f }}); + gaussianShader->setOffset({{ 0, 1.0f / float(properties.prerenderSize) }}); glBindTexture(GL_TEXTURE_2D, secondary_texture); coveringGaussianArray.bind(*gaussianShader, tileStencilBuffer, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); From 6350dc5235b5e206d9892e99da984dbe555a870a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 13:31:51 +0200 Subject: [PATCH 12/21] move blurring to texture object --- include/llmr/renderer/painter.hpp | 12 +++ include/llmr/renderer/prerendered_texture.hpp | 6 ++ src/renderer/painter_fill.cpp | 80 +------------------ src/renderer/painter_prerender.cpp | 25 ++++++ src/renderer/prerendered_texture.cpp | 59 +++++++++++++- 5 files changed, 105 insertions(+), 77 deletions(-) create mode 100644 src/renderer/painter_prerender.cpp diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 10f706880..f93250236 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -84,6 +84,7 @@ public: void renderIcon(IconBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderRaster(RasterBucket& bucket, const std::string& layer_name, const Tile::ID& id); + void renderPrerenderedTexture(Bucket &bucket, const GenericProperties &properties); void resize(); @@ -114,6 +115,8 @@ private: const mat4 &translatedMatrix(const std::array &translation, const Tile::ID &id, TranslateAnchor anchor = TranslateAnchor::Map); void prepareTile(const Tile& tile); + +public: void useProgram(uint32_t program); void lineWidth(float lineWidth); void depthMask(bool value); @@ -125,6 +128,14 @@ public: mat4 nativeMatrix; mat4 extrudeMatrix; + // used to composite images and flips the geometry upside down + const mat4 flipMatrix = []{ + mat4 flipMatrix; + matrix::ortho(flipMatrix, 0, 4096, -4096, 0, 0, 1); + matrix::translate(flipMatrix, flipMatrix, 0, -4096, 0); + return flipMatrix; + }(); + private: Map& map; @@ -140,6 +151,7 @@ private: enum { Opaque, Translucent } pass = Opaque; const float strata_epsilon = 1.0f / (1 << 16); +public: std::unique_ptr plainShader; std::unique_ptr outlineShader; std::unique_ptr lineShader; diff --git a/include/llmr/renderer/prerendered_texture.hpp b/include/llmr/renderer/prerendered_texture.hpp index f74fe1d11..e35cc0321 100644 --- a/include/llmr/renderer/prerendered_texture.hpp +++ b/include/llmr/renderer/prerendered_texture.hpp @@ -6,8 +6,11 @@ namespace llmr { +class Painter; + class PrerenderedTexture : private util::noncopyable { public: + PrerenderedTexture(uint16_t size); ~PrerenderedTexture(); void bindTexture(); @@ -16,7 +19,10 @@ public: inline GLuint getTexture() const { return texture; } + void blur(Painter& painter, uint16_t passes); + private: + const uint16_t size; GLint previous_fbo = 0; GLuint fbo = 0; GLuint texture = 0; diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 858377047..8d86716aa 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -157,10 +157,9 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // 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 - const int buffer = 4096 * properties.prerenderBuffer; if (!bucket.prerendered) { - bucket.prerendered = std::make_unique(); + bucket.prerendered = std::make_unique(properties.prerenderSize); glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); @@ -179,6 +178,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // essentially downscale everyting, and then upscale it later when rendering. mat4 vtxMatrix; + const int buffer = 4096 * properties.prerenderBuffer; matrix::ortho(vtxMatrix, -buffer, 4096 + buffer, -4096 - buffer, buffer, 0, 1); matrix::translate(vtxMatrix, vtxMatrix, 0, -4096, 0); @@ -188,63 +188,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons renderFill(bucket, properties, id, vtxMatrix); - - mat4 regularMatrix; - matrix::ortho(regularMatrix, 0, 4096, -4096, 0, 0, 1); - matrix::translate(regularMatrix, regularMatrix, 0, -4096, 0); - - - // BLUR - - GLuint original_texture = bucket.prerendered->getTexture(); - - GLuint secondary_texture; - glGenTextures(1, &secondary_texture); - glBindTexture(GL_TEXTURE_2D, secondary_texture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - 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.prerenderSize, properties.prerenderSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, 0); - - - useProgram(gaussianShader->program); - gaussianShader->setMatrix(regularMatrix); - gaussianShader->setImage(0); - glActiveTexture(GL_TEXTURE0); - - - for (int i = 0; i < properties.prerenderBlur; i++) { - // Render horizontal - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, secondary_texture, 0); -#if GL_EXT_discard_framebuffer - const GLenum discards[] = { GL_COLOR_ATTACHMENT0 }; - glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); -#endif - glClear(GL_COLOR_BUFFER_BIT); - - gaussianShader->setOffset({{ 1.0f / float(properties.prerenderSize), 0 }}); - glBindTexture(GL_TEXTURE_2D, original_texture); - coveringGaussianArray.bind(*gaussianShader, tileStencilBuffer, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); - - - - // Render vertical - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, original_texture, 0); -#if GL_EXT_discard_framebuffer - glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); -#endif - glClear(GL_COLOR_BUFFER_BIT); - - gaussianShader->setOffset({{ 0, 1.0f / float(properties.prerenderSize) }}); - glBindTexture(GL_TEXTURE_2D, secondary_texture); - coveringGaussianArray.bind(*gaussianShader, tileStencilBuffer, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); - } - - glDeleteTextures(1, &secondary_texture); + bucket.prerendered->blur(*this, properties.prerenderBlur); // RESET STATE @@ -257,23 +201,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons glViewport(0, 0, gl_viewport[0], gl_viewport[1]); } - // draw the texture on a quad - depthMask(false); - - useProgram(rasterShader->program); - rasterShader->setMatrix(matrix); - rasterShader->setOpacity(1); - - glDepthRange(strata, 1.0f); - - glActiveTexture(GL_TEXTURE0); - rasterShader->setImage(0); - rasterShader->setBuffer(buffer); - bucket.prerendered->bindTexture(); - coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); - - depthMask(true); + renderPrerenderedTexture(bucket, properties); } } else { const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); diff --git a/src/renderer/painter_prerender.cpp b/src/renderer/painter_prerender.cpp new file mode 100644 index 000000000..7d6abcb35 --- /dev/null +++ b/src/renderer/painter_prerender.cpp @@ -0,0 +1,25 @@ +#include + +using namespace llmr; + +void Painter::renderPrerenderedTexture(Bucket &bucket, const GenericProperties &properties) { + const int buffer = 4096 * properties.prerenderBuffer; + + // draw the texture on a quad + depthMask(false); + + useProgram(rasterShader->program); + rasterShader->setMatrix(matrix); + rasterShader->setOpacity(1); + + glDepthRange(strata, 1.0f); + + glActiveTexture(GL_TEXTURE0); + rasterShader->setImage(0); + rasterShader->setBuffer(buffer); + bucket.prerendered->bindTexture(); + coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); + + depthMask(true); +} diff --git a/src/renderer/prerendered_texture.cpp b/src/renderer/prerendered_texture.cpp index 3fd81ccdf..408f433be 100644 --- a/src/renderer/prerendered_texture.cpp +++ b/src/renderer/prerendered_texture.cpp @@ -1,8 +1,13 @@ #include +#include using namespace llmr; +PrerenderedTexture::PrerenderedTexture(uint16_t size) + : size(size) { +} + PrerenderedTexture::~PrerenderedTexture() { if (texture != 0) { glDeleteTextures(1, &texture); @@ -40,7 +45,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, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); } @@ -78,3 +83,55 @@ void PrerenderedTexture::unbindFramebuffer() { fbo = 0; } } + +void PrerenderedTexture::blur(Painter& painter, uint16_t passes) { + const GLuint original_texture = texture; + + // Create a secondary texture + GLuint secondary_texture; + glGenTextures(1, &secondary_texture); + glBindTexture(GL_TEXTURE_2D, secondary_texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + 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); + glBindTexture(GL_TEXTURE_2D, 0); + + + painter.useProgram(painter.gaussianShader->program); + painter.gaussianShader->setMatrix(painter.flipMatrix); + painter.gaussianShader->setImage(0); + glActiveTexture(GL_TEXTURE0); + + for (int i = 0; i < passes; i++) { + // Render horizontal + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, secondary_texture, 0); +#if GL_EXT_discard_framebuffer + const GLenum discards[] = { GL_COLOR_ATTACHMENT0 }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); +#endif + glClear(GL_COLOR_BUFFER_BIT); + + painter.gaussianShader->setOffset({{ 1.0f / float(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()); + + + + // Render vertical + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, original_texture, 0); +#if GL_EXT_discard_framebuffer + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); +#endif + glClear(GL_COLOR_BUFFER_BIT); + + painter.gaussianShader->setOffset({{ 0, 1.0f / float(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()); + } + + glDeleteTextures(1, &secondary_texture); +} From 9b5c75cef066420daea384b00349459115c30237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 15:34:50 +0200 Subject: [PATCH 13/21] add isVisible function to Properties --- include/llmr/style/properties.hpp | 6 ++++++ src/map/map.cpp | 11 ++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index d44579b48..af304c1ea 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -106,6 +106,12 @@ struct GenericProperties { float prerenderBuffer = 1.0f / 32.0f; uint16_t prerenderSize = 256; uint16_t prerenderBlur = 0; + + virtual bool isVisible() const { + if (!enabled) { return false; } + if (opacity <= 0) { return false; } + return true; + } }; struct IconClass : public GenericClass { diff --git a/src/map/map.cpp b/src/map/map.cpp index 13e42727d..252d29204 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -572,18 +572,11 @@ typename Styles::const_iterator find_style(const Styles &styles, const LayerDesc return it; } -template -bool is_invisible(const Properties &properties) { - if (!properties.enabled) { return true; } - if (properties.opacity <= 0) { return true; } - return false; -} - template bool is_invisible(const Styles &styles, const LayerDescription &layer_desc) { auto it = find_style(styles, layer_desc); if (it == styles.end()) { return true; } - return is_invisible(it->second); + return !it->second.isVisible(); } void Map::renderLayer(const LayerDescription& layer_desc, RenderPass pass) { @@ -592,7 +585,7 @@ void Map::renderLayer(const LayerDescription& layer_desc, RenderPass pass) { if (pass == Translucent) { auto it = find_style(style.computed.composites, layer_desc); const CompositeProperties &properties = (it != style.computed.composites.end()) ? it->second : defaultCompositeProperties; - if (!is_invisible(properties)) { + if (properties.isVisible()) { gl::group group(std::string("group: ") + layer_desc.name); if (debug::renderTree) { From 6ed5c0ddf3d940b8fb6c4517984b25e0e5d9d002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 15:35:08 +0200 Subject: [PATCH 14/21] use sigma 1 for blur by default --- src/shader/gaussian.fragment.glsl | 10 ++++------ src/shader/gaussian.vertex.glsl | 8 +++----- src/shader/shaders_gl.cpp | 4 ++-- src/shader/shaders_gles2.cpp | 4 ++-- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/shader/gaussian.fragment.glsl b/src/shader/gaussian.fragment.glsl index b7b193b26..e29afc0a8 100644 --- a/src/shader/gaussian.fragment.glsl +++ b/src/shader/gaussian.fragment.glsl @@ -1,14 +1,12 @@ uniform sampler2D u_image; -varying vec2 v_coords[5]; +varying vec2 v_coords[3]; void main() { vec4 sum = vec4(0.0); - sum += texture2D(u_image, v_coords[0]) * 0.204164; - sum += texture2D(u_image, v_coords[1]) * 0.304005; - sum += texture2D(u_image, v_coords[2]) * 0.304005; - sum += texture2D(u_image, v_coords[3]) * 0.093913; - sum += texture2D(u_image, v_coords[4]) * 0.093913; + sum += texture2D(u_image, v_coords[0]) * 0.40261994689424746; + sum += texture2D(u_image, v_coords[1]) * 0.2986900265528763; + sum += texture2D(u_image, v_coords[2]) * 0.2986900265528763; gl_FragColor = sum; } \ No newline at end of file diff --git a/src/shader/gaussian.vertex.glsl b/src/shader/gaussian.vertex.glsl index 4f60e2a11..320d48f23 100644 --- a/src/shader/gaussian.vertex.glsl +++ b/src/shader/gaussian.vertex.glsl @@ -3,15 +3,13 @@ attribute vec2 a_pos; uniform mat4 u_matrix; uniform vec2 u_offset; -varying vec2 v_coords[5]; +varying vec2 v_coords[3]; void main() { gl_Position = u_matrix * vec4(a_pos, 0, 1); vec2 tex = (gl_Position.xy + 1.0) / 2.0; v_coords[0] = tex; - v_coords[1] = tex + u_offset * 1.407333; - v_coords[2] = tex - u_offset * 1.407333; - v_coords[3] = tex + u_offset * 3.294215; - v_coords[4] = tex - u_offset * 3.294215; + v_coords[1] = tex + u_offset * 1.1824255238063563; + v_coords[2] = tex - u_offset * 1.1824255238063563; } diff --git a/src/shader/shaders_gl.cpp b/src/shader/shaders_gl.cpp index 84fc539b4..fab63485f 100644 --- a/src/shader/shaders_gl.cpp +++ b/src/shader/shaders_gl.cpp @@ -15,8 +15,8 @@ const shader_source llmr::shaders[SHADER_COUNT] = { "#version 120\nuniform vec4 u_color;\nuniform float u_blur;\nvoid main ()\n{\n vec2 x_1;\n x_1 = (gl_PointCoord - 0.5);\n float tmpvar_2;\n tmpvar_2 = clamp (((\n sqrt(dot (x_1, x_1))\n - 0.5) / (\n (0.5 - u_blur)\n - 0.5)), 0.0, 1.0);\n gl_FragColor = (u_color * (tmpvar_2 * (tmpvar_2 * \n (3.0 - (2.0 * tmpvar_2))\n )));\n}\n\n", }, { - "#version 120\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform vec2 u_offset;\nvarying vec2 v_coords[5];\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n vec4 tmpvar_2;\n tmpvar_2 = (u_matrix * tmpvar_1);\n gl_Position = tmpvar_2;\n vec2 tmpvar_3;\n tmpvar_3 = ((tmpvar_2.xy + 1.0) / 2.0);\n v_coords[0] = tmpvar_3;\n vec2 cse_4;\n cse_4 = (u_offset * 1.40733);\n v_coords[1] = (tmpvar_3 + cse_4);\n v_coords[2] = (tmpvar_3 - cse_4);\n vec2 cse_5;\n cse_5 = (u_offset * 3.29421);\n v_coords[3] = (tmpvar_3 + cse_5);\n v_coords[4] = (tmpvar_3 - cse_5);\n}\n\n", - "#version 120\nuniform sampler2D u_image;\nvarying vec2 v_coords[5];\nvoid main ()\n{\n gl_FragColor = (((\n ((texture2D (u_image, v_coords[0]) * 0.204164) + (texture2D (u_image, v_coords[1]) * 0.304005))\n + \n (texture2D (u_image, v_coords[2]) * 0.304005)\n ) + (texture2D (u_image, v_coords[3]) * 0.093913)) + (texture2D (u_image, v_coords[4]) * 0.093913));\n}\n\n", + "#version 120\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform vec2 u_offset;\nvarying vec2 v_coords[3];\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n vec4 tmpvar_2;\n tmpvar_2 = (u_matrix * tmpvar_1);\n gl_Position = tmpvar_2;\n vec2 tmpvar_3;\n tmpvar_3 = ((tmpvar_2.xy + 1.0) / 2.0);\n v_coords[0] = tmpvar_3;\n vec2 cse_4;\n cse_4 = (u_offset * 1.18243);\n v_coords[1] = (tmpvar_3 + cse_4);\n v_coords[2] = (tmpvar_3 - cse_4);\n}\n\n", + "#version 120\nuniform sampler2D u_image;\nvarying vec2 v_coords[3];\nvoid main ()\n{\n gl_FragColor = (((texture2D (u_image, v_coords[0]) * 0.40262) + (texture2D (u_image, v_coords[1]) * 0.29869)) + (texture2D (u_image, v_coords[2]) * 0.29869));\n}\n\n", }, { "#version 120\nattribute vec2 a_pos;\nattribute vec2 a_tex;\nuniform mat4 u_matrix;\nuniform float u_size;\nuniform float u_ratio;\nvarying vec2 v_tex;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n v_tex = (a_tex * u_ratio);\n}\n\n", diff --git a/src/shader/shaders_gles2.cpp b/src/shader/shaders_gles2.cpp index 6dad644e7..ce17d1bbc 100644 --- a/src/shader/shaders_gles2.cpp +++ b/src/shader/shaders_gles2.cpp @@ -15,8 +15,8 @@ const shader_source llmr::shaders[SHADER_COUNT] = { "precision highp float;\nuniform vec4 u_color;\nuniform float u_blur;\nvoid main ()\n{\n mediump vec2 x_1;\n x_1 = (gl_PointCoord - 0.5);\n mediump float tmpvar_2;\n tmpvar_2 = clamp (((\n sqrt(dot (x_1, x_1))\n - 0.5) / (\n (0.5 - u_blur)\n - 0.5)), 0.0, 1.0);\n gl_FragColor = (u_color * (tmpvar_2 * (tmpvar_2 * \n (3.0 - (2.0 * tmpvar_2))\n )));\n}\n\n", }, { - "precision highp float;\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform vec2 u_offset;\nvarying highp vec2 v_coords[5];\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n vec4 tmpvar_2;\n tmpvar_2 = (u_matrix * tmpvar_1);\n gl_Position = tmpvar_2;\n highp vec2 tmpvar_3;\n tmpvar_3 = ((tmpvar_2.xy + 1.0) / 2.0);\n v_coords[0] = tmpvar_3;\n vec2 cse_4;\n cse_4 = (u_offset * 1.40733);\n v_coords[1] = (tmpvar_3 + cse_4);\n v_coords[2] = (tmpvar_3 - cse_4);\n vec2 cse_5;\n cse_5 = (u_offset * 3.29421);\n v_coords[3] = (tmpvar_3 + cse_5);\n v_coords[4] = (tmpvar_3 - cse_5);\n}\n\n", - "precision highp float;\nuniform sampler2D u_image;\nvarying vec2 v_coords[5];\nvoid main ()\n{\n lowp vec4 tmpvar_1;\n tmpvar_1 = (((\n ((texture2D (u_image, v_coords[0]) * 0.204164) + (texture2D (u_image, v_coords[1]) * 0.304005))\n + \n (texture2D (u_image, v_coords[2]) * 0.304005)\n ) + (texture2D (u_image, v_coords[3]) * 0.093913)) + (texture2D (u_image, v_coords[4]) * 0.093913));\n gl_FragColor = tmpvar_1;\n}\n\n", + "precision highp float;\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform vec2 u_offset;\nvarying highp vec2 v_coords[3];\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n vec4 tmpvar_2;\n tmpvar_2 = (u_matrix * tmpvar_1);\n gl_Position = tmpvar_2;\n highp vec2 tmpvar_3;\n tmpvar_3 = ((tmpvar_2.xy + 1.0) / 2.0);\n v_coords[0] = tmpvar_3;\n vec2 cse_4;\n cse_4 = (u_offset * 1.18243);\n v_coords[1] = (tmpvar_3 + cse_4);\n v_coords[2] = (tmpvar_3 - cse_4);\n}\n\n", + "precision highp float;\nuniform sampler2D u_image;\nvarying vec2 v_coords[3];\nvoid main ()\n{\n lowp vec4 tmpvar_1;\n tmpvar_1 = (((texture2D (u_image, v_coords[0]) * 0.40262) + (texture2D (u_image, v_coords[1]) * 0.29869)) + (texture2D (u_image, v_coords[2]) * 0.29869));\n gl_FragColor = tmpvar_1;\n}\n\n", }, { "precision highp float;\nattribute vec2 a_pos;\nattribute vec2 a_tex;\nuniform mat4 u_matrix;\nuniform float u_size;\nuniform float u_ratio;\nvarying vec2 v_tex;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n v_tex = (a_tex * u_ratio);\n}\n\n", From 2d0037b11203a7f7c186ca088dab37938d772f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 15:38:51 +0200 Subject: [PATCH 15/21] don't respect opacity when prerendering tile; we do opacity at composite-time --- src/renderer/painter_fill.cpp | 10 ++++++++-- src/renderer/painter_prerender.cpp | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 8d86716aa..6fe4c2cb9 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -174,6 +174,12 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons glViewport(0, 0, properties.prerenderSize, properties.prerenderSize); + const FillProperties modifiedProperties = [&]{ + FillProperties modifiedProperties = properties; + modifiedProperties.opacity = 1; + return modifiedProperties; + }(); + // When drawing the fill, we want to draw a 16.66% buffer around too, so we // essentially downscale everyting, and then upscale it later when rendering. @@ -183,9 +189,9 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons matrix::translate(vtxMatrix, vtxMatrix, 0, -4096, 0); pass = Opaque; - renderFill(bucket, properties, id, vtxMatrix); + renderFill(bucket, modifiedProperties, id, vtxMatrix); pass = Translucent; - renderFill(bucket, properties, id, vtxMatrix); + renderFill(bucket, modifiedProperties, id, vtxMatrix); bucket.prerendered->blur(*this, properties.prerenderBlur); diff --git a/src/renderer/painter_prerender.cpp b/src/renderer/painter_prerender.cpp index 7d6abcb35..be78487f3 100644 --- a/src/renderer/painter_prerender.cpp +++ b/src/renderer/painter_prerender.cpp @@ -17,6 +17,7 @@ void Painter::renderPrerenderedTexture(Bucket &bucket, const GenericProperties & glActiveTexture(GL_TEXTURE0); rasterShader->setImage(0); rasterShader->setBuffer(buffer); + rasterShader->setOpacity(properties.opacity); bucket.prerendered->bindTexture(); coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); From e40ed2729d24ce5fd914a0264eb3a0ae2d8ca45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 15:43:12 +0200 Subject: [PATCH 16/21] use lambda initialization for matrix --- src/renderer/painter_fill.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 6fe4c2cb9..431f0a455 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -180,16 +180,19 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons return modifiedProperties; }(); - // When drawing the fill, we want to draw a 16.66% buffer around too, so we + // When drawing the fill, we want to draw a buffer around too, so we // essentially downscale everyting, and then upscale it later when rendering. - - mat4 vtxMatrix; const int buffer = 4096 * properties.prerenderBuffer; - matrix::ortho(vtxMatrix, -buffer, 4096 + buffer, -4096 - buffer, buffer, 0, 1); - matrix::translate(vtxMatrix, vtxMatrix, 0, -4096, 0); + 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; + }(); pass = Opaque; renderFill(bucket, modifiedProperties, id, vtxMatrix); + pass = Translucent; renderFill(bucket, modifiedProperties, id, vtxMatrix); @@ -198,8 +201,6 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // RESET STATE - - bucket.prerendered->unbindFramebuffer(); glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); From 2029763b71a9020f706bba9a5bfe4203c7af9952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 16:11:23 +0200 Subject: [PATCH 17/21] only blur if we actually need to --- src/renderer/painter_fill.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 431f0a455..dbfebb5a6 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -197,7 +197,9 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons renderFill(bucket, modifiedProperties, id, vtxMatrix); - bucket.prerendered->blur(*this, properties.prerenderBlur); + if (properties.prerenderBlur > 0) { + bucket.prerendered->blur(*this, properties.prerenderBlur); + } // RESET STATE From 8b63d19198053214e523f593397fa6a118f34a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 16:14:09 +0200 Subject: [PATCH 18/21] prerender/blur terrain --- bin/style.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/bin/style.js b/bin/style.js index f8ce84b6c..5c8ada38c 100644 --- a/bin/style.js +++ b/bin/style.js @@ -1731,6 +1731,8 @@ module.exports = { "hillshade_full_shadow": { "color": "#103", "antialias": false, + "prerender": true, + "prerender-blur": 1, "opacity": [ "stops", {"z": 15, "val": 0.075}, @@ -1741,6 +1743,8 @@ module.exports = { "hillshade_medium_shadow": { "color": "#206", "antialias": false, + "prerender": true, + "prerender-blur": 1, "opacity": [ "stops", {"z": 15, "val": 0.075}, @@ -1751,6 +1755,8 @@ module.exports = { "hillshade_full_highlight": { "color": "#fffff3", "antialias": false, + "prerender": true, + "prerender-blur": 1, "opacity": [ "stops", {"z": 15, "val": 0.3}, @@ -1761,6 +1767,8 @@ module.exports = { "hillshade_medium_highlight": { "color": "#ffd", "antialias": false, + "prerender": true, + "prerender-blur": 1, "opacity": [ "stops", {"z": 15, "val": 0.3}, @@ -2429,6 +2437,8 @@ module.exports = { "hillshade_full_shadow": { "color": "#103", "antialias": false, + "prerender": true, + "prerender-blur": 1, "opacity": [ "stops", {"z": 0, "val": 0.3}, @@ -2439,6 +2449,8 @@ module.exports = { "hillshade_medium_shadow": { "color": "#206", "antialias": false, + "prerender": true, + "prerender-blur": 1, "opacity": [ "stops", {"z": 0, "val": 0.3}, @@ -2449,6 +2461,8 @@ module.exports = { "hillshade_full_highlight": { "color": "#fdfdad", "antialias": false, + "prerender": true, + "prerender-blur": 1, "opacity": [ "stops", {"z": 14, "val": 0.4}, @@ -2460,6 +2474,8 @@ module.exports = { "hillshade_medium_highlight": { "color": "#ffe1b7", "antialias": false, + "prerender": true, + "prerender-blur": 1, "opacity": [ "stops", {"z": 15, "val": 0.3}, From 3a9f353a1eea77d1f0a07dea85c7a91799dea43b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 16:33:38 +0200 Subject: [PATCH 19/21] move a view calls to generic functions --- include/llmr/renderer/painter.hpp | 3 +++ src/renderer/painter_fill.cpp | 18 ++---------------- src/renderer/painter_prerender.cpp | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index f93250236..0345c9c00 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -84,6 +84,9 @@ public: void renderIcon(IconBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderRaster(RasterBucket& bucket, const std::string& layer_name, const Tile::ID& id); + + void preparePrerender(const GenericProperties &properties); + void finishPrerender(const GenericProperties &properties); void renderPrerenderedTexture(Bucket &bucket, const GenericProperties &properties); void resize(); diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index dbfebb5a6..b52f8c396 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -160,19 +160,9 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons if (!bucket.prerendered) { bucket.prerendered = std::make_unique(properties.prerenderSize); - glDisable(GL_DEPTH_TEST); - glDisable(GL_STENCIL_TEST); - bucket.prerendered->bindFramebuffer(); - // Render the actual tile. -#if GL_EXT_discard_framebuffer - const GLenum discards[] = { GL_COLOR_ATTACHMENT0 }; - glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); -#endif - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, properties.prerenderSize, properties.prerenderSize); + preparePrerender(properties); const FillProperties modifiedProperties = [&]{ FillProperties modifiedProperties = properties; @@ -201,13 +191,9 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons bucket.prerendered->blur(*this, properties.prerenderBlur); } - // RESET STATE bucket.prerendered->unbindFramebuffer(); - glEnable(GL_DEPTH_TEST); - glEnable(GL_STENCIL_TEST); - - glViewport(0, 0, gl_viewport[0], gl_viewport[1]); + finishPrerender(properties); } renderPrerenderedTexture(bucket, properties); diff --git a/src/renderer/painter_prerender.cpp b/src/renderer/painter_prerender.cpp index be78487f3..d112f7aad 100644 --- a/src/renderer/painter_prerender.cpp +++ b/src/renderer/painter_prerender.cpp @@ -2,6 +2,27 @@ using namespace llmr; +void Painter::preparePrerender(const GenericProperties &properties) { + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + +// Render the actual tile. +#if GL_EXT_discard_framebuffer + const GLenum discards[] = {GL_COLOR_ATTACHMENT0}; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); +#endif + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, properties.prerenderSize, properties.prerenderSize); +} + +void Painter::finishPrerender(const GenericProperties &properties) { + 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; From 65bffccfd91820cbf0518c841a33995999c68a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 17:41:00 +0200 Subject: [PATCH 20/21] use most recent ios wrapper --- ios/MVKMapKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/MVKMapKit b/ios/MVKMapKit index 172218fa9..851bf5c22 160000 --- a/ios/MVKMapKit +++ b/ios/MVKMapKit @@ -1 +1 @@ -Subproject commit 172218fa978dc061c31ce3a814294fd7cd5559b9 +Subproject commit 851bf5c22829e4f8ccbfcb02faf25c8277b7f02e From 1b58fb30a3205e68f03f021e8c4314cf59629683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 26 May 2014 18:40:47 +0200 Subject: [PATCH 21/21] use unordered map, don't make copies (auto usage!) and swap maps --- include/llmr/style/style.hpp | 37 +++++++++++++++++---------------- src/renderer/painter_fill.cpp | 4 ++-- src/renderer/painter_icon.cpp | 4 ++-- src/renderer/painter_line.cpp | 4 ++-- src/renderer/painter_raster.cpp | 4 ++-- src/renderer/painter_text.cpp | 4 ++-- src/style/style.cpp | 14 ++++++------- 7 files changed, 36 insertions(+), 35 deletions(-) diff --git a/include/llmr/style/style.hpp b/include/llmr/style/style.hpp index 4aa4b748b..048c4d545 100644 --- a/include/llmr/style/style.hpp +++ b/include/llmr/style/style.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -52,12 +53,12 @@ public: std::set appliedClasses; struct { BackgroundProperties background; - std::map fills; - std::map lines; - std::map icons; - std::map texts; - std::map rasters; - std::map composites; + std::unordered_map fills; + std::unordered_map lines; + std::unordered_map icons; + std::unordered_map texts; + std::unordered_map rasters; + std::unordered_map composites; std::map> effective_classes; } computed; @@ -74,24 +75,24 @@ private: // Last applied settings. struct { BackgroundProperties background; - std::map fills; - std::map lines; - std::map icons; - std::map texts; - std::map rasters; - std::map composites; + std::unordered_map fills; + std::unordered_map lines; + std::unordered_map icons; + std::unordered_map texts; + std::unordered_map rasters; + std::unordered_map composites; std::map> effective_classes; } previous; // Settings values currently being transitioned. struct { BackgroundProperties background; - std::map fills; - std::map lines; - std::map icons; - std::map texts; - std::map rasters; - std::map composites; + std::unordered_map fills; + std::unordered_map lines; + std::unordered_map icons; + std::unordered_map texts; + std::unordered_map rasters; + std::unordered_map composites; } transitioning; std::map> properties_to_transition; diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index b52f8c396..5f014dc01 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -144,8 +144,8 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // Abort early. if (!bucket.hasData()) return; - auto fill_properties = map.getStyle().computed.fills; - auto fill_properties_it = fill_properties.find(layer_name); + const std::unordered_map &fill_properties = map.getStyle().computed.fills; + const std::unordered_map::const_iterator fill_properties_it = fill_properties.find(layer_name); if (fill_properties_it == fill_properties.end()) return; const FillProperties& properties = fill_properties_it->second; diff --git a/src/renderer/painter_icon.cpp b/src/renderer/painter_icon.cpp index b5f4964e6..382312c12 100644 --- a/src/renderer/painter_icon.cpp +++ b/src/renderer/painter_icon.cpp @@ -11,8 +11,8 @@ void Painter::renderIcon(IconBucket& bucket, const std::string& layer_name, cons if (!bucket.hasData()) return; if (pass == Opaque) return; - auto icon_properties = map.getStyle().computed.icons; - auto icon_properties_it = icon_properties.find(layer_name); + const std::unordered_map &icon_properties = map.getStyle().computed.icons; + const std::unordered_map::const_iterator icon_properties_it = icon_properties.find(layer_name); if (icon_properties_it == icon_properties.end()) return; const IconProperties& properties = icon_properties_it->second; diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp index 8dc486201..2788a8bb1 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -9,8 +9,8 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons if (pass == Opaque) return; if (!bucket.hasData()) return; - auto line_properties = map.getStyle().computed.lines; - auto line_properties_it = line_properties.find(layer_name); + const std::unordered_map &line_properties = map.getStyle().computed.lines; + const std::unordered_map::const_iterator line_properties_it = line_properties.find(layer_name); if (line_properties_it == line_properties.end()) return; const LineProperties& properties = line_properties_it->second; diff --git a/src/renderer/painter_raster.cpp b/src/renderer/painter_raster.cpp index b877496e0..de0d35261 100644 --- a/src/renderer/painter_raster.cpp +++ b/src/renderer/painter_raster.cpp @@ -7,8 +7,8 @@ using namespace llmr; void Painter::renderRaster(RasterBucket& bucket, const std::string& layer_name, const Tile::ID& /*id*/) { if (pass == Translucent) return; - auto raster_properties = map.getStyle().computed.rasters; - auto raster_properties_it = raster_properties.find(layer_name); + const std::unordered_map &raster_properties = map.getStyle().computed.rasters; + const std::unordered_map::const_iterator raster_properties_it = raster_properties.find(layer_name); if (raster_properties_it == raster_properties.end()) return; const RasterProperties& properties = raster_properties_it->second; diff --git a/src/renderer/painter_text.cpp b/src/renderer/painter_text.cpp index f2e458d8c..0c3c0a01b 100644 --- a/src/renderer/painter_text.cpp +++ b/src/renderer/painter_text.cpp @@ -9,8 +9,8 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons if (pass == Opaque) return; if (!bucket.hasData()) return; - auto text_properties = map.getStyle().computed.texts; - auto text_properties_it = text_properties.find(layer_name); + const std::unordered_map &text_properties = map.getStyle().computed.texts; + const std::unordered_map::const_iterator text_properties_it = text_properties.find(layer_name); if (text_properties_it == text_properties.end()) return; const TextProperties& properties = text_properties_it->second; diff --git a/src/style/style.cpp b/src/style/style.cpp index 7f9b6ba78..38b8f1723 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -74,15 +74,15 @@ void Style::cascade(float z) { time start = util::now(); - previous.fills = computed.fills; - previous.lines = computed.lines; - previous.icons = computed.icons; - previous.texts = computed.texts; - previous.rasters = computed.rasters; - previous.composites = computed.composites; + previous.fills.swap(computed.fills); + previous.lines.swap(computed.lines); + previous.icons.swap(computed.icons); + previous.texts.swap(computed.texts); + previous.rasters.swap(computed.rasters); + previous.composites.swap(computed.composites); previous.background = computed.background; - previous.effective_classes = computed.effective_classes; + previous.effective_classes.swap(computed.effective_classes); reset();