diff options
author | Alex Wilson <alex.wilson@nokia.com> | 2012-03-27 15:28:20 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-28 01:26:21 +0200 |
commit | 6cdedaf13ccd44fad6729e43b4b79d75572fe9ca (patch) | |
tree | 2e07c67b1e9df98a7a2ff42ff41f7924a36a10d3 /src | |
parent | e900cf4a74b241e7f68b18a8768c062d06de8e60 (diff) | |
download | qtlocation-6cdedaf13ccd44fad6729e43b4b79d75572fe9ca.tar.gz |
Maps: "snap" and disable linear filtering near whole zoom numbers
Near whole zoom numbers, this patch enables "snapping" behaviour,
so that zoom = 0.97 and zoom = 1.01 will display the same result on
screen. When this snapping is active, textures are now displayed with
linear filtering disabled, giving a much sharper appearance.
Depends on http://codereview.qt-project.org/21497 in Qt3d for support
for disabling bilinear filtering on already-uploaded textures.
Task-number: QTBUG-24940
Change-Id: I791e6469781ef73f53394a8d62ff61c725a5ff2a
Reviewed-by: Ian Chen <ian.1.chen@nokia.com>
Reviewed-by: Cristian Adam <cristian.adam@nokia.com>
Reviewed-by: Aaron McCarthy <aaron.mccarthy@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/location/maps/qgeomapgeometry.cpp | 34 | ||||
-rw-r--r-- | src/location/maps/qgeotiledmapdata.cpp | 18 |
2 files changed, 50 insertions, 2 deletions
diff --git a/src/location/maps/qgeomapgeometry.cpp b/src/location/maps/qgeomapgeometry.cpp index 215de3ff..3a10ca03 100644 --- a/src/location/maps/qgeomapgeometry.cpp +++ b/src/location/maps/qgeomapgeometry.cpp @@ -105,6 +105,7 @@ public: bool useVerticalLock_; bool verticalLock_; + bool linearScaling_; void addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture); @@ -117,6 +118,7 @@ public: QGLSceneNode *buildGeometry(const QGeoTileSpec &spec); void setTileBounds(const QSet<QGeoTileSpec> &tiles); void setupCamera(); + void setScalingOnTextures(); void paintGL(QGLPainter *painter); @@ -157,6 +159,14 @@ void QGeoMapGeometry::setCameraData(const QGeoCameraData &cameraData) Q_D(QGeoMapGeometry); d->cameraData_ = cameraData; d->intZoomLevel_ = static_cast<int>(floor(d->cameraData_.zoomLevel())); + float delta = cameraData.zoomLevel() - d->intZoomLevel_; + if (qAbs(delta) < 0.05) { + d->linearScaling_ = false; + d->setScalingOnTextures(); + } else { + d->linearScaling_ = true; + d->setScalingOnTextures(); + } d->sideLength_ = 1 << d->intZoomLevel_; } @@ -231,6 +241,7 @@ QGeoMapGeometryPrivate::QGeoMapGeometryPrivate(QGeoMapGeometry *geometry) screenHeight_(0.0), useVerticalLock_(false), verticalLock_(false), + linearScaling_(true), q_ptr(geometry) {} QGeoMapGeometryPrivate::~QGeoMapGeometryPrivate() @@ -345,8 +356,31 @@ QGLSceneNode *QGeoMapGeometryPrivate::buildGeometry(const QGeoTileSpec &spec) return builder.finalizedSceneNode(); } +void QGeoMapGeometryPrivate::setScalingOnTextures() +{ + if (!linearScaling_) { + foreach (const QSharedPointer<QGeoTileTexture> &tex, textures_.values()) { + tex->texture->setBindOptions(tex->texture->bindOptions() & + (~QGLTexture2D::LinearFilteringBindOption)); + } + } else { + foreach (const QSharedPointer<QGeoTileTexture> &tex, textures_.values()) { + tex->texture->setBindOptions(tex->texture->bindOptions() | + (QGLTexture2D::LinearFilteringBindOption)); + } + } +} + void QGeoMapGeometryPrivate::addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture) { + if (linearScaling_) { + texture->texture->setBindOptions(texture->texture->bindOptions() | + (QGLTexture2D::LinearFilteringBindOption)); + } else { + texture->texture->setBindOptions(texture->texture->bindOptions() & + (~QGLTexture2D::LinearFilteringBindOption)); + } + QGLSceneNode *node = nodes_.value(spec, 0); if (!node) { node = buildGeometry(spec); diff --git a/src/location/maps/qgeotiledmapdata.cpp b/src/location/maps/qgeotiledmapdata.cpp index bf8df5f9..1ecc26e8 100644 --- a/src/location/maps/qgeotiledmapdata.cpp +++ b/src/location/maps/qgeotiledmapdata.cpp @@ -266,10 +266,24 @@ void QGeoTiledMapDataPrivate::changeCameraData(const QGeoCameraData &oldCameraDa map_->cameraData().setCenter(coord); } - cameraTiles_->setCamera(map_->cameraData()); + // For zoomlevel, "snap" 0.05 either side of a whole number. + // This is so that when we turn off bilinear scaling, we're + // snapped to the exact pixel size of the tiles + QGeoCameraData cam = map_->cameraData(); + int izl = static_cast<int>(floor(cam.zoomLevel())); + float delta = cam.zoomLevel() - izl; + if (delta > 0.5) { + izl++; + delta -= 1.0; + } + if (qAbs(delta) < 0.05) { + cam.setZoomLevel(izl); + } + + cameraTiles_->setCamera(cam); visibleTiles_ = cameraTiles_->tiles(); - mapGeometry_->setCameraData(map_->cameraData()); + mapGeometry_->setCameraData(cam); mapGeometry_->setVisibleTiles(visibleTiles_); if (mapImages_) { |