summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabian Bumberger <fbumberger@rim.com>2013-11-20 19:23:47 +0100
committerFabian Bumberger <fbumberger@rim.com>2014-01-28 16:57:17 +0100
commit40523fde410adf74d021bec4869e9bf6a7aef39c (patch)
treeceba858c1e7795665ec976cb676eafb17f8d4d1f
parentc056043611675eb894a6d4417324438b28fd952c (diff)
Prepare to get rid of the Qt3D dependency
This patch puts most Qt3D dependencies in ifdefs and thus is the first step to eliminate the dependency. Change-Id: Ifa3c3213aacd8dd50aec18fedd4df3d3c34671e8 Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
-rw-r--r--src/imports/location/location.pro19
-rw-r--r--src/imports/location/mapnode_qt3d.cpp (renamed from src/imports/location/mapnode.cpp)2
-rw-r--r--src/imports/location/mapnode_qt3d_p.h (renamed from src/imports/location/mapnode_p.h)0
-rw-r--r--src/imports/location/mapnode_sg.cpp64
-rw-r--r--src/imports/location/mapnode_sg_p.h68
-rw-r--r--src/imports/location/qdeclarativegeomap.cpp8
-rw-r--r--src/imports/location/qdeclarativegeomap_p.h4
-rw-r--r--src/location/maps/maps.pri15
-rw-r--r--src/location/maps/qgeomap.cpp2
-rw-r--r--src/location/maps/qgeomap_p.h2
-rw-r--r--src/location/maps/qgeomapdata.cpp9
-rw-r--r--src/location/maps/qgeomapdata_p.h2
-rw-r--r--src/location/maps/qgeomapdata_p_p.h3
-rw-r--r--src/location/maps/qgeomapscene.cpp517
-rw-r--r--src/location/maps/qgeomapscene_p.h9
-rw-r--r--src/location/maps/qgeomapscene_p_p.h144
-rw-r--r--src/location/maps/qgeomapscene_sg.cpp65
-rw-r--r--src/location/maps/qgeomapsscene_qt3d.cpp420
-rw-r--r--src/location/maps/qgeotilecache.cpp9
-rw-r--r--src/location/maps/qgeotilecache_p.h10
-rw-r--r--src/location/maps/qgeotiledmapdata.cpp11
-rw-r--r--src/location/maps/qgeotiledmapdata_p.h3
-rw-r--r--src/location/maps/qgeotiledmapdata_p_p.h2
-rw-r--r--src/plugins/geoservices/nokia/nokia.pro5
-rw-r--r--src/src.pro11
25 files changed, 882 insertions, 522 deletions
diff --git a/src/imports/location/location.pro b/src/imports/location/location.pro
index 8dccfa2d..c437eb77 100644
--- a/src/imports/location/location.pro
+++ b/src/imports/location/location.pro
@@ -1,4 +1,4 @@
-QT += quick-private network positioning-private location-private qml-private 3d core-private gui-private
+QT += quick-private network positioning-private location-private qml-private core-private gui-private
INCLUDEPATH += ../../location
INCLUDEPATH += ../../location/maps
@@ -15,6 +15,21 @@ win32 {
}
}
+qtHaveModule(3d):!no_qt3d {
+ QT += 3d
+
+ SOURCES += mapnode_qt3d.cpp
+
+ HEADERS += mapnode_qt3d_p.h
+} else {
+ DEFINES += NO_QT3D_RENDERER
+ SOURCES += mapnode_sg.cpp
+
+ HEADERS += mapnode_sg_p.h
+}
+
+
+
HEADERS += \
qdeclarativegeomapitemview_p.h \
qdeclarativegeomapmouseevent_p.h \
@@ -29,7 +44,6 @@ HEADERS += \
qdeclarativegeomaptype_p.h \
qdeclarativegeomapitembase_p.h \
qdeclarativegeomapquickitem_p.h \
- mapnode_p.h \
qdeclarativecirclemapitem_p.h \
qdeclarativerectanglemapitem_p.h \
qdeclarativepolygonmapitem_p.h \
@@ -56,7 +70,6 @@ SOURCES += \
qdeclarativegeomaptype.cpp \
qdeclarativegeomapitembase.cpp \
qdeclarativegeomapquickitem.cpp \
- mapnode.cpp \
qdeclarativecirclemapitem.cpp \
qdeclarativerectanglemapitem.cpp \
qdeclarativepolygonmapitem.cpp \
diff --git a/src/imports/location/mapnode.cpp b/src/imports/location/mapnode_qt3d.cpp
index 3c557d35..f02b8158 100644
--- a/src/imports/location/mapnode.cpp
+++ b/src/imports/location/mapnode_qt3d.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "mapnode_p.h"
+#include "mapnode_qt3d_p.h"
#include "qgeomap_p.h"
#include <Qt3D/qglpainter.h>
#include <Qt3D/QGLFramebufferObjectSurface>
diff --git a/src/imports/location/mapnode_p.h b/src/imports/location/mapnode_qt3d_p.h
index 911b8f77..911b8f77 100644
--- a/src/imports/location/mapnode_p.h
+++ b/src/imports/location/mapnode_qt3d_p.h
diff --git a/src/imports/location/mapnode_sg.cpp b/src/imports/location/mapnode_sg.cpp
new file mode 100644
index 00000000..3a44e0b1
--- /dev/null
+++ b/src/imports/location/mapnode_sg.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "mapnode_sg_p.h"
+
+MapNode::MapNode(QGeoMap *map) :
+ m_map(map)
+{
+}
+
+MapNode::~MapNode()
+{
+
+}
+
+void MapNode::setSize(const QSize &size)
+{
+ if (size == m_size)
+ return;
+ m_size = size;
+ markDirty(DirtyGeometry);
+}
+
+void MapNode::update()
+{
+
+}
diff --git a/src/imports/location/mapnode_sg_p.h b/src/imports/location/mapnode_sg_p.h
new file mode 100644
index 00000000..02c2ddd9
--- /dev/null
+++ b/src/imports/location/mapnode_sg_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAPNODE_SG_P_H
+#define MAPNODE_SG_P_H
+
+#include <QSGNode>
+
+QT_BEGIN_NAMESPACE
+
+class QGeoMap;
+
+class MapNode : public QSGNode
+{
+public:
+ explicit MapNode(QGeoMap *m_map);
+ ~MapNode();
+
+ void setSize(const QSize &size);
+ QSize size() const { return m_size; }
+ void update();
+
+private:
+ QGeoMap *m_map;
+ QSize m_size;
+};
+
+QT_END_NAMESPACE
+
+#endif // MAPNODE_SG_P_H
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp
index bc97bed1..02f65437 100644
--- a/src/imports/location/qdeclarativegeomap.cpp
+++ b/src/imports/location/qdeclarativegeomap.cpp
@@ -54,7 +54,13 @@
#include "qgeocameradata_p.h"
#include "qgeocameracapabilities_p.h"
#include "qgeomapcontroller_p.h"
-#include "mapnode_p.h"
+
+#ifdef NO_QT3D_RENDERER
+#include "mapnode_sg_p.h"
+#else
+#include "mapnode_qt3d_p.h"
+#endif
+
#include <cmath>
#include <QtPositioning/QGeoCoordinate>
diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h
index b024d006..b231c76e 100644
--- a/src/imports/location/qdeclarativegeomap_p.h
+++ b/src/imports/location/qdeclarativegeomap_p.h
@@ -223,10 +223,6 @@ private:
QDeclarativeGeoMapGestureArea *gestureArea_;
- void paintGL(QGLPainter *painter);
- void earlyDraw(QGLPainter *painter);
- void restoreDefaults(QGLPainter *painter);
-
QQuickWindow *window_;
int touchTimer_;
diff --git a/src/location/maps/maps.pri b/src/location/maps/maps.pri
index 3a43c5ea..df0b0f2d 100644
--- a/src/location/maps/maps.pri
+++ b/src/location/maps/maps.pri
@@ -1,7 +1,16 @@
INCLUDEPATH += maps
-QT_PRIVATE += gui 3d
+QT_PRIVATE += gui
+
+qtHaveModule(3d):!no_qt3d {
+ QT_PRIVATE += 3d
+ SOURCES += maps/qgeomapsscene_qt3d.cpp
+} else {
+ QT_PRIVATE += quick
+ DEFINES += NO_QT3D_RENDERER
+ SOURCES += maps/qgeomapscene_sg.cpp
+}
PUBLIC_HEADERS += \
maps/qgeocodereply.h \
@@ -55,7 +64,8 @@ PRIVATE_HEADERS += \
maps/qgeotiledmapreply_p_p.h \
maps/qgeotilespec_p.h \
maps/qgeotilespec_p_p.h \
- maps/qcache3q_p.h
+ maps/qcache3q_p.h \
+ maps/qgeomapscene_p_p.h
SOURCES += \
maps/qgeocameracapabilities.cpp \
@@ -89,3 +99,4 @@ SOURCES += \
maps/qgeotilespec.cpp
+
diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp
index 1f2b6e9b..c9e79fcb 100644
--- a/src/location/maps/qgeomap.cpp
+++ b/src/location/maps/qgeomap.cpp
@@ -95,6 +95,7 @@ QGeoMapController *QGeoMap::mapController()
return mapData_->mapController();
}
+#ifndef NO_QT3D_RENDERER
QGLCamera *QGeoMap::glCamera() const
{
return mapData_->glCamera();
@@ -104,6 +105,7 @@ void QGeoMap::paintGL(QGLPainter *painter)
{
mapData_->paintGL(painter);
}
+#endif
void QGeoMap::resize(int width, int height)
{
diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h
index e956d886..d27fd178 100644
--- a/src/location/maps/qgeomap_p.h
+++ b/src/location/maps/qgeomap_p.h
@@ -87,8 +87,10 @@ public:
QGeoMapController *mapController();
+#ifndef NO_QT3D_RENDERER
QGLCamera *glCamera() const;
void paintGL(QGLPainter *painter);
+#endif
void resize(int width, int height);
int width() const;
diff --git a/src/location/maps/qgeomapdata.cpp b/src/location/maps/qgeomapdata.cpp
index 69e11530..7cb74920 100644
--- a/src/location/maps/qgeomapdata.cpp
+++ b/src/location/maps/qgeomapdata.cpp
@@ -91,11 +91,13 @@ QGeoMapController *QGeoMapData::mapController()
return d->mapController();
}
+#ifndef NO_QT3D_RENDERER
QGLCamera *QGeoMapData::glCamera() const
{
Q_D(const QGeoMapData);
return d->glCamera();
}
+#endif
void QGeoMapData::resize(int width, int height)
{
@@ -178,7 +180,9 @@ QGeoMapDataPrivate::QGeoMapDataPrivate(QGeoMappingManagerEngine *engine, QGeoMap
: width_(0),
height_(0),
aspectRatio_(0.0),
+#ifndef NO_QT3D_RENDERER
camera_(new QGLCamera()),
+#endif
map_(parent),
engine_(engine),
controller_(0),
@@ -190,8 +194,9 @@ QGeoMapDataPrivate::QGeoMapDataPrivate(QGeoMappingManagerEngine *engine, QGeoMap
QGeoMapDataPrivate::~QGeoMapDataPrivate()
{
// controller_ is a child of map_, don't need to delete it here
-
+#ifndef NO_QT3D_RENDERER
delete camera_;
+#endif
// TODO map items are not deallocated!
// However: how to ensure this is done in rendering thread?
}
@@ -213,10 +218,12 @@ QGeoMapController *QGeoMapDataPrivate::mapController()
return controller_;
}
+#ifndef NO_QT3D_RENDERER
QGLCamera *QGeoMapDataPrivate::glCamera() const
{
return camera_;
}
+#endif
void QGeoMapDataPrivate::setCameraData(const QGeoCameraData &cameraData)
{
diff --git a/src/location/maps/qgeomapdata_p.h b/src/location/maps/qgeomapdata_p.h
index 35ed32c2..40a1b0d2 100644
--- a/src/location/maps/qgeomapdata_p.h
+++ b/src/location/maps/qgeomapdata_p.h
@@ -83,8 +83,10 @@ public:
QGeoMapController *mapController();
+#ifndef NO_QT3D_RENDERER
QGLCamera *glCamera() const;
virtual void paintGL(QGLPainter *painter) = 0;
+#endif
void resize(int width, int height);
int width() const;
diff --git a/src/location/maps/qgeomapdata_p_p.h b/src/location/maps/qgeomapdata_p_p.h
index 5e81d457..0c1238a9 100644
--- a/src/location/maps/qgeomapdata_p_p.h
+++ b/src/location/maps/qgeomapdata_p_p.h
@@ -87,8 +87,9 @@ public:
QGeoMapController *mapController();
+#ifndef NO_QT3D_RENDERER
QGLCamera *glCamera() const;
-
+#endif
void setCameraData(const QGeoCameraData &cameraData);
QGeoCameraData cameraData() const;
diff --git a/src/location/maps/qgeomapscene.cpp b/src/location/maps/qgeomapscene.cpp
index cb24861f..feade05e 100644
--- a/src/location/maps/qgeomapscene.cpp
+++ b/src/location/maps/qgeomapscene.cpp
@@ -49,100 +49,21 @@
#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QtPositioning/private/qdoublevector3d_p.h>
-#include <Qt3D/qglscenenode.h>
-#include <Qt3D/qglbuilder.h>
-#include <Qt3D/qglmaterial.h>
-#include <Qt3D/qgltexture2d.h>
-#include <Qt3D/qgeometrydata.h>
-#include <Qt3D/qglcamera.h>
-#include <Qt3D/qglpainter.h>
-#include <Qt3D/QGLLightParameters>
-
-
#include <QHash>
#include <QPointF>
#include <cmath>
-QT_BEGIN_NAMESPACE
+#include "qgeomapscene_p_p.h"
-class QGeoMapScenePrivate
-{
-public:
- explicit QGeoMapScenePrivate(QGeoMapScene *scene);
- ~QGeoMapScenePrivate();
-
- QSize screenSize_; // in pixels
- int tileSize_; // the pixel resolution for each tile
- QGeoCameraData cameraData_;
- QSet<QGeoTileSpec> visibleTiles_;
-
- QGLCamera *camera_;
- QGLSceneNode *sceneNode_;
- QGLLightParameters* light_;
-
- // scales up the tile geometry and the camera altitude, resulting in no visible effect
- // other than to control the accuracy of the render by keeping the values in a sensible range
- double scaleFactor_;
-
- // rounded down, positive zoom is zooming in, corresponding to reduced altitude
- int intZoomLevel_;
-
- // mercatorToGrid transform
- // the number of tiles in each direction for the whole map (earth) at the current zoom level.
- // it is 1<<zoomLevel
- int sideLength_;
-
- QHash<QGeoTileSpec, QGLSceneNode *> nodes_;
- QHash<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > textures_;
- QList<QSharedPointer<QGeoTileTexture> > newUploads_;
-
- // tilesToGrid transform
- int minTileX_; // the minimum tile index, i.e. 0 to sideLength which is 1<< zoomLevel
- int minTileY_;
- int maxTileX_;
- int maxTileY_;
- int tileZ_; // caches the zoom level for this tile set
- int tileXWrapsBelow_; // the wrap point as a tile index
-
- // cameraToGrid transform
- double mercatorCenterX_; // centre of camera in grid space (0 to sideLength)
- double mercatorCenterY_;
- double mercatorWidth_; // width of camera in grid space (0 to sideLength)
- double mercatorHeight_;
-
- // screenToWindow transform
- double screenOffsetX_; // in pixels
- double screenOffsetY_; // in pixels
- // cameraToScreen transform
- double screenWidth_; // in pixels
- double screenHeight_; // in pixels
-
- bool useVerticalLock_;
- bool verticalLock_;
- bool linearScaling_;
-
- void addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture);
-
- QDoubleVector2D screenPositionToMercator(const QDoubleVector2D &pos) const;
- QDoubleVector2D mercatorToScreenPosition(const QDoubleVector2D &mercator) const;
-
- void setVisibleTiles(const QSet<QGeoTileSpec> &tiles);
- void removeTiles(const QSet<QGeoTileSpec> &oldTiles);
- void updateTiles(const QSet<QGeoTileSpec> &tiles);
- QGeometryData buildGeometry(const QGeoTileSpec &spec);
- QGLSceneNode *buildSceneNodeFromGeometry(const QGeometryData &geom);
- void setTileBounds(const QSet<QGeoTileSpec> &tiles);
- void setupCamera();
- void setScalingOnTextures();
-
- void paintGL(QGLPainter *painter);
-
-private:
- QGeoMapScene *q_ptr;
- Q_DECLARE_PUBLIC(QGeoMapScene)
-};
+#ifndef NO_QT3D_RENDERER
+#include <QGLLightParameters>
+#include <QGLSceneNode>
+#include <QGLCamera>
+#endif
+
+QT_BEGIN_NAMESPACE
QGeoMapScene::QGeoMapScene()
: QObject(),
@@ -211,17 +132,17 @@ QDoubleVector2D QGeoMapScene::mercatorToScreenPosition(const QDoubleVector2D &me
return d->mercatorToScreenPosition(mercator);
}
-QGLCamera *QGeoMapScene::camera() const
-{
- Q_D(const QGeoMapScene);
- return d->camera_;
-}
+//QGLCamera *QGeoMapScene::camera() const
+//{
+// Q_D(const QGeoMapScene);
+// return d->camera_;
+//}
-QGLSceneNode *QGeoMapScene::sceneNode() const
-{
- Q_D(const QGeoMapScene);
- return d->sceneNode_;
-}
+//QGLSceneNode *QGeoMapScene::sceneNode() const
+//{
+// Q_D(const QGeoMapScene);
+// return d->sceneNode_;
+//}
bool QGeoMapScene::verticalLock() const
{
@@ -229,11 +150,13 @@ bool QGeoMapScene::verticalLock() const
return d->verticalLock_;
}
+#ifndef NO_QT3D_RENDERER
void QGeoMapScene::paintGL(QGLPainter *painter)
{
Q_D(QGeoMapScene);
d->paintGL(painter);
}
+#endif
QSet<QGeoTileSpec> QGeoMapScene::texturedTiles()
{
@@ -247,9 +170,11 @@ QSet<QGeoTileSpec> QGeoMapScene::texturedTiles()
QGeoMapScenePrivate::QGeoMapScenePrivate(QGeoMapScene *scene)
: tileSize_(0),
+#ifndef NO_QT3D_RENDERER
camera_(new QGLCamera()),
sceneNode_(new QGLSceneNode()),
light_(new QGLLightParameters()),
+#endif
scaleFactor_(10.0),
intZoomLevel_(0),
sideLength_(0),
@@ -272,12 +197,6 @@ QGeoMapScenePrivate::QGeoMapScenePrivate(QGeoMapScene *scene)
linearScaling_(true),
q_ptr(scene) {}
-QGeoMapScenePrivate::~QGeoMapScenePrivate()
-{
- delete sceneNode_;
- delete camera_;
- delete light_;
-}
QDoubleVector2D QGeoMapScenePrivate::screenPositionToMercator(const QDoubleVector2D &pos) const
{
@@ -340,215 +259,6 @@ QDoubleVector2D QGeoMapScenePrivate::mercatorToScreenPosition(const QDoubleVecto
return QDoubleVector2D(x + screenOffsetX_, y + screenOffsetY_);
}
-QGeometryData QGeoMapScenePrivate::buildGeometry(const QGeoTileSpec &spec)
-{
- int x = spec.x();
-
- if (x < tileXWrapsBelow_)
- x += sideLength_;
-
- if ((x < minTileX_)
- || (maxTileX_ < x)
- || (spec.y() < minTileY_)
- || (maxTileY_ < spec.y())
- || (spec.zoom() != tileZ_)) {
- return 0;
- }
-
- double edge = scaleFactor_ * tileSize_;
-
- double x1 = (x - minTileX_);
- double x2 = x1 + 1.0;
-
- double y1 = (minTileY_ - spec.y());
- double y2 = y1 - 1.0;
-
- x1 *= edge;
- x2 *= edge;
- y1 *= edge;
- y2 *= edge;
-
- QGeometryData g;
-
- QDoubleVector3D n = QDoubleVector3D(0, 0, 1);
-
- //Texture coordinate order for veritcal flip of texture
- g.appendVertex(QVector3D(x1, y1, 0.0));
- g.appendNormal(n);
- g.appendTexCoord(QVector2D(0.0, 0.0));
-
- g.appendVertex(QVector3D(x1, y2, 0.0));
- g.appendNormal(n);
- g.appendTexCoord(QVector2D(0.0, 1.0));
-
- g.appendVertex(QVector3D(x2, y2, 0.0));
- g.appendNormal(n);
- g.appendTexCoord(QVector2D(1.0, 1.0));
-
- g.appendVertex(QVector3D(x2, y1, 0.0));
- g.appendNormal(n);
- g.appendTexCoord(QVector2D(1.0, 0.0));
-
- return g;
-}
-
-QGLSceneNode *QGeoMapScenePrivate::buildSceneNodeFromGeometry(const QGeometryData &geom)
-{
- QGLBuilder builder;
- builder.addQuads(geom);
- return builder.finalizedSceneNode();
-}
-
-
-void QGeoMapScenePrivate::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 QGeoMapScenePrivate::addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture)
-{
- if (!visibleTiles_.contains(spec)) // Don't add the geometry if it isn't visible
- return;
- if (linearScaling_) {
- texture->texture->setBindOptions(texture->texture->bindOptions() |
- (QGLTexture2D::LinearFilteringBindOption));
- } else {
- texture->texture->setBindOptions(texture->texture->bindOptions() &
- (~QGLTexture2D::LinearFilteringBindOption));
- }
-
- //Avoid expensive conversion of ARGB32_Premultiplied to ARGB32
- if (texture->texture->image().format() == QImage::Format_ARGB32_Premultiplied) {
- texture->texture->setBindOptions(texture->texture->bindOptions() |
- (QGLTexture2D::PremultipliedAlphaBindOption));
- }
-
- //There are tiles for different zoom levels, no need for mipmaps
- texture->texture->setBindOptions(texture->texture->bindOptions() & (~QGLTexture2D::MipmapBindOption));
-
- //We flip the texture coordinates instead of the texture
- texture->texture->setBindOptions(texture->texture->bindOptions() & (~QGLTexture2D::InvertedYBindOption));
-
- QGLSceneNode *node = nodes_.value(spec, 0);
- if (!node) {
- QGeometryData geom = buildGeometry(spec);
- node = buildSceneNodeFromGeometry(geom);
- if (!node)
- return;
-
- QGLMaterial *mat = new QGLMaterial(node);
- mat->setTexture(texture->texture);
- node->setEffect(QGL::LitDecalTexture2D);
- node->setMaterial(mat);
-
- sceneNode_->addNode(node);
- nodes_.insert(spec, node);
- textures_.insert(spec, texture);
- newUploads_ << texture;
-
- } else {
- // TODO handle texture updates when we make node removal more efficient
- if (textures_[spec].data() != texture.data()) {
- textures_.insert(spec, texture);
- node->material()->setTexture(texture->texture);
- newUploads_ << texture;
- }
- }
-}
-
-// return true if new tiles introduced in [tiles]
-void QGeoMapScenePrivate::setVisibleTiles(const QSet<QGeoTileSpec> &tiles)
-{
- Q_Q(QGeoMapScene);
-
- // detect if new tiles introduced
- bool newTilesIntroduced = !visibleTiles_.contains(tiles);
-
- // work out the tile bounds for the new scene
- setTileBounds(tiles);
-
- // set up the gl camera for the new scene
- setupCamera();
-
- QSet<QGeoTileSpec> toRemove = visibleTiles_ - tiles;
- QSet<QGeoTileSpec> toUpdate = visibleTiles_ - toRemove;
- if (!toRemove.isEmpty())
- removeTiles(toRemove);
-
- // only need to update tiles when the bounds have changed,
- if (visibleTiles_ != tiles && !toUpdate.isEmpty())
- updateTiles(toUpdate);
-
- visibleTiles_ = tiles;
- if (newTilesIntroduced)
- emit q->newTilesVisible(visibleTiles_);
-}
-
-void QGeoMapScenePrivate::updateTiles(const QSet<QGeoTileSpec> &tiles)
-{
- typedef QSet<QGeoTileSpec>::const_iterator iter;
- iter i = tiles.constBegin();
- iter end = tiles.constEnd();
- for (; i != end; ++i) {
- QGeoTileSpec tile = *i;
- QGLSceneNode *node = nodes_.value(tile, 0);
-
- if (node) {
- QGeometryData geom = buildGeometry(tile);
- // if the new geometry (after wrapping) is the same as the old one,
- // it can be reused
- if ( node->children().size() > 0) {
- if (node->children().front()->geometry() == geom)
- continue;
- }
-
- sceneNode_->removeNode(node);
- QGLSceneNode *newNode = buildSceneNodeFromGeometry(geom);
- if (newNode) {
- QGLMaterial *mat = new QGLMaterial(newNode);
- mat->setTexture(textures_[tile]->texture);
- newNode->setEffect(QGL::LitDecalTexture2D);
- newNode->setMaterial(mat);
- sceneNode_->addNode(newNode);
- nodes_.insert(tile, newNode);
- } else {
- nodes_.remove(tile);
- textures_.remove(tile);
- }
- delete node;
- }
- }
-}
-
-void QGeoMapScenePrivate::removeTiles(const QSet<QGeoTileSpec> &oldTiles)
-{
- typedef QSet<QGeoTileSpec>::const_iterator iter;
- iter i = oldTiles.constBegin();
- iter end = oldTiles.constEnd();
-
- for (; i != end; ++i) {
- QGeoTileSpec tile = *i;
- QGLSceneNode *node = nodes_.value(tile, 0);
- if (node) {
- // TODO protect with mutex?
- sceneNode_->removeNode(node);
- nodes_.remove(tile);
- textures_.remove(tile);
- delete node;
- }
- }
-}
-
void QGeoMapScenePrivate::setTileBounds(const QSet<QGeoTileSpec> &tiles)
{
if (tiles.isEmpty()) {
@@ -627,188 +337,5 @@ void QGeoMapScenePrivate::setTileBounds(const QSet<QGeoTileSpec> &tiles)
}
}
-void QGeoMapScenePrivate::setupCamera()
-{
-
- double f = 1.0 * qMin(screenSize_.width(), screenSize_.height());
-
- // fraction of zoom level
- double z = std::pow(2.0, cameraData_.zoomLevel() - intZoomLevel_);
-
- // calculate altitdue that allows the visible map tiles
- // to fit in the screen correctly (note that a larger f will cause
- // the camera be higher, resulting in gray areas displayed around
- // the tiles)
- double altitude = scaleFactor_ * f / (2.0 * z);
-
- double aspectRatio = 1.0 * screenSize_.width() / screenSize_.height();
-
- double a = f / (z * tileSize_);
-
- // mercatorWidth_ and mercatorHeight_ define the ratio for
- // mercator and screen coordinate conversion,
- // see mercatorToScreenPosition() and screenPositionToMercator()
- if (aspectRatio > 1.0) {
- mercatorHeight_ = a;
- mercatorWidth_ = a * aspectRatio;
- } else {
- mercatorWidth_ = a;
- mercatorHeight_ = a / aspectRatio;
- }
-
- // calculate center
-
- double edge = scaleFactor_ * tileSize_;
-
- // first calculate the camera center in map space in the range of 0 <-> sideLength (2^z)
- QDoubleVector3D center = (sideLength_ * QGeoProjection::coordToMercator(cameraData_.center()));
-
- // wrap the center if necessary (due to dateline crossing)
- if (center.x() < tileXWrapsBelow_)
- center.setX(center.x() + 1.0 * sideLength_);
-
- mercatorCenterX_ = center.x();
- mercatorCenterY_ = center.y();
-
- // work out where the camera center is w.r.t minimum tile bounds
- center.setX(center.x() - 1.0 * minTileX_);
- center.setY(1.0 * minTileY_ - center.y());
-
- // letter box vertically
- if (useVerticalLock_ && (mercatorHeight_ > 1.0 * sideLength_)) {
- center.setY(-1.0 * sideLength_ / 2.0);
- mercatorCenterY_ = sideLength_ / 2.0;
- screenOffsetY_ = screenSize_.height() * (0.5 - sideLength_ / (2 * mercatorHeight_));
- screenHeight_ = screenSize_.height() - 2 * screenOffsetY_;
- mercatorHeight_ = 1.0 * sideLength_;
- verticalLock_ = true;
- } else {
- screenOffsetY_ = 0.0;
- screenHeight_ = screenSize_.height();
- verticalLock_ = false;
- }
-
- if (mercatorWidth_ > 1.0 * sideLength_) {
- screenOffsetX_ = screenSize_.width() * (0.5 - (sideLength_ / (2 * mercatorWidth_)));
- screenWidth_ = screenSize_.width() - 2 * screenOffsetX_;
- mercatorWidth_ = 1.0 * sideLength_;
- } else {
- screenOffsetX_ = 0.0;
- screenWidth_ = screenSize_.width();
- }
-
- // apply necessary scaling to the camera center
- center *= edge;
-
- // calculate eye
-
- QDoubleVector3D eye = center;
- eye.setZ(altitude);
-
- // calculate up
-
- QDoubleVector3D view = eye - center;
- QDoubleVector3D side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0));
- QDoubleVector3D up = QDoubleVector3D::normal(side, view);
-
- // old bearing, tilt and roll code
- // QMatrix4x4 mBearing;
- // mBearing.rotate(-1.0 * camera.bearing(), view);
- // up = mBearing * up;
-
- // QDoubleVector3D side2 = QDoubleVector3D::normal(up, view);
- // QMatrix4x4 mTilt;
- // mTilt.rotate(camera.tilt(), side2);
- // eye = (mTilt * view) + center;
-
- // view = eye - center;
- // side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0));
- // up = QDoubleVector3D::normal(view, side2);
-
- // QMatrix4x4 mRoll;
- // mRoll.rotate(camera.roll(), view);
- // up = mRoll * up;
-
- // near plane and far plane
-
- double nearPlane = 1.0;
- double farPlane = 4.0 * edge;
-
- // TODO protect with mutex?
- // set glcamera parameters
- camera_->setCenter(center);
- camera_->setEye(eye);
- camera_->setUpVector(up);
- camera_->setNearPlane(nearPlane);
- camera_->setFarPlane(farPlane);
-}
-
-void QGeoMapScenePrivate::paintGL(QGLPainter *painter)
-{
- // TODO protect with mutex?
-
- // TODO add a shortcut here for when we don't need to repeat and clip the map
- // NOTE- this is important as the repeat code below removes a lot of accuracy
- // by converting to float and adding/removing large numbers when at high zoom
-
- // do any pending upload/releases
- while (!newUploads_.isEmpty()) {
- if (!newUploads_.front()->textureBound) {
- newUploads_.front()->texture->bind();
- newUploads_.front()->texture->clearImage();
- newUploads_.front()->textureBound = true;
- }
- newUploads_.pop_front();
- }
-
- glEnable(GL_SCISSOR_TEST);
-
- painter->setScissor(QRect(screenOffsetX_, screenOffsetY_, screenWidth_, screenHeight_));
-
- painter->setCamera(camera_);
-
- painter->setMainLight(light_);
-
- sceneNode_->draw(painter);
-
- QGLCamera *camera = camera_;
-
- bool old = camera->blockSignals(true);
-
- glDisable(GL_DEPTH_TEST);
-
- double sideLength = scaleFactor_ * tileSize_ * sideLength_;
-
- QDoubleVector3D c = QDoubleVector3D(camera->center());
- c.setX(c.x() + sideLength);
- camera->setCenter(c);
-
- QDoubleVector3D e = QDoubleVector3D(camera->eye());
- e.setX(e.x() + sideLength);
- camera->setEye(e);
-
- painter->setCamera(camera);
- sceneNode_->draw(painter);
-
- c.setX(c.x() - 2 * sideLength);
- camera->setCenter(c);
- e.setX(e.x() - 2 * sideLength);
- camera->setEye(e);
-
- painter->setCamera(camera);
- sceneNode_->draw(painter);
-
- c.setX(c.x() + sideLength);
- camera->setCenter(c);
- e.setX(e.x() + sideLength);
- camera->setEye(e);
-
- painter->setCamera(camera);
- sceneNode_->draw(painter);
-
- glEnable(GL_DEPTH_TEST);
-
- camera->blockSignals(old);
-}
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeomapscene_p.h b/src/location/maps/qgeomapscene_p.h
index 203eeb8a..47c82e2a 100644
--- a/src/location/maps/qgeomapscene_p.h
+++ b/src/location/maps/qgeomapscene_p.h
@@ -67,10 +67,12 @@ class QGeoTileSpec;
class QDoubleVector2D;
+#ifndef NO_QT3D_RENDERER
class QGLSceneNode;
class QGLCamera;
class QGLPainter;
class QGLTexture2D;
+#endif
class QGeoTileTexture;
class QPointF;
@@ -97,10 +99,11 @@ public:
QDoubleVector2D screenPositionToMercator(const QDoubleVector2D &pos) const;
QDoubleVector2D mercatorToScreenPosition(const QDoubleVector2D &mercator) const;
- QGLCamera *camera() const;
- QGLSceneNode *sceneNode() const;
+ //QGLCamera *camera() const;
+ //QGLSceneNode *sceneNode() const;
+#ifndef NO_QT3D_RENDERER
void paintGL(QGLPainter *painter);
-
+#endif
bool verticalLock() const;
QSet<QGeoTileSpec> texturedTiles();
diff --git a/src/location/maps/qgeomapscene_p_p.h b/src/location/maps/qgeomapscene_p_p.h
new file mode 100644
index 00000000..f1fb6c48
--- /dev/null
+++ b/src/location/maps/qgeomapscene_p_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGEOMAPSCENE_P_P_H
+#define QGEOMAPSCENE_P_P_H
+
+#ifndef NO_QT3D_RENDERER
+#include <Qt3D/qgeometrydata.h>
+#else
+#include <QSGNode>
+#endif
+
+#include "qgeocameradata_p.h"
+#include "qgeomapscene_p.h"
+
+#ifndef NO_QT3D_RENDERER
+class QGLLightParameters;
+#endif
+
+class QGeoMapScenePrivate
+{
+public:
+ explicit QGeoMapScenePrivate(QGeoMapScene *scene);
+ ~QGeoMapScenePrivate();
+
+ QSize screenSize_; // in pixels
+ int tileSize_; // the pixel resolution for each tile
+ QGeoCameraData cameraData_;
+ QSet<QGeoTileSpec> visibleTiles_;
+
+#ifndef NO_QT3D_RENDERER
+ QGLCamera *camera_;
+ QGLSceneNode *sceneNode_;
+ QGLLightParameters* light_;
+#endif
+
+ // scales up the tile geometry and the camera altitude, resulting in no visible effect
+ // other than to control the accuracy of the render by keeping the values in a sensible range
+ double scaleFactor_;
+
+ // rounded down, positive zoom is zooming in, corresponding to reduced altitude
+ int intZoomLevel_;
+
+ // mercatorToGrid transform
+ // the number of tiles in each direction for the whole map (earth) at the current zoom level.
+ // it is 1<<zoomLevel
+ int sideLength_;
+
+#ifndef NO_QT3D_RENDERER
+ QHash<QGeoTileSpec, QGLSceneNode *> nodes_;
+#else
+ QHash<QGeoTileSpec, QSGNode *> nodes_;
+#endif
+ QHash<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > textures_;
+ QList<QSharedPointer<QGeoTileTexture> > newUploads_;
+
+ // tilesToGrid transform
+ int minTileX_; // the minimum tile index, i.e. 0 to sideLength which is 1<< zoomLevel
+ int minTileY_;
+ int maxTileX_;
+ int maxTileY_;
+ int tileZ_; // caches the zoom level for this tile set
+ int tileXWrapsBelow_; // the wrap point as a tile index
+
+ // cameraToGrid transform
+ double mercatorCenterX_; // center of camera in grid space (0 to sideLength)
+ double mercatorCenterY_;
+ double mercatorWidth_; // width of camera in grid space (0 to sideLength)
+ double mercatorHeight_;
+
+ // screenToWindow transform
+ double screenOffsetX_; // in pixels
+ double screenOffsetY_; // in pixels
+ // cameraToScreen transform
+ double screenWidth_; // in pixels
+ double screenHeight_; // in pixels
+
+ bool useVerticalLock_;
+ bool verticalLock_;
+ bool linearScaling_;
+
+ void addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture);
+
+ QDoubleVector2D screenPositionToMercator(const QDoubleVector2D &pos) const;
+ QDoubleVector2D mercatorToScreenPosition(const QDoubleVector2D &mercator) const;
+
+ void setVisibleTiles(const QSet<QGeoTileSpec> &tiles);
+ void removeTiles(const QSet<QGeoTileSpec> &oldTiles);
+ void updateTiles(const QSet<QGeoTileSpec> &tiles);
+#ifndef NO_QT3D_RENDERER
+ QGeometryData buildGeometry(const QGeoTileSpec &spec);
+ QGLSceneNode *buildSceneNodeFromGeometry(const QGeometryData &geom);
+ void paintGL(QGLPainter *painter);
+#endif
+ void setTileBounds(const QSet<QGeoTileSpec> &tiles);
+ void setupCamera();
+ void setScalingOnTextures();
+
+private:
+ QGeoMapScene *q_ptr;
+ Q_DECLARE_PUBLIC(QGeoMapScene)
+};
+
+
+#endif // QGEOMAPSCENE_P_P_H
diff --git a/src/location/maps/qgeomapscene_sg.cpp b/src/location/maps/qgeomapscene_sg.cpp
new file mode 100644
index 00000000..1b0b5a35
--- /dev/null
+++ b/src/location/maps/qgeomapscene_sg.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgeomapscene_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+QGeoMapScenePrivate::~QGeoMapScenePrivate()
+{
+}
+
+void QGeoMapScenePrivate::setScalingOnTextures()
+{
+}
+
+void QGeoMapScenePrivate::addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture)
+{
+}
+
+// return true if new tiles introduced in [tiles]
+void QGeoMapScenePrivate::setVisibleTiles(const QSet<QGeoTileSpec> &tiles)
+{
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/location/maps/qgeomapsscene_qt3d.cpp b/src/location/maps/qgeomapsscene_qt3d.cpp
new file mode 100644
index 00000000..9ef66398
--- /dev/null
+++ b/src/location/maps/qgeomapsscene_qt3d.cpp
@@ -0,0 +1,420 @@
+#include <Qt3D/qglscenenode.h>
+#include <Qt3D/qglbuilder.h>
+#include <Qt3D/qglmaterial.h>
+#include <Qt3D/qgltexture2d.h>
+#include <Qt3D/qglcamera.h>
+#include <Qt3D/qglpainter.h>
+#include <Qt3D/QGLLightParameters>
+
+#include "qgeomapscene_p_p.h"
+
+#include "qgeotilespec_p.h"
+#include "qgeotilecache_p.h"
+#include <QtPositioning/private/qgeoprojection_p.h>
+#include <QtPositioning/private/qdoublevector2d_p.h>
+#include <QtPositioning/private/qdoublevector3d_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QGeoMapScenePrivate::~QGeoMapScenePrivate()
+{
+ delete sceneNode_;
+ delete camera_;
+ delete light_;
+}
+
+QGeometryData QGeoMapScenePrivate::buildGeometry(const QGeoTileSpec &spec)
+{
+ int x = spec.x();
+
+ if (x < tileXWrapsBelow_)
+ x += sideLength_;
+
+ if ((x < minTileX_)
+ || (maxTileX_ < x)
+ || (spec.y() < minTileY_)
+ || (maxTileY_ < spec.y())
+ || (spec.zoom() != tileZ_)) {
+ return 0;
+ }
+
+ double edge = scaleFactor_ * tileSize_;
+
+ double x1 = (x - minTileX_);
+ double x2 = x1 + 1.0;
+
+ double y1 = (minTileY_ - spec.y());
+ double y2 = y1 - 1.0;
+
+ x1 *= edge;
+ x2 *= edge;
+ y1 *= edge;
+ y2 *= edge;
+
+ QGeometryData g;
+
+ QDoubleVector3D n = QDoubleVector3D(0, 0, 1);
+
+ //Texture coordinate order for veritcal flip of texture
+ g.appendVertex(QVector3D(x1, y1, 0.0));
+ g.appendNormal(n);
+ g.appendTexCoord(QVector2D(0.0, 0.0));
+
+ g.appendVertex(QVector3D(x1, y2, 0.0));
+ g.appendNormal(n);
+ g.appendTexCoord(QVector2D(0.0, 1.0));
+
+ g.appendVertex(QVector3D(x2, y2, 0.0));
+ g.appendNormal(n);
+ g.appendTexCoord(QVector2D(1.0, 1.0));
+
+ g.appendVertex(QVector3D(x2, y1, 0.0));
+ g.appendNormal(n);
+ g.appendTexCoord(QVector2D(1.0, 0.0));
+
+ return g;
+}
+
+QGLSceneNode *QGeoMapScenePrivate::buildSceneNodeFromGeometry(const QGeometryData &geom)
+{
+ QGLBuilder builder;
+ builder.addQuads(geom);
+ return builder.finalizedSceneNode();
+}
+
+
+void QGeoMapScenePrivate::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 QGeoMapScenePrivate::addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture)
+{
+ if (!visibleTiles_.contains(spec)) // Don't add the geometry if it isn't visible
+ return;
+ if (linearScaling_) {
+ texture->texture->setBindOptions(texture->texture->bindOptions() |
+ (QGLTexture2D::LinearFilteringBindOption));
+ } else {
+ texture->texture->setBindOptions(texture->texture->bindOptions() &
+ (~QGLTexture2D::LinearFilteringBindOption));
+ }
+
+ //Avoid expensive conversion of ARGB32_Premultiplied to ARGB32
+ if (texture->texture->image().format() == QImage::Format_ARGB32_Premultiplied) {
+ texture->texture->setBindOptions(texture->texture->bindOptions() |
+ (QGLTexture2D::PremultipliedAlphaBindOption));
+ }
+
+ //There are tiles for different zoom levels, no need for mipmaps
+ texture->texture->setBindOptions(texture->texture->bindOptions() & (~QGLTexture2D::MipmapBindOption));
+
+ //We flip the texture coordinates instead of the texture
+ texture->texture->setBindOptions(texture->texture->bindOptions() & (~QGLTexture2D::InvertedYBindOption));
+
+ QGLSceneNode *node = nodes_.value(spec, 0);
+ if (!node) {
+ QGeometryData geom = buildGeometry(spec);
+ node = buildSceneNodeFromGeometry(geom);
+ if (!node)
+ return;
+
+ QGLMaterial *mat = new QGLMaterial(node);
+ mat->setTexture(texture->texture);
+ node->setEffect(QGL::LitDecalTexture2D);
+ node->setMaterial(mat);
+
+ sceneNode_->addNode(node);
+ nodes_.insert(spec, node);
+ textures_.insert(spec, texture);
+ newUploads_ << texture;
+
+ } else {
+ // TODO handle texture updates when we make node removal more efficient
+ if (textures_[spec].data() != texture.data()) {
+ textures_.insert(spec, texture);
+ node->material()->setTexture(texture->texture);
+ newUploads_ << texture;
+ }
+ }
+}
+
+// return true if new tiles introduced in [tiles]
+void QGeoMapScenePrivate::setVisibleTiles(const QSet<QGeoTileSpec> &tiles)
+{
+ Q_Q(QGeoMapScene);
+
+ // detect if new tiles introduced
+ bool newTilesIntroduced = !visibleTiles_.contains(tiles);
+
+ // work out the tile bounds for the new scene
+ setTileBounds(tiles);
+
+ // set up the gl camera for the new scene
+ setupCamera();
+
+ QSet<QGeoTileSpec> toRemove = visibleTiles_ - tiles;
+ QSet<QGeoTileSpec> toUpdate = visibleTiles_ - toRemove;
+ if (!toRemove.isEmpty())
+ removeTiles(toRemove);
+
+ // only need to update tiles when the bounds have changed,
+ if (visibleTiles_ != tiles && !toUpdate.isEmpty())
+ updateTiles(toUpdate);
+
+ visibleTiles_ = tiles;
+ if (newTilesIntroduced)
+ emit q->newTilesVisible(visibleTiles_);
+}
+
+void QGeoMapScenePrivate::updateTiles(const QSet<QGeoTileSpec> &tiles)
+{
+ typedef QSet<QGeoTileSpec>::const_iterator iter;
+ iter i = tiles.constBegin();
+ iter end = tiles.constEnd();
+ for (; i != end; ++i) {
+ QGeoTileSpec tile = *i;
+ QGLSceneNode *node = nodes_.value(tile, 0);
+
+ if (node) {
+ QGeometryData geom = buildGeometry(tile);
+ // if the new geometry (after wrapping) is the same as the old one,
+ // it can be reused
+ if ( node->children().size() > 0) {
+ if (node->children().front()->geometry() == geom)
+ continue;
+ }
+
+ sceneNode_->removeNode(node);
+ QGLSceneNode *newNode = buildSceneNodeFromGeometry(geom);
+ if (newNode) {
+ QGLMaterial *mat = new QGLMaterial(newNode);
+ mat->setTexture(textures_[tile]->texture);
+ newNode->setEffect(QGL::LitDecalTexture2D);
+ newNode->setMaterial(mat);
+ sceneNode_->addNode(newNode);
+ nodes_.insert(tile, newNode);
+ } else {
+ nodes_.remove(tile);
+ textures_.remove(tile);
+ }
+ delete node;
+ }
+ }
+}
+
+void QGeoMapScenePrivate::removeTiles(const QSet<QGeoTileSpec> &oldTiles)
+{
+ typedef QSet<QGeoTileSpec>::const_iterator iter;
+ iter i = oldTiles.constBegin();
+ iter end = oldTiles.constEnd();
+
+ for (; i != end; ++i) {
+ QGeoTileSpec tile = *i;
+ QGLSceneNode *node = nodes_.value(tile, 0);
+ if (node) {
+ // TODO protect with mutex?
+ sceneNode_->removeNode(node);
+ nodes_.remove(tile);
+ textures_.remove(tile);
+ delete node;
+ }
+ }
+}
+
+void QGeoMapScenePrivate::setupCamera()
+{
+
+ double f = 1.0 * qMin(screenSize_.width(), screenSize_.height());
+
+ // fraction of zoom level
+ double z = std::pow(2.0, cameraData_.zoomLevel() - intZoomLevel_);
+
+ // calculate altitdue that allows the visible map tiles
+ // to fit in the screen correctly (note that a larger f will cause
+ // the camera be higher, resulting in gray areas displayed around
+ // the tiles)
+ double altitude = scaleFactor_ * f / (2.0 * z);
+
+ double aspectRatio = 1.0 * screenSize_.width() / screenSize_.height();
+
+ double a = f / (z * tileSize_);
+
+ // mercatorWidth_ and mercatorHeight_ define the ratio for
+ // mercator and screen coordinate conversion,
+ // see mercatorToScreenPosition() and screenPositionToMercator()
+ if (aspectRatio > 1.0) {
+ mercatorHeight_ = a;
+ mercatorWidth_ = a * aspectRatio;
+ } else {
+ mercatorWidth_ = a;
+ mercatorHeight_ = a / aspectRatio;
+ }
+
+ // calculate center
+
+ double edge = scaleFactor_ * tileSize_;
+
+ // first calculate the camera center in map space in the range of 0 <-> sideLength (2^z)
+ QDoubleVector3D center = (sideLength_ * QGeoProjection::coordToMercator(cameraData_.center()));
+
+ // wrap the center if necessary (due to dateline crossing)
+ if (center.x() < tileXWrapsBelow_)
+ center.setX(center.x() + 1.0 * sideLength_);
+
+ mercatorCenterX_ = center.x();
+ mercatorCenterY_ = center.y();
+
+ // work out where the camera center is w.r.t minimum tile bounds
+ center.setX(center.x() - 1.0 * minTileX_);
+ center.setY(1.0 * minTileY_ - center.y());
+
+ // letter box vertically
+ if (useVerticalLock_ && (mercatorHeight_ > 1.0 * sideLength_)) {
+ center.setY(-1.0 * sideLength_ / 2.0);
+ mercatorCenterY_ = sideLength_ / 2.0;
+ screenOffsetY_ = screenSize_.height() * (0.5 - sideLength_ / (2 * mercatorHeight_));
+ screenHeight_ = screenSize_.height() - 2 * screenOffsetY_;
+ mercatorHeight_ = 1.0 * sideLength_;
+ verticalLock_ = true;
+ } else {
+ screenOffsetY_ = 0.0;
+ screenHeight_ = screenSize_.height();
+ verticalLock_ = false;
+ }
+
+ if (mercatorWidth_ > 1.0 * sideLength_) {
+ screenOffsetX_ = screenSize_.width() * (0.5 - (sideLength_ / (2 * mercatorWidth_)));
+ screenWidth_ = screenSize_.width() - 2 * screenOffsetX_;
+ mercatorWidth_ = 1.0 * sideLength_;
+ } else {
+ screenOffsetX_ = 0.0;
+ screenWidth_ = screenSize_.width();
+ }
+
+ // apply necessary scaling to the camera center
+ center *= edge;
+
+ // calculate eye
+
+ QDoubleVector3D eye = center;
+ eye.setZ(altitude);
+
+ // calculate up
+
+ QDoubleVector3D view = eye - center;
+ QDoubleVector3D side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0));
+ QDoubleVector3D up = QDoubleVector3D::normal(side, view);
+
+ // old bearing, tilt and roll code
+ // QMatrix4x4 mBearing;
+ // mBearing.rotate(-1.0 * camera.bearing(), view);
+ // up = mBearing * up;
+
+ // QDoubleVector3D side2 = QDoubleVector3D::normal(up, view);
+ // QMatrix4x4 mTilt;
+ // mTilt.rotate(camera.tilt(), side2);
+ // eye = (mTilt * view) + center;
+
+ // view = eye - center;
+ // side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0));
+ // up = QDoubleVector3D::normal(view, side2);
+
+ // QMatrix4x4 mRoll;
+ // mRoll.rotate(camera.roll(), view);
+ // up = mRoll * up;
+
+ // near plane and far plane
+
+ double nearPlane = 1.0;
+ double farPlane = 4.0 * edge;
+
+ // TODO protect with mutex?
+ // set glcamera parameters
+ camera_->setCenter(center);
+ camera_->setEye(eye);
+ camera_->setUpVector(up);
+ camera_->setNearPlane(nearPlane);
+ camera_->setFarPlane(farPlane);
+}
+
+void QGeoMapScenePrivate::paintGL(QGLPainter *painter)
+{
+ // TODO protect with mutex?
+
+ // TODO add a shortcut here for when we don't need to repeat and clip the map
+ // NOTE- this is important as the repeat code below removes a lot of accuracy
+ // by converting to float and adding/removing large numbers when at high zoom
+
+ // do any pending upload/releases
+ while (!newUploads_.isEmpty()) {
+ if (!newUploads_.front()->textureBound) {
+ newUploads_.front()->texture->bind();
+ newUploads_.front()->texture->clearImage();
+ newUploads_.front()->textureBound = true;
+ }
+ newUploads_.pop_front();
+ }
+
+ glEnable(GL_SCISSOR_TEST);
+
+ painter->setScissor(QRect(screenOffsetX_, screenOffsetY_, screenWidth_, screenHeight_));
+
+ painter->setCamera(camera_);
+
+ painter->setMainLight(light_);
+
+ sceneNode_->draw(painter);
+
+ QGLCamera *camera = camera_;
+
+ bool old = camera->blockSignals(true);
+
+ glDisable(GL_DEPTH_TEST);
+
+ double sideLength = scaleFactor_ * tileSize_ * sideLength_;
+
+ QDoubleVector3D c = QDoubleVector3D(camera->center());
+ c.setX(c.x() + sideLength);
+ camera->setCenter(c);
+
+ QDoubleVector3D e = QDoubleVector3D(camera->eye());
+ e.setX(e.x() + sideLength);
+ camera->setEye(e);
+
+ painter->setCamera(camera);
+ sceneNode_->draw(painter);
+
+ c.setX(c.x() - 2 * sideLength);
+ camera->setCenter(c);
+ e.setX(e.x() - 2 * sideLength);
+ camera->setEye(e);
+
+ painter->setCamera(camera);
+ sceneNode_->draw(painter);
+
+ c.setX(c.x() + sideLength);
+ camera->setCenter(c);
+ e.setX(e.x() + sideLength);
+ camera->setEye(e);
+
+ painter->setCamera(camera);
+ sceneNode_->draw(painter);
+
+ glEnable(GL_DEPTH_TEST);
+
+ camera->blockSignals(old);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/location/maps/qgeotilecache.cpp b/src/location/maps/qgeotilecache.cpp
index 8a86b7c4..a1852490 100644
--- a/src/location/maps/qgeotilecache.cpp
+++ b/src/location/maps/qgeotilecache.cpp
@@ -57,7 +57,12 @@ Q_DECLARE_METATYPE(QSet<QGeoTileSpec>)
QT_BEGIN_NAMESPACE
QMutex QGeoTileCache::cleanupMutex_;
+#ifndef NO_QT3D_RENDERER
QList<QGLTexture2D*> QGeoTileCache::cleanupList_;
+#else
+QList<void*> QGeoTileCache::cleanupList_;
+#endif
+
class QGeoCachedTileMemory
{
@@ -272,6 +277,7 @@ int QGeoTileCache::textureUsage() const
return textureCache_.totalCost();
}
+#ifndef NO_QT3D_RENDERER
void QGeoTileCache::GLContextAvailable()
{
QMutexLocker ml(&cleanupMutex_);
@@ -290,6 +296,7 @@ void QGeoTileCache::GLContextAvailable()
cleanupList_.pop_front();
}
}
+#endif
QSharedPointer<QGeoTileTexture> QGeoTileCache::get(const QGeoTileSpec &spec)
{
@@ -402,10 +409,12 @@ QSharedPointer<QGeoTileTexture> QGeoTileCache::addToTextureCache(const QGeoTileS
{
QSharedPointer<QGeoTileTexture> tt(new QGeoTileTexture);
tt->spec = spec;
+#ifndef NO_QT3D_RENDERER
tt->texture = new QGLTexture2D();
tt->texture->setPixmap(pixmap);
tt->texture->setHorizontalWrap(QGL::ClampToEdge);
tt->texture->setVerticalWrap(QGL::ClampToEdge);
+#endif
/* Do not bind/cleanImage on the texture here -- it needs to be done
* in the render thread (by qgeomapscene) */
diff --git a/src/location/maps/qgeotilecache_p.h b/src/location/maps/qgeotilecache_p.h
index 6fecfa8f..9e51860d 100644
--- a/src/location/maps/qgeotilecache_p.h
+++ b/src/location/maps/qgeotilecache_p.h
@@ -98,7 +98,11 @@ public:
~QGeoTileTexture();
QGeoTileSpec spec;
+#ifndef NO_QT3D_RENDERER
QGLTexture2D *texture;
+#else
+ void *texture; //need a custom texture class here
+#endif
bool textureBound;
};
@@ -132,7 +136,9 @@ public:
int minTextureUsage() const;
int textureUsage() const;
+#ifndef NO_QT3D_RENDERER
void GLContextAvailable();
+#endif
QSharedPointer<QGeoTileTexture> get(const QGeoTileSpec &spec);
@@ -169,7 +175,11 @@ private:
int extraTextureUsage_;
static QMutex cleanupMutex_;
+#ifndef NO_QT3D_RENDERER
static QList<QGLTexture2D*> cleanupList_;
+#else
+ static QList<void*> cleanupList_;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeotiledmapdata.cpp b/src/location/maps/qgeotiledmapdata.cpp
index 1655327b..bf45fdd7 100644
--- a/src/location/maps/qgeotiledmapdata.cpp
+++ b/src/location/maps/qgeotiledmapdata.cpp
@@ -55,14 +55,7 @@
#include <qnumeric.h>
-#include <Qt3D/qglscenenode.h>
-#include <Qt3D/qgeometrydata.h>
-#include <Qt3D/qglbuilder.h>
#include <Qt3D/qglpainter.h>
-#include <Qt3D/qgeometrydata.h>
-#include <Qt3D/qglbuilder.h>
-#include <Qt3D/qglcamera.h>
-#include <Qt3D/qglsubsurface.h>
#include <QtPositioning/private/qgeoprojection_p.h>
#include <QtPositioning/private/qdoublevector2d_p.h>
@@ -103,11 +96,13 @@ QGeoTileCache *QGeoTiledMapData::tileCache()
return d->tileCache();
}
+#ifndef NO_QT3D_RENDERER
void QGeoTiledMapData::paintGL(QGLPainter *painter)
{
Q_D(QGeoTiledMapData);
d->paintGL(painter);
}
+#endif
void QGeoTiledMapData::mapResized(int width, int height)
{
@@ -308,11 +303,13 @@ QSet<QGeoTileSpec> QGeoTiledMapDataPrivate::visibleTiles()
return cameraTiles_->tiles();
}
+#ifndef NO_QT3D_RENDERER
void QGeoTiledMapDataPrivate::paintGL(QGLPainter *painter)
{
mapScene_->paintGL(painter);
cache_->GLContextAvailable();
}
+#endif
QGeoCoordinate QGeoTiledMapDataPrivate::screenPositionToCoordinate(const QDoubleVector2D &pos) const
{
diff --git a/src/location/maps/qgeotiledmapdata_p.h b/src/location/maps/qgeotiledmapdata_p.h
index 126454e4..c760926f 100644
--- a/src/location/maps/qgeotiledmapdata_p.h
+++ b/src/location/maps/qgeotiledmapdata_p.h
@@ -82,8 +82,9 @@ public:
QGeoTileCache *tileCache();
+#ifndef NO_QT3D_RENDERER
void paintGL(QGLPainter *painter);
-
+#endif
void newTileFetched(const QGeoTileSpec &spec);
QGeoCoordinate screenPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const;
diff --git a/src/location/maps/qgeotiledmapdata_p_p.h b/src/location/maps/qgeotiledmapdata_p_p.h
index 67ad5cc1..89f34e36 100644
--- a/src/location/maps/qgeotiledmapdata_p_p.h
+++ b/src/location/maps/qgeotiledmapdata_p_p.h
@@ -93,7 +93,9 @@ public:
QGeoTileCache *tileCache();
+#ifndef NO_QT3D_RENDERER
void paintGL(QGLPainter *painter);
+#endif
void changeCameraData(const QGeoCameraData &oldCameraData);
void changeActiveMapType(const QGeoMapType mapType);
diff --git a/src/plugins/geoservices/nokia/nokia.pro b/src/plugins/geoservices/nokia/nokia.pro
index 597f8bae..c093bef8 100644
--- a/src/plugins/geoservices/nokia/nokia.pro
+++ b/src/plugins/geoservices/nokia/nokia.pro
@@ -49,6 +49,11 @@ SOURCES += \
include(placesv2/placesv2.pri)
+qtHaveModule(3d):!no_qt3d {
+} else {
+ DEFINES += NO_QT3D_RENDERER
+}
+
RESOURCES += resource.qrc
INCLUDEPATH += $$QT.location.includes
diff --git a/src/src.pro b/src/src.pro
index 72274cdc..4a42f439 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -10,11 +10,16 @@ positioning_doc_snippets.depends = positioning
SUBDIRS += positioning_doc_snippets
#no point in building QtLocation without Qt3D
-qtHaveModule(3d) {
- SUBDIRS += 3rdparty
+qtHaveModule(3d)|no_qt3d {
+ qtHaveModule(3d):!no_qt3d {
+ message(Using Qt3D Renderer)
+ } else {
+ DEFINES += NO_QT3D_RENDERER
+ warning(Not using Qt3D as renderer backend)
+ }
location.depends = positioning 3rdparty
- SUBDIRS += location
+ SUBDIRS += location 3rdparty
plugins.depends += location
qtHaveModule(quick):imports.depends += location