textured fills & enforce vao program with templates

This commit is contained in:
Konstantin Käfer
2014-02-05 19:03:44 +01:00
parent eabd99d8f6
commit cf31a80920
24 changed files with 114 additions and 178 deletions

View File

@@ -83,7 +83,7 @@ module.exports = {
"type": "fill",
"color": "#c8df9f",
"antialias": true,
// "image": "park"
"image": "park"
},
"wood": {
"type": "fill",
@@ -96,7 +96,7 @@ module.exports = {
"color": "#bae0e9",
"stroke": "#73b6e6",
"antialias": true,
// "image": "water_etsy"
"image": "water_etsy"
},
"building": {
"type": "fill",

View File

@@ -7,28 +7,26 @@
namespace llmr {
template <typename Shader>
class VertexArrayObject {
public:
template <typename Shader, typename VertexBuffer>
void bind(Shader& shader, VertexBuffer& vertex_buffer, char *vertex_offset) {
template <typename Buffer>
void bind(Shader& shader, Buffer& buffer, char *offset) {
if (!vao) {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
vertex_buffer.bind();
shader.bind_vertex(vertex_offset);
buffer.bind();
shader.bind(offset);
program = shader.program;
buffer = &vertex_buffer;
offset = vertex_offset;
} else if (program != shader.program) {
throw std::runtime_error("trying to bind VAO to different program");
} else if (buffer != &vertex_buffer) {
buffer_ptr = &buffer;
offset_ptr = offset;
} else if (buffer_ptr != &buffer) {
throw std::runtime_error("trying to bind VAO to another buffer");
} else if (offset != vertex_offset) {
} else if (offset_ptr != offset) {
throw std::runtime_error("trying to bind VAO to another offset");
} else {
// This is the correct program for this VAO.
// We have been given the correct information.
glBindVertexArray(vao);
}
}
@@ -44,9 +42,8 @@ private:
// For debug reasons, we're storing the bind information so that we can
// detect errors and report
GLuint program = 0;
void *buffer = NULL;
char *offset = 0;
void *buffer_ptr = NULL;
char *offset_ptr = 0;
};
}

View File

@@ -22,6 +22,7 @@ class VectorTile;
class VectorTileLayer;
class FillBuffer;
class LineBuffer;
class PlainShader;
class Tile : public std::enable_shared_from_this<Tile> {
public:
@@ -73,7 +74,7 @@ public:
// Holds the actual geometries in this tile.
DebugFontBuffer debugFontBuffer;
VertexArrayObject debugFontArray;
VertexArrayObject<PlainShader> debugFontArray;
std::shared_ptr<FillBuffer> fillBuffer;
std::shared_ptr<LineBuffer> lineBuffer;

View File

@@ -18,6 +18,8 @@ namespace llmr {
class Style;
class FillBuffer;
class BucketDescription;
class OutlineShader;
class PlainShader;
struct Coordinate;
struct pbf;
@@ -31,8 +33,8 @@ public:
void addGeometry(const std::vector<Coordinate>& line);
uint32_t size() const;
template <typename Shader> void drawElements(Shader& shader);
template <typename Shader> void drawVertices(Shader& shader);
void drawElements(PlainShader& shader);
void drawVertices(OutlineShader& shader);
public:
const BucketGeometryDescription geom_desc;
@@ -41,7 +43,7 @@ private:
std::shared_ptr<FillBuffer> buffer;
struct group {
VertexArrayObject array;
VertexArrayObject<PlainShader> array;
uint32_t vertex_length;
uint32_t elements_length;
@@ -56,32 +58,10 @@ private:
uint32_t vertex_start;
uint32_t elements_start;
uint32_t length;
VertexArrayObject array;
VertexArrayObject<OutlineShader> array;
std::vector<group> groups;
};
template <typename Shader>
void FillBucket::drawElements(Shader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
char *elements_index = BUFFER_OFFSET(elements_start * 3 * sizeof(int16_t));
for (group& group : groups) {
group.array.bind(shader, *buffer, vertex_index);
glDrawElements(GL_TRIANGLES, group.elements_length * 3 - 3, GL_UNSIGNED_SHORT, elements_index);
vertex_index += group.vertex_length * 2 * sizeof(uint16_t);
elements_index += group.elements_length * 3 * sizeof(uint16_t);
}
}
template <typename Shader>
void FillBucket::drawVertices(Shader& shader) {
// Draw the entire line
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
array.bind(shader, *buffer, vertex_index);
glDrawArrays(GL_LINE_STRIP, 0, length);
}
}
#endif

View File

@@ -37,7 +37,7 @@ private:
std::shared_ptr<LineBuffer> buffer;
uint32_t start;
uint32_t length;
VertexArrayObject array;
VertexArrayObject<LineShader> array;
};
}

View File

@@ -7,7 +7,6 @@
#include <llmr/util/mat4.hpp>
#include <llmr/renderer/shader-plain.hpp>
#include <llmr/renderer/shader-fill.hpp>
#include <llmr/renderer/shader-outline.hpp>
#include <llmr/renderer/shader-pattern.hpp>
#include <llmr/renderer/shader-line.hpp>
@@ -58,7 +57,6 @@ private:
mat4 matrix;
mat4 exMatrix;
std::unique_ptr<FillShader> fillShader;
std::unique_ptr<PlainShader> plainShader;
std::unique_ptr<OutlineShader> outlineShader;
std::unique_ptr<LineShader> lineShader;
@@ -77,7 +75,8 @@ private:
4096, 4096
};
VertexArrayObject tileStencilArray;
VertexArrayObject<PlainShader> coveringPlainArray;
VertexArrayObject<PatternShader> coveringPatternArray;
// Set up the tile boundary lines we're using to draw the tile outlines.
VertexBuffer tileBorderBuffer = {
@@ -88,7 +87,7 @@ private:
0, 0
};
VertexArrayObject tileBorderArray;
VertexArrayObject<PlainShader> tileBorderArray;
// Set up the matte buffer we're using to draw the filling background.
VertexBuffer matteBuffer = {
@@ -103,7 +102,7 @@ private:
16384, 16384
};
VertexArrayObject matteArray;
VertexArrayObject<PlainShader> matteArray;
};
}

View File

@@ -1,21 +0,0 @@
#ifndef LLMR_RENDERER_SHADER_FILL
#define LLMR_RENDERER_SHADER_FILL
#include "shader.hpp"
namespace llmr {
class FillShader : public Shader {
public:
FillShader();
void bind_vertex(char *offset);
int32_t a_pos;
int32_t u_matrix;
int32_t u_color;
};
}
#endif

View File

@@ -9,7 +9,7 @@ class LineShader : public Shader {
public:
LineShader();
void bind_vertex(char *offset);
void bind(char *offset);
int32_t a_pos;
int32_t a_extrude;

View File

@@ -9,7 +9,7 @@ class OutlineShader : public Shader {
public:
OutlineShader();
void bind_vertex(char *offset);
void bind(char *offset);
int32_t a_pos;
int32_t u_matrix;

View File

@@ -9,6 +9,8 @@ class PatternShader : public Shader {
public:
PatternShader();
void bind(char *offset);
int32_t a_pos;
int32_t u_matrix;
int32_t u_color;

View File

@@ -9,7 +9,7 @@ class PlainShader : public Shader {
public:
PlainShader();
void bind_vertex(char *offset);
void bind(char *offset);
int32_t a_pos;
int32_t u_matrix;

View File

@@ -11,7 +11,6 @@ struct shader_source {
};
enum {
FILL_SHADER,
LINE_SHADER,
OUTLINE_SHADER,
PATTERN_SHADER,

Binary file not shown.

View File

@@ -103,3 +103,24 @@ uint32_t FillBucket::size() const {
return length;
}
void FillBucket::drawElements(PlainShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
char *elements_index = BUFFER_OFFSET(elements_start * 3 * sizeof(int16_t));
for (group& group : groups) {
group.array.bind(shader, *buffer, vertex_index);
glDrawElements(GL_TRIANGLES, group.elements_length * 3 - 3, GL_UNSIGNED_SHORT, elements_index);
vertex_index += group.vertex_length * 2 * sizeof(uint16_t);
elements_index += group.elements_length * 3 * sizeof(uint16_t);
}
}
void FillBucket::drawVertices(OutlineShader& shader) {
// Draw the entire line
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
array.bind(shader, *buffer, vertex_index);
glDrawArrays(GL_LINE_STRIP, 0, length);
}

View File

@@ -29,7 +29,6 @@ Painter::Painter(Transform& transform, Settings& settings, Style& style)
void Painter::setup() {
setupShaders();
assert(fillShader);
assert(plainShader);
assert(outlineShader);
assert(lineShader);
@@ -44,7 +43,6 @@ void Painter::setup() {
}
void Painter::setupShaders() {
fillShader = std::make_unique<FillShader>();
plainShader = std::make_unique<PlainShader>();
outlineShader = std::make_unique<OutlineShader>();
lineShader = std::make_unique<LineShader>();
@@ -94,7 +92,7 @@ void Painter::drawClippingMask() {
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
tileStencilArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
// Draw the clipping mask
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 1.0f, 1.0f);
@@ -195,11 +193,11 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
glColorMask(false, false, false, false);
// Draw the actual triangle fan into the stencil buffer.
glUseProgram(fillShader->program);
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data());
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
// Draw all groups
bucket.drawElements(*fillShader);
bucket.drawElements(*plainShader);
// Now that we have the stencil mask in the stencil buffer, we can start
// writing to the color buffer.
@@ -243,42 +241,40 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F);
if (properties.image.size() && style.sprite) {
// TODO:
// // Draw texture fill
// ImagePosition imagePos = style.sprite->getPosition(properties.image, true);
// 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 };
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)
// };
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);
glUseProgram(patternShader->program);
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());
// Draw a rectangle that covers the entire viewport.
coveringPatternArray.bind(*patternShader, tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
} else {
// Draw filling rectangle.
glUseProgram(fillShader->program);
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data());
glUniform4fv(fillShader->u_color, 1, fill_color.data());
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
glUniform4fv(plainShader->u_color, 1, fill_color.data());
// Draw a rectangle that covers the entire viewport.
tileStencilArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
}
@@ -407,7 +403,7 @@ void Painter::renderBackground() {
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
// Draw the clipping mask
tileStencilArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
glUniform4fv(plainShader->u_color, 1, white.data());
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
}

View File

@@ -1,28 +0,0 @@
#include <llmr/renderer/shader-fill.hpp>
#include <llmr/shader/shaders.hpp>
#include <llmr/platform/gl.hpp>
#include <cstdio>
using namespace llmr;
FillShader::FillShader()
: Shader(
shaders[FILL_SHADER].vertex,
shaders[FILL_SHADER].fragment
) {
if (!valid) {
fprintf(stderr, "invalid fill shader\n");
return;
}
a_pos = glGetAttribLocation(program, "a_pos");
u_matrix = glGetUniformLocation(program, "u_matrix");
u_color = glGetUniformLocation(program, "u_color");
}
void FillShader::bind_vertex(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}

View File

@@ -31,7 +31,7 @@ LineShader::LineShader()
u_gamma = glGetUniformLocation(program, "u_gamma");
}
void LineShader::bind_vertex(char *offset) {
void LineShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset);

View File

@@ -23,7 +23,7 @@ OutlineShader::OutlineShader()
u_world = glGetUniformLocation(program, "u_world");
}
void OutlineShader::bind_vertex(char *offset) {
void OutlineShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}

View File

@@ -26,3 +26,8 @@ PatternShader::PatternShader()
u_pattern_br = glGetUniformLocation(program, "u_pattern_br");
u_mix = glGetUniformLocation(program, "u_mix");
}
void PatternShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}

View File

@@ -22,7 +22,7 @@ PlainShader::PlainShader()
u_color = glGetUniformLocation(program, "u_color");
}
void PlainShader::bind_vertex(char *offset) {
void PlainShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}

View File

@@ -1,5 +0,0 @@
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}

View File

@@ -1,7 +0,0 @@
attribute vec2 a_pos;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * vec4(a_pos, 0, 1);
}

View File

@@ -4,10 +4,6 @@
using namespace llmr;
const shader_source llmr::shaders[SHADER_COUNT] = {
{
"attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n",
"uniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n",
},
{
"// 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",
"// 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",

View File

@@ -47,27 +47,28 @@ 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, 202, 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,
27, 10, 5, 119, 97, 116, 101, 114, 34, 8, 8, 2, 18, 4, 0, 0,
128, 63, 45, 255, 233, 224, 186, 53, 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, 220, 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, 39, 10, 5, 119, 97, 116, 101, 114, 34, 8,
8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 233, 224, 186, 53, 255, 230,
182, 115, 66, 10, 119, 97, 116, 101, 114, 95, 101, 116, 115, 121, 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);