summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-01-28 18:40:17 +0100
committerKonstantin Käfer <mail@kkaefer.com>2014-01-28 18:40:17 +0100
commite359d697fbf92f91be78001f922657b8e015948c (patch)
tree6ba5ff241d122c594999ab27bf23a08eff958ecb /src
parent43ab6732d98c0020f28546cbf0377f4b6980f22a (diff)
downloadqtlocation-mapboxgl-e359d697fbf92f91be78001f922657b8e015948c.tar.gz
buggy line support
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/map/map.cpp1
-rw-r--r--src/map/transform.cpp16
-rw-r--r--src/renderer/line_bucket.cpp2
-rw-r--r--src/renderer/painter.cpp79
-rw-r--r--src/renderer/shader-line.cpp33
-rw-r--r--src/renderer/shader.cpp4
-rw-r--r--src/shader/line.fragment.glsl35
-rw-r--r--src/shader/line.vertex.glsl62
-rw-r--r--src/shader/plain.vertex.glsl2
-rw-r--r--src/shader/shaders.cpp6
11 files changed, 223 insertions, 19 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4ae8d7a22a..178d4ce5bc 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,6 +10,7 @@ SET(llmr_SOURCES
renderer/shader-fill.cpp
renderer/shader-plain.cpp
renderer/shader-outline.cpp
+ renderer/shader-line.cpp
renderer/shader.cpp
renderer/fill_bucket.cpp
renderer/line_bucket.cpp
@@ -39,6 +40,7 @@ SET(llmr_HEADERS
../include/llmr/renderer/shader-fill.hpp
../include/llmr/renderer/shader-plain.hpp
../include/llmr/renderer/shader-outline.hpp
+ ../include/llmr/renderer/shader-line.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 2b008c2ccf..8e9c80e509 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -48,6 +48,7 @@ void Map::resize(uint32_t width, uint32_t height, uint32_t fb_width, uint32_t fb
transform.height = height;
transform.fb_width = fb_width;
transform.fb_height = fb_height;
+ transform.pixelRatio = (double)fb_width / (double)width;
update();
}
diff --git a/src/map/transform.cpp b/src/map/transform.cpp
index 7f8d9939d1..023e7c302d 100644
--- a/src/map/transform.cpp
+++ b/src/map/transform.cpp
@@ -1,7 +1,6 @@
#include <llmr/map/transform.hpp>
#include <llmr/util/mat4.hpp>
#include <llmr/util/math.hpp>
-#include <cmath>
#include <cstdio>
using namespace llmr;
@@ -14,16 +13,7 @@ const double M2PI = 2 * M_PI;
const double A = 6378137;
-Transform::Transform()
- :
- width(0),
- height(0),
- x(0),
- y(0),
- angle(0.0),
- scale(1.0),
- min_scale(pow(2, 0)),
- max_scale(pow(2, 20)) {
+Transform::Transform() {
setScale(scale);
setAngle(angle);
}
@@ -168,6 +158,10 @@ float Transform::getZoom() const {
return log(scale) / M_LN2;
}
+int32_t Transform::getIntegerZoom() const {
+ return floor(log(scale) / M_LN2);
+}
+
double Transform::getScale() const {
return scale;
}
diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp
index 96c654f757..f62a299c79 100644
--- a/src/renderer/line_bucket.cpp
+++ b/src/renderer/line_bucket.cpp
@@ -23,6 +23,8 @@ LineBucket::LineBucket(const std::shared_ptr<LineBuffer>& buffer)
}
void LineBucket::addGeometry(pbf& geom, const BucketDescription& bucket_desc) {
+ join = bucket_desc.join;
+
std::vector<Coordinate> line;
Geometry::command cmd;
diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp
index 282cf3e39b..2e7d249225 100644
--- a/src/renderer/painter.cpp
+++ b/src/renderer/painter.cpp
@@ -54,6 +54,7 @@ void Painter::setup() {
assert(fillShader);
assert(plainShader);
assert(outlineShader);
+ assert(lineShader);
// Set up the stencil quad we're using to generate the stencil mask.
glGenBuffers(1, &tile_stencil_buffer);
@@ -78,6 +79,7 @@ void Painter::setupShaders() {
fillShader = std::make_shared<FillShader>();
plainShader = std::make_shared<PlainShader>();
outlineShader = std::make_shared<OutlineShader>();
+ lineShader = std::make_shared<LineShader>();
}
void Painter::teardown() {
@@ -89,10 +91,13 @@ void Painter::changeMatrix(const Tile::Ptr& tile) {
float projMatrix[16];
mat4::ortho(projMatrix, 0, transform.width, transform.height, 0, 1, 10);
- float mvMatrix[16];
- transform.matrixFor(mvMatrix, tile->id);
+ // The position matrix.
+ transform.matrixFor(matrix, tile->id);
+ mat4::multiply(matrix, projMatrix, matrix);
- mat4::multiply(matrix, projMatrix, mvMatrix);
+ // The extrusion matrix.
+ mat4::copy(exMatrix, projMatrix);
+ mat4::rotate_z(exMatrix, exMatrix, transform.getAngle());
}
void Painter::drawClippingMask() {
@@ -318,7 +323,73 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name) {
void Painter::renderLine(LineBucket& bucket, const std::string& layer_name) {
const LineProperties& properties = style.computed.lines[layer_name];
- // TODO
+ double width = properties.width;
+ double offset = (properties.offset || 0) / 2;
+ double inset = fmax(-1, offset - width / 2 - 0.5) + 1;
+ double outset = offset + width / 2 + 0.5;
+
+ // var imagePos = properties.image && imageSprite.getPosition(properties.image);
+ // var shader;
+ bool imagePos = false;
+
+ if (imagePos) {
+ // var factor = 8 / Math.pow(2, painter.transform.zoom - params.z);
+
+ // imageSprite.bind(gl, true);
+
+ // //factor = Math.pow(2, 4 - painter.transform.zoom + params.z);
+ // gl.switchShader(painter.linepatternShader, painter.translatedMatrix || painter.posMatrix, painter.exMatrix);
+ // shader = painter.linepatternShader;
+ // glUniform2fv(painter.linepatternShader.u_pattern_size, [imagePos.size[0] * factor, imagePos.size[1] ]);
+ // glUniform2fv(painter.linepatternShader.u_pattern_tl, imagePos.tl);
+ // glUniform2fv(painter.linepatternShader.u_pattern_br, imagePos.br);
+ // glUniform1f(painter.linepatternShader.u_fade, painter.transform.z % 1.0);
+
+ } else {
+ switchShader(lineShader);
+ glUniformMatrix4fv(lineShader->u_matrix, 1, GL_FALSE, matrix);
+ glUniformMatrix4fv(lineShader->u_exmatrix, 1, GL_FALSE, exMatrix);
+ // glUniform2fv(painter.lineShader.u_dasharray, properties.dasharray || [1, -1]);
+ glUniform2f(lineShader->u_dasharray, 1, -1);
+ }
+
+
+ const double tilePixelRatio = transform.getScale() / (1 << transform.getIntegerZoom()) / 8;
+
+ glUniform2f(lineShader->u_linewidth, outset, inset);
+ glUniform1f(lineShader->u_ratio, tilePixelRatio);
+ glUniform1f(lineShader->u_gamma, transform.pixelRatio);
+
+ // const Color& color = properties.color;
+ // if (!params.antialiasing) {
+ // color[3] = Infinity;
+ // glUniform4fv(lineShader->u_color, color);
+ // } else {
+ glUniform4fv(lineShader->u_color, 1, properties.color.data());
+ // }
+
+
+ bucket.buffer->bind();
+
+
+ char *vertex_index = BUFFER_OFFSET(bucket.start * 2 * sizeof(uint16_t));
+ glVertexAttribPointer(lineShader->a_pos, 4, GL_SHORT, false, 8, vertex_index);
+ glVertexAttribPointer(lineShader->a_extrude, 2, GL_BYTE, false, 8, vertex_index + 6);
+ glVertexAttribPointer(lineShader->a_linesofar, 2, GL_SHORT, false, 8, vertex_index + 4);
+
+ uint32_t begin = bucket.start;
+ uint32_t count = bucket.length;
+
+ glUniform1f(lineShader->u_point, 0);
+ glDrawArrays(GL_TRIANGLE_STRIP, begin, count);
+
+ if (bucket.join == JoinType::Round) {
+ glUniform1f(lineShader->u_point, 1);
+ glDrawArrays(GL_POINTS, begin, count);
+ }
+
+ // statistics
+ // stats.lines += count;
}
void Painter::renderDebug(const Tile::Ptr& tile) {
diff --git a/src/renderer/shader-line.cpp b/src/renderer/shader-line.cpp
new file mode 100644
index 0000000000..ae73dbb4fd
--- /dev/null
+++ b/src/renderer/shader-line.cpp
@@ -0,0 +1,33 @@
+#include <llmr/renderer/shader-line.hpp>
+#include <llmr/shader/shaders.hpp>
+#include <llmr/platform/gl.hpp>
+
+using namespace llmr;
+
+LineShader::LineShader()
+ : Shader(
+ shaders[LINE_SHADER].vertex,
+ shaders[LINE_SHADER].fragment
+ ) {
+ if (!valid) {
+ fprintf(stderr, "invalid line shader\n");
+ return;
+ }
+
+ a_pos = glGetAttribLocation(program, "a_pos");
+ attributes.emplace_front(a_pos);
+ a_extrude = glGetAttribLocation(program, "a_extrude");
+ attributes.emplace_front(a_extrude);
+ a_linesofar = glGetAttribLocation(program, "a_linesofar");
+ attributes.emplace_front(a_linesofar);
+
+ u_matrix = glGetUniformLocation(program, "u_matrix");
+ u_exmatrix = glGetUniformLocation(program, "u_exmatrix");
+ u_linewidth = glGetUniformLocation(program, "u_linewidth");
+ u_color = glGetUniformLocation(program, "u_color");
+ u_debug = glGetUniformLocation(program, "u_debug");
+ u_ratio = glGetUniformLocation(program, "u_ratio");
+ u_dasharray = glGetUniformLocation(program, "u_dasharray");
+ u_point = glGetUniformLocation(program, "u_point");
+ u_gamma = glGetUniformLocation(program, "u_gamma");
+}
diff --git a/src/renderer/shader.cpp b/src/renderer/shader.cpp
index d9614c0ad9..b2c735d22b 100644
--- a/src/renderer/shader.cpp
+++ b/src/renderer/shader.cpp
@@ -119,7 +119,7 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) {
glCompileShader(*shader);
-#if defined(DEBUG)
+// #if defined(DEBUG)
GLint logLength;
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
@@ -128,7 +128,7 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) {
fprintf(stderr, "Shader compile log:\n%s", log);
free(log);
}
-#endif
+// #endif
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
if (status == 0) {
diff --git a/src/shader/line.fragment.glsl b/src/shader/line.fragment.glsl
new file mode 100644
index 0000000000..5dcc5ec660
--- /dev/null
+++ b/src/shader/line.fragment.glsl
@@ -0,0 +1,35 @@
+#version 120
+// shared
+uniform float u_debug;
+uniform vec2 u_linewidth;
+uniform vec4 u_color;
+uniform float u_point;
+uniform float u_gamma;
+
+uniform vec2 u_dasharray;
+
+varying vec2 v_normal;
+varying float v_linesofar;
+
+void main() {
+ // Calculate the distance of the pixel from the line in pixels.
+ float dist = length(v_normal) * (1.0 - u_point) + u_point * length(gl_PointCoord * 2.0 - 1.0);
+
+ dist *= u_linewidth.s;
+
+ // Calculate the antialiasing fade factor. This is either when fading in
+ // the line in case of an offset line (v_linewidth.t) or when fading out
+ // (v_linewidth.s)
+ float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist) * u_gamma, 0.0, 1.0);
+
+ // 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));
+
+ gl_FragColor = u_color * alpha;
+
+ if (u_debug > 0.0) {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ }
+}
diff --git a/src/shader/line.vertex.glsl b/src/shader/line.vertex.glsl
new file mode 100644
index 0000000000..b7cb2fed46
--- /dev/null
+++ b/src/shader/line.vertex.glsl
@@ -0,0 +1,62 @@
+// these are the shaders for rendering antialiased lines
+
+// floor(127 / 2) == 63.0
+// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is
+// stored in a byte (-128..127). we scale regular normals up to length 63, but
+// there are also "special" normals that have a bigger length (of up to 126 in
+// this case).
+#define scale 63.0
+
+attribute vec2 a_pos;
+attribute vec2 a_extrude;
+attribute float a_linesofar;
+
+// matrix is for the vertex position, exmatrix is for rotating and projecting
+// the extrusion vector.
+uniform mat4 u_matrix;
+uniform mat4 u_exmatrix;
+
+
+uniform float u_debug;
+
+// shared
+uniform float u_ratio;
+uniform vec2 u_linewidth;
+uniform vec4 u_color;
+uniform float u_point;
+
+varying vec2 v_normal;
+varying float v_linesofar;
+
+void main() {
+ // We store the texture normals in the most insignificant bit
+ // transform y so that 0 => -1 and 1 => 1
+ // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap
+ // y is 1 if the normal points up, and -1 if it points down
+ vec2 normal = mod(a_pos, 2.0);
+ normal.y = sign(normal.y - 0.5);
+ v_normal = normal;
+
+ // Scale the extrusion vector down to a normal and then up by the line width
+ // of this vertex.
+ vec2 extrude = a_extrude / scale;
+ vec2 dist = u_linewidth.s * extrude * (1.0 - u_point);
+
+ // If the x coordinate is the maximum integer, we move the z coordinates out
+ // of the view plane so that the triangle gets clipped. This makes it easier
+ // for us to create degenerate triangle strips.
+ float z = step(32767.0, a_pos.x);
+
+ // When drawing points, skip every other vertex
+ z += u_point * step(1.0, v_normal.y);
+
+ // Remove the texture normal bit of the position before scaling it with the
+ // model/view matrix. Add the extrusion vector *after* the model/view matrix
+ // 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 / 2.0), 0.0, 1.0) + u_exmatrix * vec4(dist, z, 0.0);
+ v_linesofar = a_linesofar * u_ratio;
+
+
+ gl_PointSize = 2.0 * u_linewidth.s - 1.0;
+}
diff --git a/src/shader/plain.vertex.glsl b/src/shader/plain.vertex.glsl
index 547576757e..ef8225231c 100644
--- a/src/shader/plain.vertex.glsl
+++ b/src/shader/plain.vertex.glsl
@@ -5,4 +5,4 @@ uniform mat4 u_matrix;
void main() {
float z = step(32767.0, a_pos.x) * 2.0;
gl_Position = u_matrix * vec4(a_pos, z, 1);
- }
+}
diff --git a/src/shader/shaders.cpp b/src/shader/shaders.cpp
index c5e33a0b93..1b57bb68da 100644
--- a/src/shader/shaders.cpp
+++ b/src/shader/shaders.cpp
@@ -8,12 +8,16 @@ const shader_source llmr::shaders[SHADER_COUNT] = {
.vertex = "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n",
.fragment = "uniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n",
},
+ [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",
+ },
[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",
},
[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",
+ .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",
}
};