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",