diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-02-11 15:51:54 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-02-11 15:51:54 +0100 |
commit | bec0ad10c4b460941d08cca597bf352c96820d34 (patch) | |
tree | 39fd506db5deeeedc8aebc51b124e6a68ddd7de4 /src/renderer | |
parent | eb9a6b7068b9910301bfc7a3b83e114c7545c893 (diff) | |
download | qtlocation-mapboxgl-bec0ad10c4b460941d08cca597bf352c96820d34.tar.gz |
drawing lines with triangles
Diffstat (limited to 'src/renderer')
-rw-r--r-- | src/renderer/fill_bucket.cpp | 12 | ||||
-rw-r--r-- | src/renderer/line_bucket.cpp | 251 | ||||
-rw-r--r-- | src/renderer/painter.cpp | 62 | ||||
-rw-r--r-- | src/renderer/shader-line.cpp | 10 | ||||
-rw-r--r-- | src/renderer/shader-linejoin.cpp | 31 |
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); +} |