diff options
Diffstat (limited to 'src/mbgl/renderer/painter_line.cpp')
-rw-r--r-- | src/mbgl/renderer/painter_line.cpp | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp new file mode 100644 index 0000000000..4bf50569ac --- /dev/null +++ b/src/mbgl/renderer/painter_line.cpp @@ -0,0 +1,101 @@ +#include <mbgl/renderer/painter.hpp> +#include <mbgl/renderer/line_bucket.hpp> +#include <mbgl/style/style.hpp> +#include <mbgl/style/style_layer.hpp> +#include <mbgl/map/sprite.hpp> +#include <mbgl/geometry/sprite_atlas.hpp> +#include <mbgl/map/map.hpp> + +using namespace mbgl; + +void Painter::renderLine(LineBucket& bucket, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix) { + // Abort early. + if (pass == RenderPass::Opaque) return; + if (!bucket.hasData()) return; + + const LineProperties &properties = layer_desc->getProperties<LineProperties>(); + + float antialiasing = 1 / state.getPixelRatio(); + float width = properties.width; + float offset = properties.gap_width == 0 ? 0 : (properties.gap_width + width) / 2; + float blur = properties.blur + antialiasing; + + float inset = std::fmin((std::fmax(-1, offset - width / 2 - antialiasing / 2) + 1), 16.0f); + float outset = std::fmin(offset + width / 2 + antialiasing / 2, 16.0f); + + Color color = properties.color; + color[0] *= properties.opacity; + color[1] *= properties.opacity; + color[2] *= properties.opacity; + color[3] *= properties.opacity; + + float dash_length = properties.dash_array[0]; + float dash_gap = properties.dash_array[1]; + + float ratio = state.getPixelRatio(); + mat4 vtxMatrix = translatedMatrix(matrix, properties.translate, id, properties.translateAnchor); + + depthRange(strata, 1.0f); + + // 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) { + useProgram(linejoinShader->program); + linejoinShader->u_matrix = vtxMatrix; + linejoinShader->u_color = color; + linejoinShader->u_world = {{ + state.getFramebufferWidth() * 0.5f, + state.getFramebufferHeight() * 0.5f + }}; + linejoinShader->u_linewidth = {{ + ((outset - 0.25f) * state.getPixelRatio()), + ((inset - 0.25f) * state.getPixelRatio()) + }}; + + float pointSize = std::ceil(state.getPixelRatio() * outset * 2.0); +#if defined(GL_ES_VERSION_2_0) + linejoinShader->u_size = pointSize; +#else + glPointSize(pointSize); +#endif + bucket.drawPoints(*linejoinShader); + } + + if (properties.image.size()) { + SpriteAtlasPosition imagePos = spriteAtlas.getPosition(properties.image); + + float factor = 8.0 / std::pow(2, state.getIntegerZoom() - id.z); + float fade = std::fmod(state.getZoom(), 1.0); + + useProgram(linepatternShader->program); + + linepatternShader->u_matrix = vtxMatrix; + linepatternShader->u_exmatrix = extrudeMatrix; + linepatternShader->u_linewidth = {{ outset, inset }}; + linepatternShader->u_ratio = ratio; + linepatternShader->u_blur = blur; + + linepatternShader->u_pattern_size = {{imagePos.size[0] * factor, imagePos.size[1]}}; + linepatternShader->u_pattern_tl = imagePos.tl; + linepatternShader->u_pattern_br = imagePos.br; + linepatternShader->u_fade = fade; + + spriteAtlas.bind(true); + glDepthRange(strata + strata_epsilon, 1.0f); // may or may not matter + + bucket.drawLinePatterns(*linepatternShader); + + } else { + useProgram(lineShader->program); + + lineShader->u_matrix = vtxMatrix; + lineShader->u_exmatrix = extrudeMatrix; + lineShader->u_linewidth = {{ outset, inset }}; + lineShader->u_ratio = ratio; + lineShader->u_blur = blur; + + lineShader->u_color = color; + lineShader->u_dasharray = {{ dash_length, dash_gap }}; + + bucket.drawLines(*lineShader); + } +} |