[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
This commit is contained in:
Molly Lloyd
2016-04-20 15:21:44 -07:00
parent da78422c5c
commit c86f558e9d
12 changed files with 167 additions and 4 deletions

View File

@@ -18,7 +18,7 @@
},
"devDependencies": {
"aws-sdk": "^2.3.5",
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#1e0d988e187a6c9a7a74fa8d7feb9c66c2258123",
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#d974ec6b3748a258f8ddd7528e049493390177b4",
"node-gyp": "^3.3.1",
"request": "^2.72.0",
"tape": "^4.5.1"

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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]),

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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));
}

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -21,7 +21,8 @@
"source": "mapbox",
"source-layer": "water",
"paint": {
"fill-pattern": "noise"
"fill-pattern": "noise",
"fill-antialias": false
}
}, {
"id": "admin",