textured fills

fixes #15
This commit is contained in:
Konstantin Käfer
2014-02-03 22:51:21 +01:00
parent e478ae2a2d
commit 9ab9eeec13
24 changed files with 187 additions and 69 deletions

View File

@@ -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;
}

View File

@@ -82,7 +82,8 @@ module.exports = {
"park": {
"type": "fill",
"color": "#c8df9f",
"antialias": true
"antialias": true,
"image": "park"
},
"wood": {
"type": "fill",

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 = {

View File

@@ -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

View File

@@ -14,6 +14,7 @@ enum {
FILL_SHADER,
LINE_SHADER,
OUTLINE_SHADER,
PATTERN_SHADER,
PLAIN_SHADER,
SHADER_COUNT
};

View File

@@ -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;
};
}

View File

@@ -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;

View File

@@ -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
}

Binary file not shown.

View File

@@ -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

View File

@@ -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() {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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);
// 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];
if (properties.image.size() && style.sprite) {
// Draw texture fill
ImagePosition imagePos = style.sprite->getPosition(properties.image, true);
// var offset = [
// (params.x * 4096) % imageSize[0],
// (params.y * 4096) % imageSize[1]
// ];
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());
// 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());
// 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());
}
// 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());
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.

View File

@@ -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");
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

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

View File

@@ -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);

View File

@@ -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