optimizations + reorder vertex index

This commit is contained in:
Konstantin Käfer
2014-02-13 14:10:04 +01:00
parent 1a05832a93
commit 54454ed66a
19 changed files with 166 additions and 63 deletions

View File

@@ -43,6 +43,9 @@ private:
void renderLayers(const std::shared_ptr<Tile>& tile, const std::vector<LayerDescription>& layers);
void renderDebug(const std::shared_ptr<Tile>& tile);
void useProgram(uint32_t program);
void lineWidth(float lineWidth);
private:
Transform& transform;
Settings& settings;
@@ -52,6 +55,9 @@ private:
mat4 matrix;
mat4 exMatrix;
uint32_t gl_program = 0;
float gl_lineWidth = 0;
std::unique_ptr<PlainShader> plainShader;
std::unique_ptr<OutlineShader> outlineShader;
std::unique_ptr<LineShader> lineShader;

View File

@@ -13,9 +13,8 @@ public:
int32_t a_pos;
int32_t a_extrude;
int32_t a_linesofar;
// int32_t a_linesofar;
int32_t u_matrix;
int32_t u_exmatrix;
int32_t u_linewidth;
int32_t u_color;

View File

@@ -13,7 +13,6 @@ public:
int32_t a_pos;
int32_t u_matrix;
int32_t u_world;
int32_t u_linewidth;
int32_t u_color;

View File

@@ -11,9 +11,15 @@ public:
void bind(char *offset);
void setColor(const std::array<float, 4>& color);
void setWorld(const std::array<float, 2>& world);
private:
int32_t a_pos;
int32_t u_matrix;
std::array<float, 4> color;
int32_t u_color;
std::array<float, 2> world;
int32_t u_world;
};

View File

@@ -12,7 +12,6 @@ public:
void bind(char *offset);
int32_t a_pos;
int32_t u_matrix;
int32_t u_color;
int32_t u_offset;
int32_t u_pattern_size;

View File

@@ -11,8 +11,13 @@ public:
void bind(char *offset);
void setColor(float r, float g, float b, float a);
void setColor(const std::array<float, 4>& color);
private:
int32_t a_pos;
int32_t u_matrix;
std::array<float, 4> color;
int32_t u_color;
};

View File

@@ -3,6 +3,7 @@
#include <cstdint>
#include <llmr/util/noncopyable.hpp>
#include <llmr/util/mat4.hpp>
namespace llmr {
@@ -13,8 +14,14 @@ public:
bool valid;
uint32_t program;
void setMatrix(const mat4& matrix);
private:
bool compileShader(uint32_t *shader, uint32_t type, const char *source);
protected:
int32_t u_matrix;
mat4 matrix;
};
}

View File

@@ -12,11 +12,12 @@ size_t LineVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey, i
int16_t *coords = static_cast<int16_t *>(data);
coords[0] = (x * 2) | tx;
coords[1] = (y * 2) | ty;
coords[2] = linesofar;
int8_t *extrude = static_cast<int8_t *>(data);
extrude[6] = round(extrudeScale * ex);
extrude[7] = round(extrudeScale * ey);
extrude[4] = round(extrudeScale * ex);
extrude[5] = round(extrudeScale * ey);
coords[3] = linesofar;
return idx;
}

View File

@@ -109,14 +109,14 @@ void FillBucket::drawElements(PlainShader& shader) {
for (group_type& group : groups) {
group.array.bind(shader, *vertexBuffer, *elementsBuffer, 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);
vertex_index += group.vertex_length * vertexBuffer->itemSize;
elements_index += group.elements_length * elementsBuffer->itemSize;
}
}
void FillBucket::drawVertices(OutlineShader& shader) {
// Draw the entire line
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize);
array.bind(shader, *vertexBuffer, vertex_index);
glDrawArrays(GL_LINE_STRIP, 0, length);
}

View File

@@ -41,6 +41,9 @@ void Painter::setup() {
// draw front-to-back and use then stencil buffer to cull opaque pixels early.
glEnable(GL_BLEND);
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearStencil(0x0);
}
void Painter::setupShaders() {
@@ -51,6 +54,20 @@ void Painter::setupShaders() {
patternShader = std::make_unique<PatternShader>();
}
void Painter::useProgram(uint32_t program) {
if (gl_program != program) {
glUseProgram(program);
gl_program = program;
}
}
void Painter::lineWidth(float lineWidth) {
if (gl_lineWidth != lineWidth) {
glLineWidth(lineWidth);
gl_lineWidth = lineWidth;
}
}
void Painter::changeMatrix(const Tile::ID& id) {
// Initialize projection matrix
mat4 projMatrix;
@@ -73,15 +90,14 @@ void Painter::changeMatrix(const Tile::ID& id) {
}
void Painter::drawClippingMask() {
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
useProgram(plainShader->program);
plainShader->setMatrix(matrix);
glColorMask(false, false, false, false);
// Clear the entire stencil buffer, except for the 7th bit, which stores
// the global clipping mask that allows us to avoid drawing in regions of
// tiles we've already painted in.
glClearStencil(0x0);
glStencilMask(0xBF);
glClear(GL_STENCIL_BUFFER_BIT);
@@ -97,7 +113,7 @@ void Painter::drawClippingMask() {
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
// Draw the clipping mask
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 1.0f, 1.0f);
plainShader->setColor(1.0f, 0.0f, 1.0f, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index());
// glEnable(GL_STENCIL_TEST);
@@ -108,8 +124,6 @@ void Painter::drawClippingMask() {
}
void Painter::clear() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearStencil(0x0);
glStencilMask(0xFF);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
@@ -195,8 +209,8 @@ 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(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
useProgram(plainShader->program);
plainShader->setMatrix(matrix);
// Draw all groups
bucket.drawElements(*plainShader);
@@ -213,16 +227,16 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
// Because we're drawing top-to-bottom, and we update the stencil mask
// below, we have to draw the outline first (!)
if (properties.antialias) {
glUseProgram(outlineShader->program);
glUniformMatrix4fv(outlineShader->u_matrix, 1, GL_FALSE, matrix.data());
glLineWidth(2.0f); // This is always fixed and does not depend on the pixelRatio!
useProgram(outlineShader->program);
outlineShader->setMatrix(matrix);
lineWidth(2.0f); // This is always fixed and does not depend on the pixelRatio!
if (properties.stroke_color != properties.fill_color) {
// If we defined a different color for the fill outline, we are
// going to ignore the bits in 0x3F and just care about the global
// clipping mask.
glStencilFunc(GL_EQUAL, 0x80, 0x80);
glUniform4fv(outlineShader->u_color, 1, properties.stroke_color.data());
outlineShader->setColor(properties.stroke_color);
} else {
// Otherwise, we only want to draw the antialiased parts that are
// *outside* the current shape. This is important in case the fill
@@ -230,18 +244,18 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
// the current shape, some pixels from the outline stroke overlapped
// the (non-antialiased) fill.
glStencilFunc(GL_EQUAL, 0x80, 0xBF);
glUniform4fv(outlineShader->u_color, 1, fill_color.data());
outlineShader->setColor(fill_color);
}
// Draw the entire line
glUniform2f(outlineShader->u_world, transform.fb_width, transform.fb_height);
outlineShader->setWorld({{ (float)transform.fb_width, (float)transform.fb_height }});
bucket.drawVertices(*outlineShader);
}
// Only draw regions that we marked
glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F);
if (properties.image.size() && style.sprite) {
if (properties.image.size() && *style.sprite) {
// Draw texture fill
ImagePosition imagePos = style.sprite->getPosition(properties.image, true);
@@ -254,8 +268,8 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
fmod(id.y * 4096, imageSize.y)
};
glUseProgram(patternShader->program);
glUniformMatrix4fv(patternShader->u_matrix, 1, GL_FALSE, matrix.data());
useProgram(patternShader->program);
patternShader->setMatrix(matrix);
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);
@@ -270,16 +284,15 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
} else {
// Draw filling rectangle.
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
glUniform4fv(plainShader->u_color, 1, fill_color.data());
useProgram(plainShader->program);
plainShader->setMatrix(matrix);
plainShader->setColor(fill_color);
// Draw a rectangle that covers the entire viewport.
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index());
}
glStencilMask(0x00);
glStencilFunc(GL_EQUAL, 0x80, 0x80);
}
@@ -306,8 +319,8 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
// We're only drawing end caps + round line joins if the line is > 2px. Otherwise, they aren't visible anyway.
if (bucket.hasPoints() && outset > 1.0f) {
glUseProgram(linejoinShader->program);
glUniformMatrix4fv(linejoinShader->u_matrix, 1, GL_FALSE, matrix.data());
useProgram(linejoinShader->program);
linejoinShader->setMatrix(matrix);
glUniform4fv(linejoinShader->u_color, 1, color.data());
glUniform2f(linejoinShader->u_world, transform.fb_width / 2, transform.fb_height / 2);
glUniform2f(linejoinShader->u_linewidth, (outset - 0.25) * transform.pixelRatio, (inset - 0.25) * transform.pixelRatio);
@@ -337,8 +350,8 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
// glUniform1f(painter.linepatternShader.u_fade, painter.transform.z % 1.0);
} else {
glUseProgram(lineShader->program);
glUniformMatrix4fv(lineShader->u_matrix, 1, GL_FALSE, matrix.data());
useProgram(lineShader->program);
lineShader->setMatrix(matrix);
glUniformMatrix4fv(lineShader->u_exmatrix, 1, GL_FALSE, exMatrix.data());
// TODO: Move this to transform?
@@ -356,22 +369,22 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
void Painter::renderDebug(const Tile::Ptr& tile) {
// Blend to the front, not the back.
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
useProgram(plainShader->program);
plainShader->setMatrix(matrix);
// draw tile outline
tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0));
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 0.0f, 1.0f);
glLineWidth(4.0f * transform.pixelRatio);
plainShader->setColor(1.0f, 0.0f, 0.0f, 1.0f);
lineWidth(4.0f * transform.pixelRatio);
glDrawArrays(GL_LINE_STRIP, 0, tileBorderBuffer.index());
// draw debug info
tile->debugFontArray.bind(*plainShader, tile->debugFontBuffer, BUFFER_OFFSET(0));
glUniform4f(plainShader->u_color, 1.0f, 1.0f, 1.0f, 1.0f);
glLineWidth(4.0f * transform.pixelRatio);
plainShader->setColor(1.0f, 1.0f, 1.0f, 1.0f);
lineWidth(4.0f * transform.pixelRatio);
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.index());
glUniform4f(plainShader->u_color, 0.0f, 0.0f, 0.0f, 1.0f);
glLineWidth(2.0f * transform.pixelRatio);
plainShader->setColor(0.0f, 0.0f, 0.0f, 1.0f);
lineWidth(2.0f * transform.pixelRatio);
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.index());
// Revert blending mode to blend to the back.
@@ -383,12 +396,12 @@ void Painter::renderMatte() {
Color white = {{ 0.9, 0.9, 0.9, 1 }};
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, nativeMatrix.data());
useProgram(plainShader->program);
plainShader->setMatrix(nativeMatrix);
// Draw the clipping mask
matteArray.bind(*plainShader, matteBuffer, BUFFER_OFFSET(0));
glUniform4fv(plainShader->u_color, 1, white.data());
plainShader->setColor(white);
glDrawArrays(GL_TRIANGLES, 0, matteBuffer.index());
glEnable(GL_STENCIL_TEST);
@@ -397,11 +410,11 @@ void Painter::renderMatte() {
void Painter::renderBackground() {
Color white = {{ 1, 1, 1, 1 }};
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
useProgram(plainShader->program);
plainShader->setMatrix(matrix);
// Draw the clipping mask
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
glUniform4fv(plainShader->u_color, 1, white.data());
plainShader->setColor(white);
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index());
}

View File

@@ -18,7 +18,7 @@ LineShader::LineShader()
a_pos = glGetAttribLocation(program, "a_pos");
a_extrude = glGetAttribLocation(program, "a_extrude");
a_linesofar = glGetAttribLocation(program, "a_linesofar");
// a_linesofar = glGetAttribLocation(program, "a_linesofar");
u_matrix = glGetUniformLocation(program, "u_matrix");
u_exmatrix = glGetUniformLocation(program, "u_exmatrix");
@@ -27,15 +27,24 @@ LineShader::LineShader()
u_ratio = glGetUniformLocation(program, "u_ratio");
u_dasharray = glGetUniformLocation(program, "u_dasharray");
u_debug = glGetUniformLocation(program, "u_debug");
// fprintf(stderr, "LineShader:\n");
// fprintf(stderr, " - u_matrix: %d\n", u_matrix);
// fprintf(stderr, " - u_exmatrix: %d\n", u_exmatrix);
// fprintf(stderr, " - u_linewidth: %d\n", u_linewidth);
// fprintf(stderr, " - u_color: %d\n", u_color);
// fprintf(stderr, " - u_ratio: %d\n", u_ratio);
// fprintf(stderr, " - u_dasharray: %d\n", u_dasharray);
// fprintf(stderr, " - u_debug: %d\n", u_debug);
}
void LineShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset);
glEnableVertexAttribArray(a_linesofar);
glVertexAttribPointer(a_linesofar, 1, GL_SHORT, false, 8, offset + 4);
// glEnableVertexAttribArray(a_linesofar);
// glVertexAttribPointer(a_linesofar, 1, GL_SHORT, false, 8, offset + 6);
glEnableVertexAttribArray(a_extrude);
glVertexAttribPointer(a_extrude, 2, GL_BYTE, false, 8, offset + 6);
glVertexAttribPointer(a_extrude, 2, GL_BYTE, false, 8, offset + 4);
}

View File

@@ -23,6 +23,13 @@ LinejoinShader::LinejoinShader()
u_linewidth = glGetUniformLocation(program, "u_linewidth");
u_color = glGetUniformLocation(program, "u_color");
u_size = glGetUniformLocation(program, "u_size");
// fprintf(stderr, "LinejoinShader:\n");
// fprintf(stderr, " - u_matrix: %d\n", u_matrix);
// fprintf(stderr, " - u_world: %d\n", u_world);
// fprintf(stderr, " - u_linewidth: %d\n", u_linewidth);
// fprintf(stderr, " - u_color: %d\n", u_color);
// fprintf(stderr, " - u_size: %d\n", u_size);
}
void LinejoinShader::bind(char *offset) {

View File

@@ -21,9 +21,28 @@ OutlineShader::OutlineShader()
u_matrix = glGetUniformLocation(program, "u_matrix");
u_color = glGetUniformLocation(program, "u_color");
u_world = glGetUniformLocation(program, "u_world");
// fprintf(stderr, "OutlineShader:\n");
// fprintf(stderr, " - u_matrix: %d\n", u_matrix);
// fprintf(stderr, " - u_color: %d\n", u_color);
// fprintf(stderr, " - u_world: %d\n", u_world);
}
void OutlineShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}
void OutlineShader::setColor(const std::array<float, 4>& new_color) {
if (color != new_color) {
glUniform4fv(u_color, 1, new_color.data());
color = new_color;
}
}
void OutlineShader::setWorld(const std::array<float, 2>& new_world) {
if (world != new_world) {
glUniform2fv(u_world, 1, new_world.data());
world = new_world;
}
}

View File

@@ -25,6 +25,15 @@ PatternShader::PatternShader()
u_pattern_tl = glGetUniformLocation(program, "u_pattern_tl");
u_pattern_br = glGetUniformLocation(program, "u_pattern_br");
u_mix = glGetUniformLocation(program, "u_mix");
// fprintf(stderr, "PatternShader:\n");
// fprintf(stderr, " - u_matrix: %d\n", u_matrix);
// fprintf(stderr, " - u_color: %d\n", u_color);
// fprintf(stderr, " - u_offset: %d\n", u_offset);
// fprintf(stderr, " - u_pattern_size: %d\n", u_pattern_size);
// fprintf(stderr, " - u_pattern_tl: %d\n", u_pattern_tl);
// fprintf(stderr, " - u_pattern_br: %d\n", u_pattern_br);
// fprintf(stderr, " - u_mix: %d\n", u_mix);
}
void PatternShader::bind(char *offset) {

View File

@@ -20,9 +20,24 @@ PlainShader::PlainShader()
u_matrix = glGetUniformLocation(program, "u_matrix");
u_color = glGetUniformLocation(program, "u_color");
// fprintf(stderr, "PlainShader:\n");
// fprintf(stderr, " - u_matrix: %d\n", u_matrix);
// fprintf(stderr, " - u_color: %d\n", u_color);
}
void PlainShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}
void PlainShader::setColor(const std::array<float, 4>& new_color) {
if (color != new_color) {
glUniform4fv(u_color, 1, new_color.data());
color = new_color;
}
}
void PlainShader::setColor(float r, float g, float b, float a) {
setColor({{ r, g, b, a }});
}

View File

@@ -142,6 +142,15 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) {
return true;
}
void Shader::setMatrix(const mat4& newMatrix) {
if (matrix != newMatrix) {
glUniformMatrix4fv(u_matrix, 1, GL_FALSE, newMatrix.data());
matrix = newMatrix;
}
}
Shader::~Shader() {
if (program) {
glDeleteProgram(program);

View File

@@ -5,7 +5,7 @@ uniform vec4 u_color;
uniform vec2 u_dasharray;
varying vec2 v_normal;
varying float v_linesofar;
// varying float v_linesofar;
void main() {
// Calculate the distance of the pixel from the line in pixels.
@@ -18,8 +18,8 @@ void main() {
// Calculate the antialiasing fade factor based on distance to the dash.
// Only affects alpha when line is dashed
float pos = mod(v_linesofar, u_dasharray.x + u_dasharray.y);
alpha *= max(step(0.0, -u_dasharray.y), clamp(min(pos, u_dasharray.x - pos), 0.0, 1.0));
// float pos = mod(v_linesofar, u_dasharray.x + u_dasharray.y);
// alpha *= max(step(0.0, -u_dasharray.y), clamp(min(pos, u_dasharray.x - pos), 0.0, 1.0));
if (u_debug > 0.0) {
gl_FragColor = u_color;

View File

@@ -8,7 +8,7 @@
attribute vec2 a_pos;
attribute vec2 a_extrude;
attribute float a_linesofar;
// attribute float a_linesofar;
// posmatrix is for the vertex position, exmatrix is for rotating and projecting
// the extrusion vector.
@@ -23,7 +23,7 @@ uniform vec2 u_linewidth;
uniform vec4 u_color;
varying vec2 v_normal;
varying float v_linesofar;
// varying float v_linesofar;
void main() {
// We store the texture normals in the most insignificant bit
@@ -43,7 +43,7 @@ void main() {
// because we're extruding the line in pixel space, regardless of the current
// tile's zoom level.
gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0.0, 1.0) + u_exmatrix * dist;
v_linesofar = a_linesofar * u_ratio;
// v_linesofar = a_linesofar * u_ratio;
gl_PointSize = 8.0;

View File

@@ -5,8 +5,8 @@ using namespace llmr;
const shader_source llmr::shaders[SHADER_COUNT] = {
{
"// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\nattribute vec2 a_pos;\nattribute vec2 a_extrude;\nattribute float a_linesofar;\n\n// posmatrix is for the vertex position, exmatrix is for rotating and projecting\n// the extrusion vector.\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\n\nuniform float u_debug;\n\n// shared\nuniform float u_ratio;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\n\nvarying vec2 v_normal;\nvarying float v_linesofar;\n\nvoid main() {\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n vec4 dist = vec4(u_linewidth.s * a_extrude * scale, 0.0, 0.0);\n\n // Remove the texture normal bit of the position before scaling it with the\n // model/view matrix. Add the extrusion vector *after* the model/view matrix\n // because we're extruding the line in pixel space, regardless of the current\n // tile's zoom level.\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0.0, 1.0) + u_exmatrix * dist;\n v_linesofar = a_linesofar * u_ratio;\n\n gl_PointSize = 8.0;\n\n if (u_debug > 1.5) {\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0.0, 1.0);\n }\n}",
"uniform float u_debug;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\n\nuniform vec2 u_dasharray;\n\nvarying vec2 v_normal;\nvarying float v_linesofar;\n\nvoid main() {\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * u_linewidth.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist), 0.0, 1.0);\n\n // Calculate the antialiasing fade factor based on distance to the dash.\n // Only affects alpha when line is dashed\n float pos = mod(v_linesofar, u_dasharray.x + u_dasharray.y);\n alpha *= max(step(0.0, -u_dasharray.y), clamp(min(pos, u_dasharray.x - pos), 0.0, 1.0));\n\n if (u_debug > 0.0) {\n gl_FragColor = u_color;\n } else {\n gl_FragColor = u_color * alpha;\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#define scale 0.015873016\n\nattribute vec2 a_pos;\nattribute vec2 a_extrude;\n// attribute float a_linesofar;\n\n// posmatrix is for the vertex position, exmatrix is for rotating and projecting\n// the extrusion vector.\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\n\nuniform float u_debug;\n\n// shared\nuniform float u_ratio;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\n\nvarying vec2 v_normal;\n// varying float v_linesofar;\n\nvoid main() {\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n vec4 dist = vec4(u_linewidth.s * a_extrude * scale, 0.0, 0.0);\n\n // Remove the texture normal bit of the position before scaling it with the\n // model/view matrix. Add the extrusion vector *after* the model/view matrix\n // because we're extruding the line in pixel space, regardless of the current\n // tile's zoom level.\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0.0, 1.0) + u_exmatrix * dist;\n // v_linesofar = a_linesofar * u_ratio;\n\n gl_PointSize = 8.0;\n\n if (u_debug > 1.5) {\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0.0, 1.0);\n }\n}",
"uniform float u_debug;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\n\nuniform vec2 u_dasharray;\n\nvarying vec2 v_normal;\n// varying float v_linesofar;\n\nvoid main() {\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * u_linewidth.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist), 0.0, 1.0);\n\n // Calculate the antialiasing fade factor based on distance to the dash.\n // Only affects alpha when line is dashed\n // float pos = mod(v_linesofar, u_dasharray.x + u_dasharray.y);\n // alpha *= max(step(0.0, -u_dasharray.y), clamp(min(pos, u_dasharray.x - pos), 0.0, 1.0));\n\n if (u_debug > 0.0) {\n gl_FragColor = u_color;\n } else {\n gl_FragColor = u_color * alpha;\n }\n}",
},
{
"attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform vec2 u_world;\nuniform float u_size;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(floor(a_pos / 2.0), 0.0, 1.0);\n v_pos = (gl_Position.xy + 1.0) * u_world;\n gl_PointSize = u_size;\n}\n",