diff options
author | Ansis Brammanis <brammanis@gmail.com> | 2016-03-28 11:57:45 -0700 |
---|---|---|
committer | Ansis Brammanis <brammanis@gmail.com> | 2016-03-28 16:59:39 -0700 |
commit | b352bb81d8259f1e52fe933a20f782d1c4327f1a (patch) | |
tree | 4b19f608bf8e4a9d0994035b90d812d9774989b4 /src | |
parent | 4522bf02c9f5510ca2641e96a9e7a41048f00efe (diff) | |
download | qtlocation-mapboxgl-b352bb81d8259f1e52fe933a20f782d1c4327f1a.tar.gz |
[core] fix background-pattern rendering in perspective view
fix #3801
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 84 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_background.cpp | 105 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_fill.cpp | 23 | ||||
-rw-r--r-- | src/mbgl/shader/pattern.vertex.glsl | 8 | ||||
-rw-r--r-- | src/mbgl/shader/pattern_shader.hpp | 4 |
6 files changed, 122 insertions, 111 deletions
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index c6b8bdbc3b..2244691fdd 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -33,7 +33,6 @@ #include <mbgl/shader/circle_shader.hpp> #include <mbgl/util/constants.hpp> -#include <mbgl/util/mat3.hpp> #if defined(DEBUG) #include <mbgl/util/stopwatch.hpp> @@ -257,89 +256,6 @@ void Painter::renderPass(RenderPass pass_, } } -void Painter::renderBackground(const BackgroundLayer& layer) { - // Note that for bottommost layers without a pattern, the background color is drawn with - // glClear rather than this method. - const BackgroundPaintProperties& properties = layer.paint; - - if (!properties.pattern.value.to.empty()) { - optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(properties.pattern.value.from, true); - optional<SpriteAtlasPosition> imagePosB = spriteAtlas->getPosition(properties.pattern.value.to, true); - - if (!imagePosA || !imagePosB) - return; - - config.program = patternShader->getID(); - patternShader->u_matrix = identityMatrix; - patternShader->u_pattern_tl_a = (*imagePosA).tl; - patternShader->u_pattern_br_a = (*imagePosA).br; - patternShader->u_pattern_tl_b = (*imagePosB).tl; - patternShader->u_pattern_br_b = (*imagePosB).br; - patternShader->u_mix = properties.pattern.value.t; - patternShader->u_opacity = properties.opacity; - - LatLng latLng = state.getLatLng(); - double centerX = state.lngX(latLng.longitude); - double centerY = state.latY(latLng.latitude); - float scale = 1 / std::pow(2, state.getZoomFraction()); - - std::array<float, 2> sizeA = (*imagePosA).size; - mat3 matrixA; - matrix::identity(matrixA); - matrix::scale(matrixA, matrixA, - 1.0f / (sizeA[0] * properties.pattern.value.fromScale), - 1.0f / (sizeA[1] * properties.pattern.value.fromScale)); - matrix::translate(matrixA, matrixA, - std::fmod(centerX, sizeA[0] * properties.pattern.value.fromScale), - std::fmod(centerY, sizeA[1] * properties.pattern.value.fromScale)); - matrix::rotate(matrixA, matrixA, -state.getAngle()); - matrix::scale(matrixA, matrixA, - scale * state.getWidth() / 2, - -scale * state.getHeight() / 2); - - std::array<float, 2> sizeB = (*imagePosB).size; - mat3 matrixB; - matrix::identity(matrixB); - matrix::scale(matrixB, matrixB, - 1.0f / (sizeB[0] * properties.pattern.value.toScale), - 1.0f / (sizeB[1] * properties.pattern.value.toScale)); - matrix::translate(matrixB, matrixB, - std::fmod(centerX, sizeB[0] * properties.pattern.value.toScale), - std::fmod(centerY, sizeB[1] * properties.pattern.value.toScale)); - matrix::rotate(matrixB, matrixB, -state.getAngle()); - matrix::scale(matrixB, matrixB, - scale * state.getWidth() / 2, - -scale * state.getHeight() / 2); - - patternShader->u_patternmatrix_a = matrixA; - patternShader->u_patternmatrix_b = matrixB; - - VertexArrayObject::Unbind(); - backgroundBuffer.bind(glObjectStore); - patternShader->bind(0); - spriteAtlas->bind(true, glObjectStore); - } else { - Color color = properties.color; - color[0] *= properties.opacity; - color[1] *= properties.opacity; - color[2] *= properties.opacity; - color[3] *= properties.opacity; - - config.program = plainShader->getID(); - plainShader->u_matrix = identityMatrix; - plainShader->u_color = color; - backgroundArray.bind(*plainShader, backgroundBuffer, BUFFER_OFFSET(0), glObjectStore); - } - - config.stencilTest = GL_FALSE; - config.depthFunc.reset(); - config.depthTest = GL_TRUE; - config.depthMask = GL_FALSE; - setDepthSublayer(0); - - MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); -} - mat4 Painter::translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const TileID &id, TranslateAnchorType anchor) { if (translation[0] == 0 && translation[1] == 0) { return matrix; diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 4a07d651d1..e58985dcc1 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -181,13 +181,6 @@ private: std::unique_ptr<CollisionBoxShader> collisionBoxShader; std::unique_ptr<CircleShader> circleShader; - StaticVertexBuffer backgroundBuffer = { - { -1, -1 }, { 1, -1 }, - { -1, 1 }, { 1, 1 } - }; - - VertexArrayObject backgroundArray; - // Set up the stencil quad we're using to generate the stencil mask. StaticVertexBuffer tileStencilBuffer = { // top left triangle @@ -203,6 +196,8 @@ private: VertexArrayObject coveringPlainArray; VertexArrayObject coveringRasterArray; + VertexArrayObject backgroundPatternArray; + VertexArrayObject backgroundArray; // Set up the tile boundary lines we're using to draw the tile outlines. StaticVertexBuffer tileBorderBuffer = { diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp new file mode 100644 index 0000000000..fbca8b59f7 --- /dev/null +++ b/src/mbgl/renderer/painter_background.cpp @@ -0,0 +1,105 @@ +#include <mbgl/renderer/painter.hpp> + +#include <mbgl/layer/background_layer.hpp> +#include <mbgl/shader/pattern_shader.hpp> +#include <mbgl/shader/plain_shader.hpp> +#include <mbgl/util/mat4.hpp> +#include <mbgl/util/tile_cover.hpp> + +using namespace mbgl; + +void Painter::renderBackground(const BackgroundLayer& layer) { + // Note that for bottommost layers without a pattern, the background color is drawn with + // glClear rather than this method. + const BackgroundPaintProperties& properties = layer.paint; + + const bool isPatterned = !properties.pattern.value.to.empty();// && false; + optional<SpriteAtlasPosition> imagePosA; + optional<SpriteAtlasPosition> imagePosB; + + if (isPatterned) { + imagePosA = spriteAtlas->getPosition(properties.pattern.value.from, true); + imagePosB = spriteAtlas->getPosition(properties.pattern.value.to, true); + + if (!imagePosA || !imagePosB) + return; + + config.program = patternShader->getID(); + patternShader->u_matrix = identityMatrix; + patternShader->u_pattern_tl_a = (*imagePosA).tl; + patternShader->u_pattern_br_a = (*imagePosA).br; + patternShader->u_pattern_tl_b = (*imagePosB).tl; + patternShader->u_pattern_br_b = (*imagePosB).br; + patternShader->u_mix = properties.pattern.value.t; + patternShader->u_opacity = properties.opacity; + + spriteAtlas->bind(true, glObjectStore); + backgroundPatternArray.bind(*patternShader, tileStencilBuffer, BUFFER_OFFSET(0), glObjectStore); + + } else { + Color color = properties.color; + color[0] *= properties.opacity; + color[1] *= properties.opacity; + color[2] *= properties.opacity; + color[3] *= properties.opacity; + + config.program = plainShader->getID(); + plainShader->u_color = color; + backgroundArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0), glObjectStore); + } + + config.stencilTest = GL_FALSE; + config.depthFunc.reset(); + config.depthTest = GL_TRUE; + config.depthMask = GL_FALSE; + setDepthSublayer(0); + + auto tileIDs = tileCover(state, state.getIntegerZoom(), state.getIntegerZoom()); + + for (auto &id: tileIDs) { + mat4 vtxMatrix; + state.matrixFor(vtxMatrix, id, id.z); + matrix::multiply(vtxMatrix, projMatrix, vtxMatrix); + + if (isPatterned) { + patternShader->u_matrix = vtxMatrix; + const float factor = util::EXTENT / util::tileSize; + + std::array<int, 2> imageSizeScaledA = {{ + (int)((*imagePosA).size[0] * properties.pattern.value.fromScale), + (int)((*imagePosA).size[1] * properties.pattern.value.fromScale) + }}; + std::array<int, 2> imageSizeScaledB = {{ + (int)((*imagePosB).size[0] * properties.pattern.value.toScale), + (int)((*imagePosB).size[1] * properties.pattern.value.toScale) + }}; + + patternShader->u_patternscale_a = {{ + 1.0f / (factor * imageSizeScaledA[0]), + 1.0f / (factor * imageSizeScaledA[1]) + }}; + patternShader->u_patternscale_b = {{ + 1.0f / (factor * imageSizeScaledB[0]), + 1.0f / (factor * imageSizeScaledB[1]) + }}; + + float offsetAx = (std::fmod(util::tileSize, imageSizeScaledA[0]) * id.x) / (float)imageSizeScaledA[0]; + float offsetAy = (std::fmod(util::tileSize, imageSizeScaledA[1]) * id.y) / (float)imageSizeScaledA[1]; + + float offsetBx = (std::fmod(util::tileSize, imageSizeScaledB[0]) * id.x) / (float)imageSizeScaledB[0]; + float offsetBy = (std::fmod(util::tileSize, imageSizeScaledB[1]) * id.y) / (float)imageSizeScaledB[1]; + + patternShader->u_offset_a = std::array<float, 2>{{offsetAx, offsetAy}}; + patternShader->u_offset_b = std::array<float, 2>{{offsetBx, offsetBy}}; + + + } else { + plainShader->u_matrix = vtxMatrix; + Color color = properties.color; + plainShader->u_color = color; + } + + MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)tileStencilBuffer.index())); + } + +} diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index a8be7255bf..d65745f4e7 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -6,7 +6,6 @@ #include <mbgl/shader/outline_shader.hpp> #include <mbgl/shader/pattern_shader.hpp> #include <mbgl/shader/plain_shader.hpp> -#include <mbgl/util/mat3.hpp> using namespace mbgl; @@ -68,17 +67,6 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI const float factor = (util::EXTENT / util::tileSize / std::pow(2, state.getIntegerZoom() - id.sourceZ)); - mat3 patternMatrixA; - matrix::identity(patternMatrixA); - matrix::scale(patternMatrixA, patternMatrixA, - 1.0f / ((*posA).size[0] * factor * properties.pattern.value.fromScale), - 1.0f / ((*posA).size[1] * factor * properties.pattern.value.fromScale)); - mat3 patternMatrixB; - matrix::identity(patternMatrixB); - matrix::scale(patternMatrixB, patternMatrixB, - 1.0f / ((*posB).size[0] * factor * properties.pattern.value.toScale), - 1.0f / ((*posB).size[1] * factor * properties.pattern.value.toScale)); - config.program = patternShader->getID(); patternShader->u_matrix = vtxMatrix; patternShader->u_pattern_tl_a = (*posA).tl; @@ -88,8 +76,6 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI patternShader->u_opacity = properties.opacity; patternShader->u_image = 0; patternShader->u_mix = properties.pattern.value.t; - patternShader->u_patternmatrix_a = patternMatrixA; - patternShader->u_patternmatrix_b = patternMatrixB; std::array<int, 2> imageSizeScaledA = {{ (int)((*posA).size[0] * properties.pattern.value.fromScale), @@ -100,6 +86,15 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI (int)((*posB).size[1] * properties.pattern.value.toScale) }}; + patternShader->u_patternscale_a = {{ + 1.0f / (factor * imageSizeScaledA[0]), + 1.0f / (factor * imageSizeScaledA[1]) + }}; + patternShader->u_patternscale_b = {{ + 1.0f / (factor * imageSizeScaledB[0]), + 1.0f / (factor * imageSizeScaledB[1]) + }}; + float offsetAx = (std::fmod(util::tileSize, imageSizeScaledA[0]) * id.x) / (float)imageSizeScaledA[0]; float offsetAy = (std::fmod(util::tileSize, imageSizeScaledA[1]) * id.y) / (float)imageSizeScaledA[1]; diff --git a/src/mbgl/shader/pattern.vertex.glsl b/src/mbgl/shader/pattern.vertex.glsl index 4ff51cad64..1363f17300 100644 --- a/src/mbgl/shader/pattern.vertex.glsl +++ b/src/mbgl/shader/pattern.vertex.glsl @@ -1,6 +1,6 @@ uniform mat4 u_matrix; -uniform mat3 u_patternmatrix_a; -uniform mat3 u_patternmatrix_b; +uniform vec2 u_patternscale_a; +uniform vec2 u_patternscale_b; uniform vec2 u_offset_a; uniform vec2 u_offset_b; @@ -12,6 +12,6 @@ varying vec2 v_pos_b; void main() { gl_Position = u_matrix * vec4(a_pos, 0, 1); - v_pos_a = (u_patternmatrix_a * vec3(a_pos, 1)).xy + u_offset_a; - v_pos_b = (u_patternmatrix_b * vec3(a_pos, 1)).xy + u_offset_b; + v_pos_a = u_patternscale_a * a_pos + u_offset_a; + v_pos_b = u_patternscale_b * a_pos + u_offset_b; } diff --git a/src/mbgl/shader/pattern_shader.hpp b/src/mbgl/shader/pattern_shader.hpp index 8692f6ed39..0898dc0b8c 100644 --- a/src/mbgl/shader/pattern_shader.hpp +++ b/src/mbgl/shader/pattern_shader.hpp @@ -20,8 +20,8 @@ public: Uniform<GLfloat> u_opacity = {"u_opacity", *this}; Uniform<GLfloat> u_mix = {"u_mix", *this}; Uniform<GLint> u_image = {"u_image", *this}; - UniformMatrix<3> u_patternmatrix_a = {"u_patternmatrix_a", *this}; - UniformMatrix<3> u_patternmatrix_b = {"u_patternmatrix_b", *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}; }; |