summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2016-03-28 11:57:45 -0700
committerAnsis Brammanis <brammanis@gmail.com>2016-03-28 16:59:39 -0700
commitb352bb81d8259f1e52fe933a20f782d1c4327f1a (patch)
tree4b19f608bf8e4a9d0994035b90d812d9774989b4 /src
parent4522bf02c9f5510ca2641e96a9e7a41048f00efe (diff)
downloadqtlocation-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.cpp84
-rw-r--r--src/mbgl/renderer/painter.hpp9
-rw-r--r--src/mbgl/renderer/painter_background.cpp105
-rw-r--r--src/mbgl/renderer/painter_fill.cpp23
-rw-r--r--src/mbgl/shader/pattern.vertex.glsl8
-rw-r--r--src/mbgl/shader/pattern_shader.hpp4
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};
};