summaryrefslogtreecommitdiff
path: root/src/mbgl/map
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2018-01-22 14:46:13 -0800
committerKonstantin Käfer <mail@kkaefer.com>2018-01-24 17:02:18 -0800
commitfcc3808c83102d272006c33fb25f9c0307b466c5 (patch)
treef4357e542bd037f0312135453c2a9a14cbf34def /src/mbgl/map
parentd511f74ce45b8d18c376e7c3d806819cbe438627 (diff)
downloadqtlocation-mapboxgl-fcc3808c83102d272006c33fb25f9c0307b466c5.tar.gz
[core] align raster imagery rendering to pixel rid to avoid blurriness
Diffstat (limited to 'src/mbgl/map')
-rw-r--r--src/mbgl/map/transform_state.cpp21
-rw-r--r--src/mbgl/map/transform_state.hpp2
2 files changed, 19 insertions, 4 deletions
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index d79a65c61e..18d2c24aee 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -27,7 +27,7 @@ void TransformState::matrixFor(mat4& matrix, const UnwrappedTileID& tileID) cons
matrix::scale(matrix, matrix, s / util::EXTENT, s / util::EXTENT, 1);
}
-void TransformState::getProjMatrix(mat4& projMatrix, uint16_t nearZ) const {
+void TransformState::getProjMatrix(mat4& projMatrix, uint16_t nearZ, bool aligned) const {
if (size.isEmpty()) {
return;
}
@@ -63,8 +63,8 @@ void TransformState::getProjMatrix(mat4& projMatrix, uint16_t nearZ) const {
matrix::rotate_z(projMatrix, projMatrix, getAngle() + getNorthOrientationAngle());
- matrix::translate(projMatrix, projMatrix, pixel_x() - size.width / 2.0f,
- pixel_y() - size.height / 2.0f, 0);
+ const double dx = pixel_x() - size.width / 2.0f, dy = pixel_y() - size.height / 2.0f;
+ matrix::translate(projMatrix, projMatrix, dx, dy, 0);
if (axonometric) {
// mat[11] controls perspective
@@ -77,6 +77,21 @@ void TransformState::getProjMatrix(mat4& projMatrix, uint16_t nearZ) const {
matrix::scale(projMatrix, projMatrix, 1, 1,
1.0 / Projection::getMetersPerPixelAtLatitude(getLatLng(LatLng::Unwrapped).latitude(), getZoom()));
+
+ // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles.
+ // We're rounding the (floating point) x/y values to achieve to avoid rendering raster images to fractional
+ // coordinates. Additionally, we adjust by half a pixel in either direction in case that viewport dimension
+ // is an odd integer to preserve rendering to the pixel grid. We're rotating this shift based on the angle
+ // of the transformation so that 0°, 90°, 180°, and 270° rasters are crisp, and adjust the shift so that
+ // it is always <= 0.5 pixels.
+ if (aligned) {
+ const float xShift = float(size.width % 2) / 2, yShift = float(size.height % 2) / 2;
+ const double angleCos = std::cos(angle), angleSin = std::sin(angle);
+ double devNull;
+ const float dxa = -std::modf(dx, &devNull) + angleCos * xShift + angleSin * yShift;
+ const float dya = -std::modf(dy, &devNull) + angleCos * yShift + angleSin * xShift;
+ matrix::translate(projMatrix, projMatrix, dxa > 0.5 ? dxa - 1 : dxa, dya > 0.5 ? dya - 1 : dya, 0);
+ }
}
#pragma mark - Dimensions
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index 0dd6d5a15e..451802034d 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -25,7 +25,7 @@ public:
// Matrix
void matrixFor(mat4&, const UnwrappedTileID&) const;
- void getProjMatrix(mat4& matrix, uint16_t nearZ = 1) const;
+ void getProjMatrix(mat4& matrix, uint16_t nearZ = 1, bool aligned = false) const;
// Dimensions
Size getSize() const;