summaryrefslogtreecommitdiff
path: root/src/renderer
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-02-11 15:51:54 +0100
committerKonstantin Käfer <mail@kkaefer.com>2014-02-11 15:51:54 +0100
commitbec0ad10c4b460941d08cca597bf352c96820d34 (patch)
tree39fd506db5deeeedc8aebc51b124e6a68ddd7de4 /src/renderer
parenteb9a6b7068b9910301bfc7a3b83e114c7545c893 (diff)
downloadqtlocation-mapboxgl-bec0ad10c4b460941d08cca597bf352c96820d34.tar.gz
drawing lines with triangles
Diffstat (limited to 'src/renderer')
-rw-r--r--src/renderer/fill_bucket.cpp12
-rw-r--r--src/renderer/line_bucket.cpp251
-rw-r--r--src/renderer/painter.cpp62
-rw-r--r--src/renderer/shader-line.cpp10
-rw-r--r--src/renderer/shader-linejoin.cpp31
5 files changed, 219 insertions, 147 deletions
diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp
index 8446c04f2b..2c52701742 100644
--- a/src/renderer/fill_bucket.cpp
+++ b/src/renderer/fill_bucket.cpp
@@ -1,5 +1,6 @@
#include <llmr/renderer/fill_bucket.hpp>
#include <llmr/geometry/fill_buffer.hpp>
+#include <llmr/geometry/elements_buffer.hpp>
#include <llmr/geometry/geometry.hpp>
#include <llmr/renderer/painter.hpp>
@@ -15,7 +16,7 @@ struct geometry_too_long_exception : std::exception {};
using namespace llmr;
FillBucket::FillBucket(const std::shared_ptr<FillVertexBuffer>& vertexBuffer,
- const std::shared_ptr<FillElementsBuffer>& elementsBuffer,
+ const std::shared_ptr<TriangleElementsBuffer>& elementsBuffer,
const BucketDescription& bucket_desc)
: geom_desc(bucket_desc.geometry),
vertexBuffer(vertexBuffer),
@@ -102,14 +103,11 @@ 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));
+ char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize);
+ char *elements_index = BUFFER_OFFSET(elements_start * elementsBuffer->itemSize);
for (group& group : groups) {
- group.array.bind(shader, *vertexBuffer, vertex_index);
- elementsBuffer->bind();
+ 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);
diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp
index 213d8a2856..e60b4fa6f4 100644
--- a/src/renderer/line_bucket.cpp
+++ b/src/renderer/line_bucket.cpp
@@ -1,9 +1,11 @@
#include <llmr/renderer/line_bucket.hpp>
#include <llmr/geometry/line_buffer.hpp>
+#include <llmr/geometry/elements_buffer.hpp>
#include <llmr/geometry/geometry.hpp>
#include <llmr/renderer/painter.hpp>
#include <llmr/renderer/shader-line.hpp>
+#include <llmr/renderer/shader-linejoin.hpp>
#include <llmr/style/style.hpp>
#include <llmr/map/vector_tile.hpp>
@@ -18,11 +20,20 @@ struct geometry_too_long_exception : std::exception {};
using namespace llmr;
-LineBucket::LineBucket(const std::shared_ptr<LineBuffer>& buffer, const BucketDescription& bucket_desc)
+LineBucket::LineBucket(const std::shared_ptr<LineVertexBuffer>& vertexBuffer,
+ const std::shared_ptr<TriangleElementsBuffer>& triangleElementsBuffer,
+ const std::shared_ptr<PointElementsBuffer>& pointElementsBuffer,
+ const BucketDescription& bucket_desc)
: geometry(bucket_desc.geometry),
- buffer(buffer),
- start(buffer->index()),
- length(0) {
+ vertexBuffer(vertexBuffer),
+ vertex_start(vertexBuffer->index()),
+ vertex_length(0),
+ triangleElementsBuffer(triangleElementsBuffer),
+ triangle_elements_start(triangleElementsBuffer->index()),
+ triangle_length(0),
+ pointElementsBuffer(pointElementsBuffer),
+ point_elements_start(pointElementsBuffer->index()),
+ point_length(0) {
}
void LineBucket::addGeometry(pbf& geom) {
@@ -52,15 +63,8 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
const float miterLimit = geometry.miter_limit;
const float roundLimit = geometry.round_limit;
- if (vertices.size() < 1) {
- // alert('a line must have at least one vertex');
- return;
- }
-
- // Point
- if (vertices.size() == 1) {
- Coordinate coord = vertices.front();
- buffer->add(coord.x, coord.y, 1, 0, 0, 0);
+ if (vertices.size() < 2) {
+ // fprintf(stderr, "a line must have at least two vertices\n");
return;
}
@@ -69,19 +73,23 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
bool closed = firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y;
if (vertices.size() == 2 && closed) {
- // alert('a line may not have coincident points');
+ // fprintf(stderr, "a line may not have coincident points\n");
return;
}
CapType beginCap = cap;
CapType endCap = closed ? CapType::Butt : cap;
+ JoinType currentJoin = JoinType::None;
+
Coordinate currentVertex = Coordinate::null(),
prevVertex = Coordinate::null(),
nextVertex = Coordinate::null();
vec2<double> prevNormal = vec2<double>::null(),
nextNormal = vec2<double>::null();
+ int32_t e1 = -1, e2 = -1, e3 = -1;
+
int8_t flip = 1;
double distance = 0;
@@ -90,14 +98,12 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
nextNormal = util::normal<double>(currentVertex, lastVertex);
}
- // Start all lines with a degenerate vertex
- buffer->addDegenerate();
-
for (size_t i = 0; i < vertices.size(); ++i) {
if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y };
if (currentVertex) prevVertex = currentVertex;
currentVertex = vertices[i];
+ currentJoin = join;
if (prevVertex) distance += util::dist<double>(currentVertex, prevVertex);
@@ -108,18 +114,11 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
nextVertex = Coordinate::null();
}
- bool segment = false;
-
- if (closed && i >= 2 && (i + 1 < vertices.size())) {
- segment = true;
- }
-
// If the line is closed, we treat the last vertex like the first vertex.
if (!nextVertex && closed) {
nextVertex = vertices[1];
}
-
if (nextVertex) {
// if two consecutive vertices exist, skip one
if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue;
@@ -155,67 +154,53 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
double roundness = fmax(abs(joinNormal.x), abs(joinNormal.y));
- bool roundJoin = false;
- // Determine whether we should actually draw a round/bevelled/butt line join. It looks
- // better if we do, but we can get away with drawing a mitered join for
- // joins that have a very small angle. For this, we have the "roundLimit"
- // parameter. We do this to reduce the number of vertices we have to
- // write into the line vertex buffer. Note that joinAngularity may be 0,
- // so the roundness grows to infinity. This is intended.
- if ((join == JoinType::Round || join == JoinType::Bevel || join == JoinType::Butt) && roundness > roundLimit) {
- roundJoin = true;
+ // Switch to miter joins if the angle is very low.
+ if (currentJoin != JoinType::Miter) {
+ if (fabs(joinAngularity) < 0.5 && roundness < miterLimit) {
+ currentJoin = JoinType::Miter;
+ }
}
- // Close up the previous line for a round join
- if (roundJoin && prevVertex && nextVertex) {
+ // Add offset square begin cap.
+ if (!prevVertex && beginCap == CapType::Square) {
// Add first vertex
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- flip * prevNormal.y, -flip * prevNormal.x, // extrude normal
- 0, 0, distance); // texture normal
-
- // Add second vertex.
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- -flip * prevNormal.y, flip * prevNormal.x, // extrude normal
- 0, 1, distance); // texture normal
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal
+ 0, 0, distance) - vertex_start; // texture normal
- // Degenerate triangle
- if (join == JoinType::Round || join == JoinType::Butt) {
- buffer->addDegenerate();
- }
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
- if (join == JoinType::Round) prevVertex = Coordinate::null();
+ // Add second vertex
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal
+ 0, 1, distance) - vertex_start; // texture normal
- prevNormal = { -nextNormal.x, -nextNormal.y };
- flip = 1;
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
}
- // Add a cap.
- if (!prevVertex && (beginCap == CapType::Round || beginCap == CapType::Square || (roundJoin && join == JoinType::Round))) {
- int8_t tex = beginCap == CapType::Round || roundJoin ? 1 : 0;
-
+ // Add offset square end cap.
+ else if (!nextVertex && endCap == CapType::Square) {
// Add first vertex
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal
- tex, 0, distance); // texture normal
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal
+ 0, 0, distance) - vertex_start; // texture normal
+
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
// Add second vertex
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal
- tex, 1, distance); // texture normal
- }
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal
+ 0, 1, distance) - vertex_start; // texture normal
- if (roundJoin) {
- // ROUND JOIN
- // Add first vertex
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- -flip * nextNormal.y, flip * nextNormal.x, // extrude normal
- 0, 0, distance); // texture normal
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
+ }
- // Add second vertex
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- flip * nextNormal.y, -flip * nextNormal.x, // extrude normal
- 0, 1, distance); // texture normal
- } else if ((nextVertex || endCap != CapType::Square) && (prevVertex || beginCap != CapType::Square)) {
+ else
+ if (currentJoin == JoinType::Miter) {
// MITER JOIN
if (fabs(joinAngularity) < 0.01) {
// The two normals are almost parallel.
@@ -226,58 +211,126 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
// bevel join.
joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity;
joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity;
+ }
+
+ if (roundness > miterLimit) {
flip = -flip;
}
// Add first vertex
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- flip * joinNormal.x, flip * joinNormal.y, // extrude normal
- 0, 0, distance); // texture normal
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * joinNormal.x, flip * joinNormal.y, // extrude normal
+ 0, 0, distance) - vertex_start; // texture normal
+
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
// Add second vertex
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal
- 0, 1, distance); // texture normal
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal
+ 0, 1, distance) - vertex_start; // texture normal
+
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
+
+ if ((!prevVertex && beginCap == CapType::Round) ||
+ (!nextVertex && endCap == CapType::Round)) {
+ pointElementsBuffer->add(e1);
+ }
}
- // Add the end cap, but only if this vertex is distinct from the begin
- // vertex.
- if (!nextVertex && (endCap == CapType::Round || endCap == CapType::Square)) {
- int8_t capTex = endCap == CapType::Round ? 1 : 0;
+ else {
+ // Close up the previous line
+ // Add first vertex
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * prevNormal.y, -flip * prevNormal.x, // extrude normal
+ 0, 0, distance) - vertex_start; // texture normal
+
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
+
+ // Add second vertex.
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ -flip * prevNormal.y, flip * prevNormal.x, // extrude normal
+ 0, 1, distance) - vertex_start; // texture normal
+
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
+
+ prevNormal = { -nextNormal.x, -nextNormal.y };
+ flip = 1;
+
+
+ // begin/end caps
+ if ((!prevVertex && beginCap == CapType::Round) ||
+ (!nextVertex && endCap == CapType::Round)) {
+ pointElementsBuffer->add(e1);
+ }
+
+
+ if (currentJoin == JoinType::Round) {
+ if (prevVertex && nextVertex && (!closed || i > 0)) {
+ pointElementsBuffer->add(e1);
+ }
+ // Reset the previous vertices so that we don't accidentally create
+ // any triangles.
+ e1 = -1; e2 = -1; e3 = -1;
+ }
+
+ // Start the new quad.
// Add first vertex
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal
- capTex, 0, distance); // texture normal
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ -flip * nextNormal.y, flip * nextNormal.x, // extrude normal
+ 0, 0, distance) - vertex_start; // texture normal
+
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
// Add second vertex
- buffer->add(currentVertex.x, currentVertex.y, // vertex pos
- nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal
- capTex, 1, distance); // texture normal
+ e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * nextNormal.y, -flip * nextNormal.x, // extrude normal
+ 0, 1, distance) - vertex_start; // texture normal
+
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangleElementsBuffer->add(e1, e2, e3);
+ e1 = e2; e2 = e3;
}
}
- // Update the length.
- length = buffer->index() - start;
+ // Update the lengths.
+ vertex_length = vertexBuffer->index() - vertex_start;
+ triangle_length = triangleElementsBuffer->index() - triangle_elements_start;
+ point_length = pointElementsBuffer->index() - point_elements_start;
}
void LineBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) {
painter.renderLine(*this, layer_name, id);
}
-size_t LineBucket::size() const {
- return length;
+bool LineBucket::empty() const {
+ return vertex_length == 0;
+}
+
+bool LineBucket::hasPoints() const {
+ return point_length > 0;
}
-void LineBucket::bind(LineShader& shader) {
- char *vertex_index = BUFFER_OFFSET(start * 4 * sizeof(int16_t));
- array.bind(shader, *buffer, vertex_index);
+void LineBucket::drawLines(LineShader& shader) {
+ char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize);
+ char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer->itemSize);
+ lineArray.bind(shader, *vertexBuffer, *triangleElementsBuffer, vertex_index);
+ glDrawElements(GL_TRIANGLES, triangle_length * 3, GL_UNSIGNED_SHORT, elements_index);
}
-void LineBucket::drawLines() {
- glDrawArrays(GL_TRIANGLE_STRIP, 0, length);
+void LineBucket::drawDebugLines(LineShader& shader) {
+ char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize);
+ lineArray.bind(shader, *vertexBuffer, *triangleElementsBuffer, vertex_index);
+ glDrawArrays(GL_LINE_STRIP, 0, vertex_length);
}
-void LineBucket::drawPoints() {
- glDrawArrays(GL_POINTS, 0, length);
+void LineBucket::drawPoints(LinejoinShader& shader) {
+ char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize);
+ char *elements_index = BUFFER_OFFSET(point_elements_start * pointElementsBuffer->itemSize);
+ pointArray.bind(shader, *vertexBuffer, *pointElementsBuffer, vertex_index);
+ glDrawElements(GL_POINTS, point_length, GL_UNSIGNED_SHORT, elements_index);
}
diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp
index a00ead94fd..71e1dcfc86 100644
--- a/src/renderer/painter.cpp
+++ b/src/renderer/painter.cpp
@@ -32,6 +32,7 @@ void Painter::setup() {
assert(plainShader);
assert(outlineShader);
assert(lineShader);
+ assert(linejoinShader);
assert(patternShader);
glEnable(GL_STENCIL_TEST);
@@ -46,6 +47,7 @@ void Painter::setupShaders() {
plainShader = std::make_unique<PlainShader>();
outlineShader = std::make_unique<OutlineShader>();
lineShader = std::make_unique<LineShader>();
+ linejoinShader = std::make_unique<LinejoinShader>();
patternShader = std::make_unique<PatternShader>();
}
@@ -213,7 +215,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
if (properties.antialias) {
glUseProgram(outlineShader->program);
glUniformMatrix4fv(outlineShader->u_matrix, 1, GL_FALSE, matrix.data());
- glLineWidth(2);
+ glLineWidth(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
@@ -233,7 +235,6 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
// Draw the entire line
glUniform2f(outlineShader->u_world, transform.fb_width, transform.fb_height);
- glLineWidth(2.0f);
bucket.drawVertices(*outlineShader);
}
@@ -286,13 +287,16 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
const LineProperties& properties = style.computed.lines[layer_name];
// Abort early.
- if (!bucket.size()) return;
+ if (bucket.empty()) return;
if (properties.hidden) return;
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;
+ double offset = properties.offset / 2;
+
+ // These are the radii of the line. We are limiting it to 16, which will result
+ // in a point size of 64 on retina.
+ double inset = fmin((fmax(-1, offset - width / 2 - 0.5) + 1), 16.0f);
+ double outset = fmin(offset + width / 2 + 0.5, 16.0f);
Color color = properties.color;
color[0] *= properties.opacity;
@@ -300,10 +304,19 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
color[2] *= properties.opacity;
color[3] *= properties.opacity;
+ // 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());
+ 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);
+ glPointSize(ceil(transform.pixelRatio * outset * 2.0));
+ bucket.drawPoints(*linejoinShader);
+ }
+
// 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);
@@ -321,38 +334,17 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
glUseProgram(lineShader->program);
glUniformMatrix4fv(lineShader->u_matrix, 1, GL_FALSE, matrix.data());
glUniformMatrix4fv(lineShader->u_exmatrix, 1, GL_FALSE, exMatrix.data());
- // glUniform2fv(painter.lineShader.u_dasharray, properties.dasharray || [1, -1]);
- glUniform2f(lineShader->u_dasharray, 1, -1);
-
// TODO: Move this to transform?
const double tilePixelRatio = transform.getScale() / (1 << transform.getIntegerZoom()) / 8;
+ glUniform2f(lineShader->u_dasharray, 1, -1);
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, color.data());
- // }
-
-
- glUniform1f(lineShader->u_point, 0);
- bucket.bind(*lineShader);
- bucket.drawLines();
-
- if (bucket.geometry.join == JoinType::Round) {
- glUniform1f(lineShader->u_point, 1);
- bucket.drawPoints();
- }
+ glUniform1f(lineShader->u_debug, 0);
+ bucket.drawLines(*lineShader);
}
-
- // statistics
- // stats.lines += count;
}
void Painter::renderDebug(const Tile::Ptr& tile) {
@@ -364,16 +356,16 @@ void Painter::renderDebug(const Tile::Ptr& tile) {
// 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);
+ glLineWidth(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);
+ glLineWidth(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);
+ glLineWidth(2.0f * transform.pixelRatio);
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.index());
// Revert blending mode to blend to the back.
diff --git a/src/renderer/shader-line.cpp b/src/renderer/shader-line.cpp
index feed1626e5..667af4fe12 100644
--- a/src/renderer/shader-line.cpp
+++ b/src/renderer/shader-line.cpp
@@ -24,20 +24,18 @@ LineShader::LineShader()
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");
+ u_debug = glGetUniformLocation(program, "u_debug");
}
void LineShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset);
- glEnableVertexAttribArray(a_extrude);
- glVertexAttribPointer(a_extrude, 2, GL_BYTE, false, 8, offset + 6);
-
glEnableVertexAttribArray(a_linesofar);
glVertexAttribPointer(a_linesofar, 1, GL_SHORT, false, 8, offset + 4);
+
+ glEnableVertexAttribArray(a_extrude);
+ glVertexAttribPointer(a_extrude, 2, GL_BYTE, false, 8, offset + 6);
} \ No newline at end of file
diff --git a/src/renderer/shader-linejoin.cpp b/src/renderer/shader-linejoin.cpp
new file mode 100644
index 0000000000..5d9fa13ecb
--- /dev/null
+++ b/src/renderer/shader-linejoin.cpp
@@ -0,0 +1,31 @@
+#include <llmr/renderer/shader-linejoin.hpp>
+#include <llmr/shader/shaders.hpp>
+#include <llmr/platform/gl.hpp>
+
+#include <cstdio>
+
+using namespace llmr;
+
+LinejoinShader::LinejoinShader()
+ : Shader(
+ shaders[LINEJOIN_SHADER].vertex,
+ shaders[LINEJOIN_SHADER].fragment
+ ) {
+ if (!valid) {
+ fprintf(stderr, "invalid line shader\n");
+ return;
+ }
+
+ a_pos = glGetAttribLocation(program, "a_pos");
+
+ u_matrix = glGetUniformLocation(program, "u_matrix");
+ u_world = glGetUniformLocation(program, "u_world");
+ u_linewidth = glGetUniformLocation(program, "u_linewidth");
+ u_color = glGetUniformLocation(program, "u_color");
+}
+
+void LinejoinShader::bind(char *offset) {
+ glEnableVertexAttribArray(a_pos);
+ // Note: We're referring to the vertices in a line array, which are 8 bytes long!
+ glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset);
+}