diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-02-03 22:51:21 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-02-03 22:51:21 +0100 |
commit | 9ab9eeec1334f5556c04f944dda07abe58ed0f45 (patch) | |
tree | 891b9873793b1b93ff5bdc14cda7f5058d4b3e1b | |
parent | e478ae2a2de63402f29cf0ef7d0739d98e1c83d2 (diff) | |
download | qtlocation-mapboxgl-9ab9eeec1334f5556c04f944dda07abe58ed0f45.tar.gz |
textured fills
fixes #15
-rwxr-xr-x | bin/convert-style.js | 4 | ||||
-rw-r--r-- | bin/style.js | 3 | ||||
-rw-r--r-- | include/llmr/map/map.hpp | 2 | ||||
-rw-r--r-- | include/llmr/renderer/bucket.hpp | 3 | ||||
-rw-r--r-- | include/llmr/renderer/fill_bucket.hpp | 2 | ||||
-rw-r--r-- | include/llmr/renderer/line_bucket.hpp | 2 | ||||
-rw-r--r-- | include/llmr/renderer/painter.hpp | 6 | ||||
-rw-r--r-- | include/llmr/renderer/shader-pattern.hpp | 25 | ||||
-rw-r--r-- | include/llmr/shader/shaders.hpp | 1 | ||||
-rw-r--r-- | include/llmr/style/properties.hpp | 3 | ||||
-rw-r--r-- | include/llmr/style/style.hpp | 3 | ||||
-rw-r--r-- | proto/style.proto | 1 | ||||
-rw-r--r-- | resources/style.pbf | bin | 1027 -> 1033 bytes | |||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/map/map.cpp | 5 | ||||
-rw-r--r-- | src/renderer/fill_bucket.cpp | 4 | ||||
-rw-r--r-- | src/renderer/line_bucket.cpp | 4 | ||||
-rw-r--r-- | src/renderer/painter.cpp | 74 | ||||
-rw-r--r-- | src/renderer/shader-pattern.cpp | 27 | ||||
-rw-r--r-- | src/shader/pattern.fragment.glsl | 26 | ||||
-rw-r--r-- | src/shader/pattern.vertex.glsl | 10 | ||||
-rw-r--r-- | src/shader/shaders.cpp | 6 | ||||
-rw-r--r-- | src/style/resources.cpp | 44 | ||||
-rw-r--r-- | src/style/style.cpp | 3 |
24 files changed, 189 insertions, 71 deletions
diff --git a/bin/convert-style.js b/bin/convert-style.js index 74501ad8e3..549732c001 100755 --- a/bin/convert-style.js +++ b/bin/convert-style.js @@ -140,6 +140,10 @@ function createFillClass(layer, name) { pbf.writeMessage(7 /* opacity */, convertProperty(layer.opacity)); } + if ('image' in layer) { + pbf.writeTaggedString(8 /* image */, layer.image); + } + return pbf; } diff --git a/bin/style.js b/bin/style.js index 26b7bc6544..10f5501660 100644 --- a/bin/style.js +++ b/bin/style.js @@ -82,7 +82,8 @@ module.exports = { "park": { "type": "fill", "color": "#c8df9f", - "antialias": true + "antialias": true, + "image": "park" }, "wood": { "type": "fill", diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index 2d950afe47..0cae687302 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -69,8 +69,6 @@ private: int32_t min_zoom; int32_t max_zoom; - std::shared_ptr<Sprite> sprite; - std::forward_list<Tile::Ptr> tiles; std::forward_list<Tile::Ptr> historic_tiles; }; diff --git a/include/llmr/renderer/bucket.hpp b/include/llmr/renderer/bucket.hpp index 95db9e017d..7ae0d2d008 100644 --- a/include/llmr/renderer/bucket.hpp +++ b/include/llmr/renderer/bucket.hpp @@ -2,6 +2,7 @@ #define LLMR_RENDERER_BUCKET #include <string> +#include <llmr/map/tile.hpp> namespace llmr { @@ -10,7 +11,7 @@ class Painter; class Bucket { public: Bucket() = default; - virtual void render(Painter& painter, const std::string& layer_name) = 0; + virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id) = 0; private: // Make noncopyable diff --git a/include/llmr/renderer/fill_bucket.hpp b/include/llmr/renderer/fill_bucket.hpp index 32d8bc3218..bf1dd47cb4 100644 --- a/include/llmr/renderer/fill_bucket.hpp +++ b/include/llmr/renderer/fill_bucket.hpp @@ -18,7 +18,7 @@ class FillBucket : public Bucket { public: FillBucket(const std::shared_ptr<FillBuffer>& buffer, const BucketDescription& bucket_desc); - virtual void render(Painter& painter, const std::string& layer_name); + virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id); void addGeometry(pbf& data); void addGeometry(const std::vector<Coordinate>& line); diff --git a/include/llmr/renderer/line_bucket.hpp b/include/llmr/renderer/line_bucket.hpp index 8350dc4b22..4c75fd38f6 100644 --- a/include/llmr/renderer/line_bucket.hpp +++ b/include/llmr/renderer/line_bucket.hpp @@ -17,7 +17,7 @@ class LineBucket : public Bucket { public: LineBucket(const std::shared_ptr<LineBuffer>& buffer, const BucketDescription& bucket_desc); - virtual void render(Painter& painter, const std::string& layer_name); + virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id); void addGeometry(pbf& data); void addGeometry(const std::vector<Coordinate>& line); diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 86d53c1637..dafa61c11d 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -5,6 +5,7 @@ #include "shader-plain.hpp" #include "shader-outline.hpp" #include "shader-line.hpp" +#include "shader-pattern.hpp" #include "../map/tile.hpp" #include "../geometry/vertex_buffer.hpp" @@ -42,8 +43,8 @@ public: void renderMatte(); void renderBackground(); - void renderFill(FillBucket& bucket, const std::string& layer_name); - void renderLine(LineBucket& bucket, const std::string& layer_name); + 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 drawClippingMask(); @@ -68,6 +69,7 @@ private: std::shared_ptr<PlainShader> plainShader; std::shared_ptr<OutlineShader> outlineShader; std::shared_ptr<LineShader> lineShader; + std::shared_ptr<PatternShader> patternShader; // Set up the stencil quad we're using to generate the stencil mask. VertexBuffer tileStencilBuffer = { diff --git a/include/llmr/renderer/shader-pattern.hpp b/include/llmr/renderer/shader-pattern.hpp new file mode 100644 index 0000000000..5b295cfffb --- /dev/null +++ b/include/llmr/renderer/shader-pattern.hpp @@ -0,0 +1,25 @@ +#ifndef LLMR_RENDERER_SHADER_PATTERN +#define LLMR_RENDERER_SHADER_PATTERN + +#include "shader.hpp" + +namespace llmr { + +class PatternShader : public Shader { +public: + PatternShader(); + + int32_t a_pos; + int32_t u_matrix; + int32_t u_color; + int32_t u_offset; + int32_t u_pattern_size; + int32_t u_pattern_tl; + int32_t u_pattern_br; + int32_t u_mix; + +}; + +} + +#endif diff --git a/include/llmr/shader/shaders.hpp b/include/llmr/shader/shaders.hpp index 885f81813e..065b8d47f1 100644 --- a/include/llmr/shader/shaders.hpp +++ b/include/llmr/shader/shaders.hpp @@ -14,6 +14,7 @@ enum { FILL_SHADER, LINE_SHADER, OUTLINE_SHADER, + PATTERN_SHADER, PLAIN_SHADER, SHADER_COUNT }; diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index f0e3cf5079..572ca61acd 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -3,6 +3,7 @@ #include <array> #include <vector> +#include <string> namespace llmr { @@ -87,6 +88,7 @@ struct FillClass { Color fill_color = {{ 0, 0, 0, 1 }}; Color stroke_color = {{ 0, 0, 0, std::numeric_limits<float>::infinity() }}; FunctionProperty<float> opacity = 1; + std::string image; }; struct FillProperties { @@ -96,6 +98,7 @@ struct FillProperties { Color fill_color = {{ 0, 0, 0, 1 }}; Color stroke_color = {{ 0, 0, 0, 1 }}; float opacity = 1.0; + std::string image; }; } diff --git a/include/llmr/style/style.hpp b/include/llmr/style/style.hpp index 80834fa44f..f2acbd1eea 100644 --- a/include/llmr/style/style.hpp +++ b/include/llmr/style/style.hpp @@ -11,6 +11,7 @@ #include "bucket_description.hpp" #include "layer_description.hpp" #include "class_description.hpp" +#include "sprite.hpp" namespace llmr { @@ -37,6 +38,8 @@ private: static Color parseColor(pbf& data); public: + std::shared_ptr<Sprite> sprite; + // This is static information parsed from the stylesheet. std::map<std::string, BucketDescription> buckets; std::vector<LayerDescription> layers; diff --git a/proto/style.proto b/proto/style.proto index 281749c903..8459477bf7 100644 --- a/proto/style.proto +++ b/proto/style.proto @@ -79,6 +79,7 @@ message fill_style { optional fixed32 fill_color = 5 [ default = 0x000000FF ]; // rgba (=> rgb << 8 | 0xFF for opaque!) optional fixed32 stroke_color = 6; // if none is specified, no stroke will be painted optional property opacity = 7; // values from 0..1 + optional string image = 8; // TODO: translate x/y } diff --git a/resources/style.pbf b/resources/style.pbf Binary files differindex 2157505641..e70b6ae2bb 100644 --- a/resources/style.pbf +++ b/resources/style.pbf diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 66fea4cd14..3d805ab3d5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ SET(llmr_SOURCES renderer/shader-plain.cpp renderer/shader-outline.cpp renderer/shader-line.cpp + renderer/shader-pattern.cpp renderer/shader.cpp renderer/fill_bucket.cpp renderer/line_bucket.cpp @@ -46,6 +47,7 @@ SET(llmr_HEADERS ../include/llmr/renderer/shader-plain.hpp ../include/llmr/renderer/shader-outline.hpp ../include/llmr/renderer/shader-line.hpp + ../include/llmr/renderer/shader-pattern.hpp ../include/llmr/renderer/shader.hpp ../include/llmr/shader/shaders.hpp ../include/llmr/util/animation.hpp diff --git a/src/map/map.cpp b/src/map/map.cpp index db48054624..341f7f7197 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -21,8 +21,9 @@ Map::Map(Settings& settings) min_zoom(0), max_zoom(14) { - sprite = std::make_shared<Sprite>(); - sprite->load("http://localhost:3333/gl/debug/img/sprite"); + // TODO: Extract that information from the stylesheet instead of hard coding + style.sprite = std::make_shared<Sprite>(); + style.sprite->load("http://localhost:3333/gl/debug/img/sprite"); } Map::~Map() { diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp index 13de7edf88..4e20620aa5 100644 --- a/src/renderer/fill_bucket.cpp +++ b/src/renderer/fill_bucket.cpp @@ -116,8 +116,8 @@ void FillBucket::drawVertices(int32_t attrib) { glDrawArrays(GL_LINE_STRIP, 0, length); } -void FillBucket::render(Painter& painter, const std::string& layer_name) { - painter.renderFill(*this, layer_name); +void FillBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) { + painter.renderFill(*this, layer_name, id); } uint32_t FillBucket::size() const { diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp index 964e7879f5..51178ffd49 100644 --- a/src/renderer/line_bucket.cpp +++ b/src/renderer/line_bucket.cpp @@ -259,8 +259,8 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) { length = buffer->length() - start; } -void LineBucket::render(Painter& painter, const std::string& layer_name) { - painter.renderLine(*this, layer_name); +void LineBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) { + painter.renderLine(*this, layer_name, id); } uint32_t LineBucket::size() const { diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 35224ab837..cb33964fc8 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -35,6 +35,7 @@ void Painter::setup() { assert(plainShader); assert(outlineShader); assert(lineShader); + assert(patternShader); glEnable(GL_STENCIL_TEST); @@ -49,6 +50,7 @@ void Painter::setupShaders() { plainShader = std::make_shared<PlainShader>(); outlineShader = std::make_shared<OutlineShader>(); lineShader = std::make_shared<LineShader>(); + patternShader = std::make_shared<PatternShader>(); } void Painter::changeMatrix(const Tile::ID& id) { @@ -146,13 +148,13 @@ void Painter::renderLayers(const std::shared_ptr<Tile>& tile, const std::vector< auto bucket_it = tile->buckets.find(layer_desc.bucket_name); if (bucket_it != tile->buckets.end()) { assert(bucket_it->second); - bucket_it->second->render(*this, layer_desc.name); + bucket_it->second->render(*this, layer_desc.name, tile->id); } } } } -void Painter::renderFill(FillBucket& bucket, const std::string& layer_name) { +void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id) { const FillProperties& properties = style.computed.fills[layer_name]; // Abort early. @@ -238,50 +240,54 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name) { bucket.drawVertices(outlineShader->a_pos); } - // var imagePos = layerStyle.image && imageSprite.getPosition(layerStyle.image, true); - bool imagePos = false; - if (imagePos) { - // // Draw texture fill + // Only draw regions that we marked + glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F); + + if (properties.image.size() && style.sprite) { + // Draw texture fill + ImagePosition imagePos = style.sprite->getPosition(properties.image, true); + + double factor = 8.0 / pow(2, transform.getIntegerZoom() - id.z); + double mix = fmod(transform.getZoom(), 1.0); + vec2<double> imageSize { imagePos.size.x * factor, imagePos.size.y * factor }; + + vec2<double> offset { + fmod(id.x * 4096, imageSize.x), + fmod(id.y * 4096, imageSize.y) + }; + + switchShader(patternShader); + glUniformMatrix4fv(patternShader->u_matrix, 1, GL_FALSE, matrix.data()); + glUniform2f(patternShader->u_pattern_size, imageSize.x, imageSize.y); + glUniform2f(patternShader->u_offset, offset.x, offset.y); + glUniform2f(patternShader->u_pattern_tl, imagePos.tl.x, imagePos.tl.y); + glUniform2f(patternShader->u_pattern_br, imagePos.br.x, imagePos.br.y); + glUniform4fv(patternShader->u_color, 1, fill_color.data()); + glUniform1f(patternShader->u_mix, mix); + style.sprite->bind(true); + + // Draw a rectangle that covers the entire viewport. + tileStencilBuffer.bind(); + glVertexAttribPointer(patternShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); + glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); - // var factor = 8 / Math.pow(2, painter.transform.zoom - params.z); - // var mix = painter.transform.z % 1.0; - // var imageSize = [imagePos.size[0] * factor, imagePos.size[1] * factor]; - - // var offset = [ - // (params.x * 4096) % imageSize[0], - // (params.y * 4096) % imageSize[1] - // ]; - - // glSwitchShader(painter.patternShader, painter.posMatrix, painter.exMatrix); - // glUniform1i(painter.patternShader.u_image, 0); - // glUniform2fv(painter.patternShader.u_pattern_size, imageSize); - // glUniform2fv(painter.patternShader.u_offset, offset); - // glUniform2fv(painter.patternShader.u_rotate, [1, 1]); - // glUniform2fv(painter.patternShader.u_pattern_tl, imagePos.tl); - // glUniform2fv(painter.patternShader.u_pattern_br, imagePos.br); - // glUniform4fv(painter.patternShader.u_color, color); - // glUniform1f(painter.patternShader.u_mix, mix); - // imageSprite.bind(gl, true); } else { // Draw filling rectangle. switchShader(fillShader); glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data()); glUniform4fv(fillShader->u_color, 1, fill_color.data()); - } - // Only draw regions that we marked - glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F); - - // Draw a rectangle that covers the entire viewport. - tileStencilBuffer.bind(); - glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); + // Draw a rectangle that covers the entire viewport. + tileStencilBuffer.bind(); + glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); + glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); + } glStencilMask(0x00); glStencilFunc(GL_EQUAL, 0x80, 0x80); } -void Painter::renderLine(LineBucket& bucket, const std::string& layer_name) { +void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& id) { const LineProperties& properties = style.computed.lines[layer_name]; // Abort early. diff --git a/src/renderer/shader-pattern.cpp b/src/renderer/shader-pattern.cpp new file mode 100644 index 0000000000..4a921c665b --- /dev/null +++ b/src/renderer/shader-pattern.cpp @@ -0,0 +1,27 @@ +#include <llmr/renderer/shader-pattern.hpp> +#include <llmr/shader/shaders.hpp> +#include <llmr/platform/gl.hpp> + +using namespace llmr; + +PatternShader::PatternShader() + : Shader( + shaders[PATTERN_SHADER].vertex, + shaders[PATTERN_SHADER].fragment + ) { + if (!valid) { + fprintf(stderr, "invalid pattern shader\n"); + return; + } + + a_pos = glGetAttribLocation(program, "a_pos"); + attributes.emplace_front(a_pos); + + u_matrix = glGetUniformLocation(program, "u_matrix"); + u_color = glGetUniformLocation(program, "u_color"); + u_offset = glGetUniformLocation(program, "u_offset"); + u_pattern_size = glGetUniformLocation(program, "u_pattern_size"); + u_pattern_tl = glGetUniformLocation(program, "u_pattern_tl"); + u_pattern_br = glGetUniformLocation(program, "u_pattern_br"); + u_mix = glGetUniformLocation(program, "u_mix"); +} diff --git a/src/shader/pattern.fragment.glsl b/src/shader/pattern.fragment.glsl new file mode 100644 index 0000000000..850c7afaff --- /dev/null +++ b/src/shader/pattern.fragment.glsl @@ -0,0 +1,26 @@ +uniform vec4 u_color; + +uniform vec2 u_offset; +uniform vec2 u_pattern_size; +uniform vec2 u_pattern_tl; +uniform vec2 u_pattern_br; +uniform float u_mix; + + +uniform sampler2D u_image; + +varying vec2 v_pos; + +void main() { + + vec2 imagecoord = mod((v_pos + u_offset) / u_pattern_size, 1.0); + vec2 pos = mix(u_pattern_tl, u_pattern_br, imagecoord); + vec4 color1 = texture2D(u_image, pos); + + vec2 imagecoord2 = mod(imagecoord * 2.0, 1.0); + vec2 pos2 = mix(u_pattern_tl, u_pattern_br, imagecoord2); + vec4 color2 = texture2D(u_image, pos2); + + vec4 color = mix(color1, color2, u_mix); + gl_FragColor = color + u_color * (1.0 - color.a); +} diff --git a/src/shader/pattern.vertex.glsl b/src/shader/pattern.vertex.glsl new file mode 100644 index 0000000000..eeee39930f --- /dev/null +++ b/src/shader/pattern.vertex.glsl @@ -0,0 +1,10 @@ +uniform mat4 u_matrix; + +attribute vec2 a_pos; + +varying vec2 v_pos; + +void main() { + v_pos = a_pos; + gl_Position = u_matrix * vec4(a_pos, 0, 1); +} diff --git a/src/shader/shaders.cpp b/src/shader/shaders.cpp index 1b57bb68da..cd7222b3e1 100644 --- a/src/shader/shaders.cpp +++ b/src/shader/shaders.cpp @@ -10,12 +10,16 @@ const shader_source llmr::shaders[SHADER_COUNT] = { }, [LINE_SHADER] = { .vertex = "// these are the shaders for rendering antialiased lines\n\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\nattribute vec2 a_pos;\nattribute vec2 a_extrude;\nattribute float a_linesofar;\n\n// matrix 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\nuniform float u_debug;\n\n// shared\nuniform float u_ratio;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\nuniform float u_point;\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 vec2 extrude = a_extrude / scale;\n vec2 dist = u_linewidth.s * extrude * (1.0 - u_point);\n\n // If the x coordinate is the maximum integer, we move the z coordinates out\n // of the view plane so that the triangle gets clipped. This makes it easier\n // for us to create degenerate triangle strips.\n float z = step(32767.0, a_pos.x);\n\n // When drawing points, skip every other vertex\n z += u_point * step(1.0, v_normal.y);\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 / 2.0), 0.0, 1.0) + u_exmatrix * vec4(dist, z, 0.0);\n v_linesofar = a_linesofar * u_ratio;\n\n\n gl_PointSize = 2.0 * u_linewidth.s - 1.0;\n}\n", - .fragment = "#version 120\n// shared\nuniform float u_debug;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\nuniform float u_point;\nuniform float u_gamma;\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) * (1.0 - u_point) + u_point * length(gl_PointCoord * 2.0 - 1.0);\n\n dist *= 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) * u_gamma, 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\n if (u_debug > 0.0) {\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n }\n}\n", + .fragment = "#version 120\n\n// shared\nuniform float u_debug;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\nuniform float u_point;\nuniform float u_gamma;\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) * (1.0 - u_point) + u_point * length(gl_PointCoord * 2.0 - 1.0);\n\n dist *= 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) * u_gamma, 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\n if (u_debug > 0.0) {\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n }\n}\n", }, [OUTLINE_SHADER] = { .vertex = "attribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform vec2 u_world;\n\nvarying vec2 v_pos;\n\nvoid main() {\n // If the x coordinate is the maximum integer, we move the z coordinates out\n // of the view plane so that the triangle gets clipped. This makes it easier\n // for us to create degenerate triangle strips.\n float z = step(32767.0, a_pos.x) * 2.0;\n gl_Position = u_matrix * vec4(a_pos, z, 1);\n\n v_pos = (gl_Position.xy + 1.0) / 2.0 * u_world;\n}\n", .fragment = "uniform 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", }, + [PATTERN_SHADER] = { + .vertex = "uniform 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", + .fragment = "uniform 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", + }, [PLAIN_SHADER] = { .vertex = "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n float z = step(32767.0, a_pos.x) * 2.0;\n gl_Position = u_matrix * vec4(a_pos, z, 1);\n}\n", .fragment = "uniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n", diff --git a/src/style/resources.cpp b/src/style/resources.cpp index cfdc0d7ce7..0c45e59c5d 100644 --- a/src/style/resources.cpp +++ b/src/style/resources.cpp @@ -47,27 +47,27 @@ const unsigned char resources::style[] = { 12, 114, 111, 97, 100, 95, 114, 101, 103, 117, 108, 97, 114, 18, 24, 10, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 18, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 18, 18, 10, 7, 97, 108, 99, 111, 104, - 111, 108, 18, 7, 97, 108, 99, 111, 104, 111, 108, 26, 197, 2, 10, 7, - 100, 101, 102, 97, 117, 108, 116, 18, 21, 10, 4, 112, 97, 114, 107, 34, - 8, 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 159, 223, 200, 18, 31, - 10, 4, 119, 111, 111, 100, 34, 8, 8, 2, 18, 4, 0, 0, 128, 63, - 45, 255, 102, 170, 51, 58, 8, 8, 2, 18, 4, 205, 204, 204, 61, 18, - 22, 10, 5, 119, 97, 116, 101, 114, 34, 8, 8, 2, 18, 4, 0, 0, - 128, 63, 45, 255, 230, 182, 115, 18, 51, 10, 8, 98, 117, 105, 108, 100, - 105, 110, 103, 34, 8, 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 0, - 0, 0, 58, 24, 8, 4, 18, 20, 0, 0, 80, 65, 0, 0, 0, 0, - 205, 204, 204, 61, 0, 0, 0, 0, 205, 204, 204, 61, 26, 41, 10, 12, - 114, 111, 97, 100, 95, 108, 105, 109, 105, 116, 101, 100, 29, 255, 187, 187, - 187, 34, 20, 8, 3, 18, 16, 0, 0, 0, 0, 0, 0, 128, 63, 0, - 0, 240, 65, 0, 0, 128, 63, 26, 65, 10, 12, 114, 111, 97, 100, 95, - 114, 101, 103, 117, 108, 97, 114, 29, 255, 153, 153, 153, 34, 44, 8, 3, - 18, 40, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 80, 65, 0, 0, - 0, 63, 0, 0, 128, 65, 0, 0, 0, 64, 0, 0, 160, 65, 0, 0, - 0, 66, 0, 0, 240, 65, 0, 0, 0, 66, 26, 71, 10, 10, 114, 111, - 97, 100, 95, 108, 97, 114, 103, 101, 29, 255, 102, 102, 102, 34, 52, 8, - 3, 18, 48, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 48, 65, 0, - 0, 0, 63, 0, 0, 80, 65, 0, 0, 128, 63, 0, 0, 128, 65, 0, - 0, 128, 64, 0, 0, 160, 65, 0, 0, 128, 66, 0, 0, 240, 65, 0, - 0, 128, 66 + 111, 108, 18, 7, 97, 108, 99, 111, 104, 111, 108, 26, 203, 2, 10, 7, + 100, 101, 102, 97, 117, 108, 116, 18, 27, 10, 4, 112, 97, 114, 107, 34, + 8, 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 159, 223, 200, 66, 4, + 112, 97, 114, 107, 18, 31, 10, 4, 119, 111, 111, 100, 34, 8, 8, 2, + 18, 4, 0, 0, 128, 63, 45, 255, 102, 170, 51, 58, 8, 8, 2, 18, + 4, 205, 204, 204, 61, 18, 22, 10, 5, 119, 97, 116, 101, 114, 34, 8, + 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 230, 182, 115, 18, 51, 10, + 8, 98, 117, 105, 108, 100, 105, 110, 103, 34, 8, 8, 2, 18, 4, 0, + 0, 128, 63, 45, 255, 0, 0, 0, 58, 24, 8, 4, 18, 20, 0, 0, + 80, 65, 0, 0, 0, 0, 205, 204, 204, 61, 0, 0, 0, 0, 205, 204, + 204, 61, 26, 41, 10, 12, 114, 111, 97, 100, 95, 108, 105, 109, 105, 116, + 101, 100, 29, 255, 187, 187, 187, 34, 20, 8, 3, 18, 16, 0, 0, 0, + 0, 0, 0, 128, 63, 0, 0, 240, 65, 0, 0, 128, 63, 26, 65, 10, + 12, 114, 111, 97, 100, 95, 114, 101, 103, 117, 108, 97, 114, 29, 255, 153, + 153, 153, 34, 44, 8, 3, 18, 40, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 80, 65, 0, 0, 0, 63, 0, 0, 128, 65, 0, 0, 0, 64, + 0, 0, 160, 65, 0, 0, 0, 66, 0, 0, 240, 65, 0, 0, 0, 66, + 26, 71, 10, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 29, 255, + 102, 102, 102, 34, 52, 8, 3, 18, 48, 0, 0, 0, 0, 0, 0, 0, + 63, 0, 0, 48, 65, 0, 0, 0, 63, 0, 0, 80, 65, 0, 0, 128, + 63, 0, 0, 128, 65, 0, 0, 128, 64, 0, 0, 160, 65, 0, 0, 128, + 66, 0, 0, 240, 65, 0, 0, 128, 66 }; const unsigned long resources::style_size = sizeof(resources::style); diff --git a/src/style/style.cpp b/src/style/style.cpp index fd8d7e8bd5..85c85b979c 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -123,6 +123,8 @@ std::pair<std::string, FillClass> Style::parseFillClass(pbf data) { fill.stroke_color = parseColor(data); } else if (data.tag == 7) { // opacity fill.opacity = parseProperty<float>(data.message()); + } else if (data.tag == 8) { // image + fill.image = data.string(); } else { data.skip(); } @@ -221,6 +223,7 @@ void Style::cascade(float z) { fill.fill_color = layer.fill_color; fill.stroke_color = layer.stroke_color; fill.opacity = layer.opacity(z); + fill.image = layer.image; } // Cascade line classes |