diff options
author | Molly Lloyd <molly@mapbox.com> | 2016-04-20 15:21:44 -0700 |
---|---|---|
committer | Molly Lloyd <molly@mapbox.com> | 2016-04-28 17:13:20 -0700 |
commit | c86f558e9d608ac19ca5b26ea8f72e2dc43c07c0 (patch) | |
tree | c398f14a1cdc646119fac4ac8c0d557ca970e29d /src | |
parent | da78422c5c37b2150eefeb399658903e45bf05d9 (diff) | |
download | qtlocation-mapboxgl-c86f558e9d608ac19ca5b26ea8f72e2dc43c07c0.tar.gz |
[core] port outlinepattern for fill-pattern anti-aliasing from gl-js to native
add outlinepattern shader class to relevant files
add outlinepattern code to painter_fill.cpp
add outlinepattern code to fill_bucket
refactor painter_fill, fix tests
fix merge conflicts and setDepthSublayer
update render test to no antialiasing so travis will be happy
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/renderer/fill_bucket.cpp | 13 | ||||
-rw-r--r-- | src/mbgl/renderer/fill_bucket.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_fill.cpp | 41 | ||||
-rw-r--r-- | src/mbgl/shader/outlinepattern.fragment.glsl | 30 | ||||
-rw-r--r-- | src/mbgl/shader/outlinepattern.vertex.glsl | 21 | ||||
-rw-r--r-- | src/mbgl/shader/outlinepattern_shader.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/shader/outlinepattern_shader.hpp | 32 |
9 files changed, 164 insertions, 2 deletions
diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index 1388c6dfb7..48d9ae88aa 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -6,6 +6,7 @@ #include <mbgl/shader/plain_shader.hpp> #include <mbgl/shader/pattern_shader.hpp> #include <mbgl/shader/outline_shader.hpp> +#include <mbgl/shader/outlinepattern_shader.hpp> #include <mbgl/gl/gl.hpp> #include <mbgl/platform/log.hpp> @@ -245,3 +246,15 @@ void FillBucket::drawVertices(OutlineShader& shader, gl::GLObjectStore& glObject elements_index += group->elements_length * lineElementsBuffer.itemSize; } } + +void FillBucket::drawVertices(OutlinePatternShader& shader, gl::GLObjectStore& glObjectStore) { + GLbyte* vertex_index = BUFFER_OFFSET(0); + GLbyte* elements_index = BUFFER_OFFSET(0); + for (auto& group : lineGroups) { + assert(group); + group->array[1].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index, glObjectStore); + MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT, elements_index)); + vertex_index += group->vertex_length * vertexBuffer.itemSize; + elements_index += group->elements_length * lineElementsBuffer.itemSize; + } +} diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index 61a3b986ba..bd6a9a9cf4 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -16,6 +16,7 @@ namespace mbgl { class FillVertexBuffer; class OutlineShader; +class OutlinePatternShader; class PlainShader; class PatternShader; @@ -26,7 +27,7 @@ class FillBucket : public Bucket { static void free(void *userData, void *ptr); typedef ElementGroup<2> TriangleGroup; - typedef ElementGroup<1> LineGroup; + typedef ElementGroup<2> LineGroup; public: FillBucket(); @@ -43,6 +44,7 @@ public: void drawElements(PlainShader&, gl::GLObjectStore&); void drawElements(PatternShader&, gl::GLObjectStore&); void drawVertices(OutlineShader&, gl::GLObjectStore&); + void drawVertices(OutlinePatternShader&, gl::GLObjectStore&); private: TESSalloc *allocator; diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 552859343b..1fbce82c03 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -20,6 +20,7 @@ #include <mbgl/shader/pattern_shader.hpp> #include <mbgl/shader/plain_shader.hpp> #include <mbgl/shader/outline_shader.hpp> +#include <mbgl/shader/outlinepattern_shader.hpp> #include <mbgl/shader/line_shader.hpp> #include <mbgl/shader/linesdf_shader.hpp> #include <mbgl/shader/linepattern_shader.hpp> @@ -49,6 +50,7 @@ Painter::Painter(const TransformState& state_, gl::GLObjectStore& glObjectStore_ plainShader = std::make_unique<PlainShader>(glObjectStore); outlineShader = std::make_unique<OutlineShader>(glObjectStore); + outlinePatternShader = std::make_unique<OutlinePatternShader>(glObjectStore); lineShader = std::make_unique<LineShader>(glObjectStore); linesdfShader = std::make_unique<LineSDFShader>(glObjectStore); linepatternShader = std::make_unique<LinepatternShader>(glObjectStore); diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 5dc87f9c9f..2fa5c02604 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -53,6 +53,7 @@ class BackgroundLayer; class SDFShader; class PlainShader; class OutlineShader; +class OutlinePatternShader; class LineShader; class LinejoinShader; class LineSDFShader; @@ -190,6 +191,7 @@ private: std::unique_ptr<PlainShader> plainShader; std::unique_ptr<OutlineShader> outlineShader; + std::unique_ptr<OutlinePatternShader> outlinePatternShader; std::unique_ptr<LineShader> lineShader; std::unique_ptr<LineSDFShader> linesdfShader; std::unique_ptr<LinepatternShader> linepatternShader; diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index 0452b532ac..0808cd2ac1 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -4,6 +4,7 @@ #include <mbgl/map/tile_id.hpp> #include <mbgl/sprite/sprite_atlas.hpp> #include <mbgl/shader/outline_shader.hpp> +#include <mbgl/shader/outlinepattern_shader.hpp> #include <mbgl/shader/pattern_shader.hpp> #include <mbgl/shader/plain_shader.hpp> @@ -108,6 +109,44 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI // Draw the actual triangles into the color & stencil buffer. setDepthSublayer(0); bucket.drawElements(*patternShader, glObjectStore); + + if (properties.fillAntialias && stroke_color == fill_color) { + config.program = outlinePatternShader->getID(); + outlinePatternShader->u_matrix = vtxMatrix; + config.lineWidth = 2.0f; + + // Draw the entire line + outlinePatternShader->u_world = {{ + static_cast<float>(frame.framebufferSize[0]), + static_cast<float>(frame.framebufferSize[1]) + }}; + + outlinePatternShader->u_pattern_tl_a = (*posA).tl; + outlinePatternShader->u_pattern_br_a = (*posA).br; + outlinePatternShader->u_pattern_tl_b = (*posB).tl; + outlinePatternShader->u_pattern_br_b = (*posB).br; + outlinePatternShader->u_opacity = properties.fillOpacity; + outlinePatternShader->u_image = 0; + outlinePatternShader->u_mix = properties.fillPattern.value.t; + + outlinePatternShader->u_patternscale_a = {{ + 1.0f / id.pixelsToTileUnits(imageSizeScaledA[0], state.getIntegerZoom()), + 1.0f / id.pixelsToTileUnits(imageSizeScaledB[1], state.getIntegerZoom()) + }}; + outlinePatternShader->u_patternscale_b = {{ + 1.0f / id.pixelsToTileUnits(imageSizeScaledB[0], state.getIntegerZoom()), + 1.0f / id.pixelsToTileUnits(imageSizeScaledB[1], state.getIntegerZoom()) + }}; + + outlinePatternShader->u_offset_a = std::array<float, 2>{{offsetAx, offsetAy}}; + outlinePatternShader->u_offset_b = std::array<float, 2>{{offsetBx, offsetBy}}; + + config.activeTexture = GL_TEXTURE0; + spriteAtlas->bind(true, glObjectStore); + + setDepthSublayer(2); + bucket.drawVertices(*outlinePatternShader, glObjectStore); + } } } else { @@ -135,7 +174,7 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI config.lineWidth = 2.0f; // This is always fixed and does not depend on the pixelRatio! outlineShader->u_color = fill_color; - + // Draw the entire line outlineShader->u_world = {{ static_cast<float>(frame.framebufferSize[0]), diff --git a/src/mbgl/shader/outlinepattern.fragment.glsl b/src/mbgl/shader/outlinepattern.fragment.glsl new file mode 100644 index 0000000000..dd1efd63e6 --- /dev/null +++ b/src/mbgl/shader/outlinepattern.fragment.glsl @@ -0,0 +1,30 @@ +uniform float u_opacity; +uniform vec2 u_pattern_tl_a; +uniform vec2 u_pattern_br_a; +uniform vec2 u_pattern_tl_b; +uniform vec2 u_pattern_br_b; +uniform float u_mix; + +uniform sampler2D u_image; + +varying vec2 v_pos_a; +varying vec2 v_pos_b; +varying vec2 v_pos; + +void main() { + vec2 imagecoord = mod(v_pos_a, 1.0); + vec2 pos = mix(u_pattern_tl_a, u_pattern_br_a, imagecoord); + vec4 color1 = texture2D(u_image, pos); + + vec2 imagecoord_b = mod(v_pos_b, 1.0); + vec2 pos2 = mix(u_pattern_tl_b, u_pattern_br_b, imagecoord_b); + vec4 color2 = texture2D(u_image, pos2); + + // find distance to outline for alpha interpolation + + float dist = length(v_pos - gl_FragCoord.xy); + float alpha = smoothstep(1.0, 0.0, dist); + + + gl_FragColor = mix(color1, color2, u_mix) * alpha * u_opacity; +}
\ No newline at end of file diff --git a/src/mbgl/shader/outlinepattern.vertex.glsl b/src/mbgl/shader/outlinepattern.vertex.glsl new file mode 100644 index 0000000000..e31b77b560 --- /dev/null +++ b/src/mbgl/shader/outlinepattern.vertex.glsl @@ -0,0 +1,21 @@ +uniform vec2 u_patternscale_a; +uniform vec2 u_patternscale_b; +uniform vec2 u_offset_a; +uniform vec2 u_offset_b; + +attribute vec2 a_pos; + +uniform mat4 u_matrix; +uniform vec2 u_world; + +varying vec2 v_pos_a; +varying vec2 v_pos_b; +varying vec2 v_pos; + + +void main() { + gl_Position = u_matrix * vec4(a_pos, 0, 1); + v_pos_a = u_patternscale_a * a_pos + u_offset_a; + v_pos_b = u_patternscale_b * a_pos + u_offset_b; + v_pos = (gl_Position.xy/gl_Position.w + 1.0) / 2.0 * u_world; +} diff --git a/src/mbgl/shader/outlinepattern_shader.cpp b/src/mbgl/shader/outlinepattern_shader.cpp new file mode 100644 index 0000000000..44b76b74c0 --- /dev/null +++ b/src/mbgl/shader/outlinepattern_shader.cpp @@ -0,0 +1,21 @@ +#include <mbgl/shader/outlinepattern_shader.hpp> +#include <mbgl/shader/outlinepattern.vertex.hpp> +#include <mbgl/shader/outlinepattern.fragment.hpp> +#include <mbgl/gl/gl.hpp> + +#include <cstdio> + +using namespace mbgl; + +OutlinePatternShader::OutlinePatternShader(gl::GLObjectStore& glObjectStore) + : Shader( + "outlinepattern", + shaders::outlinepattern::vertex, shaders::outlinepattern::fragment, + glObjectStore + ) { +} + +void OutlinePatternShader::bind(GLbyte *offset) { + MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos)); + MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset)); +} diff --git a/src/mbgl/shader/outlinepattern_shader.hpp b/src/mbgl/shader/outlinepattern_shader.hpp new file mode 100644 index 0000000000..eed3839fd3 --- /dev/null +++ b/src/mbgl/shader/outlinepattern_shader.hpp @@ -0,0 +1,32 @@ +#ifndef MBGL_SHADER_SHADER_OUTLINEPATTERN +#define MBGL_SHADER_SHADER_OUTLINEPATTERN + +#include <mbgl/shader/shader.hpp> +#include <mbgl/shader/uniform.hpp> + +namespace mbgl { + +class OutlinePatternShader : public Shader { +public: + OutlinePatternShader(gl::GLObjectStore&); + + void bind(GLbyte *offset) final; + + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + Uniform<std::array<GLfloat, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this}; + Uniform<std::array<GLfloat, 2>> u_pattern_br_a = {"u_pattern_br_a", *this}; + Uniform<std::array<GLfloat, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this}; + Uniform<std::array<GLfloat, 2>> u_pattern_br_b = {"u_pattern_br_b", *this}; + Uniform<GLfloat> u_opacity = {"u_opacity", *this}; + Uniform<GLfloat> u_mix = {"u_mix", *this}; + Uniform<GLint> u_image = {"u_image", *this}; + Uniform<std::array<GLfloat, 2>> u_patternscale_a = {"u_patternscale_a", *this}; + Uniform<std::array<GLfloat, 2>> u_patternscale_b = {"u_patternscale_b", *this}; + Uniform<std::array<GLfloat, 2>> u_offset_a = {"u_offset_a", *this}; + Uniform<std::array<GLfloat, 2>> u_offset_b = {"u_offset_b", *this}; + Uniform<std::array<GLfloat, 2>> u_world = {"u_world", *this}; +}; + +} // namespace mbgl + +#endif
\ No newline at end of file |