diff options
Diffstat (limited to 'src/location/quickmapitems/rhi')
16 files changed, 0 insertions, 3081 deletions
diff --git a/src/location/quickmapitems/rhi/qdeclarativecirclemapitem_rhi.cpp b/src/location/quickmapitems/rhi/qdeclarativecirclemapitem_rhi.cpp deleted file mode 100644 index f2a7f0e2..00000000 --- a/src/location/quickmapitems/rhi/qdeclarativecirclemapitem_rhi.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** - ** - ** Copyright (C) 2022 The Qt Company Ltd. - ** Contact: https://www.qt.io/licensing/ - ** - ** 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 The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ - -#include "qdeclarativecirclemapitem_rhi_p.h" - -QT_BEGIN_NAMESPACE - -QDeclarativeCircleMapItemPrivateOpenGL::~QDeclarativeCircleMapItemPrivateOpenGL() {} - -void QDeclarativeCircleMapItemPrivateOpenGL::updatePolish() -{ - if (m_circle.m_circle.isEmpty()) { - m_geometry.clear(); - m_borderGeometry.clear(); - m_circle.setWidth(0); - m_circle.setHeight(0); - return; - } - - QScopedValueRollback<bool> rollback(m_circle.m_updatingGeometry); - m_circle.m_updatingGeometry = true; - const qreal lineWidth = m_circle.m_border.width(); - const QColor &lineColor = m_circle.m_border.color(); - const QColor &fillColor = m_circle.color(); - if (fillColor.alpha() != 0) { - m_geometry.updateSourcePoints(*m_circle.map(), m_circlePath); - m_geometry.markScreenDirty(); - m_geometry.updateScreenPoints(*m_circle.map(), lineWidth, lineColor); - } else { - m_geometry.clearBounds(); - } - - QGeoMapItemGeometry * geom = &m_geometry; - m_borderGeometry.clearScreen(); - if (lineColor.alpha() != 0 && lineWidth > 0) { - m_borderGeometry.updateSourcePoints(*m_circle.map(), m_circle.m_circle); - m_borderGeometry.markScreenDirty(); - m_borderGeometry.updateScreenPoints(*m_circle.map(), lineWidth); - geom = &m_borderGeometry; - } - m_circle.setWidth(geom->sourceBoundingBox().width()); - m_circle.setHeight(geom->sourceBoundingBox().height()); - m_circle.setPosition(1.0 * geom->firstPointOffset() - QPointF(lineWidth * 0.5,lineWidth * 0.5)); -} - -QSGNode *QDeclarativeCircleMapItemPrivateOpenGL::updateMapItemPaintNode(QSGNode *oldNode, - QQuickItem::UpdatePaintNodeData *data) -{ - Q_UNUSED(data); - - if (!m_rootNode || !oldNode) { - m_rootNode = new QDeclarativePolygonMapItemPrivateOpenGL::RootNode(); - m_node = new MapPolygonNodeGL(); - m_rootNode->appendChildNode(m_node); - m_polylinenode = new MapPolylineNodeOpenGL(); - m_rootNode->appendChildNode(m_polylinenode); - m_rootNode->markDirty(QSGNode::DirtyNodeAdded); - if (oldNode) - delete oldNode; - } else { - m_rootNode = static_cast<QDeclarativePolygonMapItemPrivateOpenGL::RootNode *>(oldNode); - } - - const QGeoMap *map = m_circle.map(); - const QMatrix4x4 &combinedMatrix = map->geoProjection().qsgTransform(); - const QDoubleVector3D &cameraCenter = map->geoProjection().centerMercator(); - - if (m_borderGeometry.isScreenDirty()) { - /* Do the border update first */ - m_polylinenode->update(m_circle.m_border.color(), - float(m_circle.m_border.width()), - &m_borderGeometry, - combinedMatrix, - cameraCenter, - Qt::SquareCap, - true, - 30); // No LOD for circles - m_borderGeometry.setPreserveGeometry(false); - m_borderGeometry.markClean(); - } else { - m_polylinenode->setSubtreeBlocked(true); - } - if (m_geometry.isScreenDirty()) { - m_node->update(m_circle.m_color, - &m_geometry, - combinedMatrix, - cameraCenter); - m_geometry.setPreserveGeometry(false); - m_geometry.markClean(); - } else { - m_node->setSubtreeBlocked(true); - } - - m_rootNode->setSubtreeBlocked(false); - return m_rootNode; -} - -bool QDeclarativeCircleMapItemPrivateOpenGL::contains(const QPointF &point) const -{ - const qreal lineWidth = m_circle.m_border.width(); - const QColor &lineColor = m_circle.m_border.color(); - const QRectF &bounds = (lineColor.alpha() != 0 && lineWidth > 0) - ? m_borderGeometry.sourceBoundingBox() - : m_geometry.sourceBoundingBox(); - if (bounds.contains(point)) { - QDeclarativeGeoMap *m = m_circle.quickMap(); - if (m) { - const QGeoCoordinate crd = m->toCoordinate(m->mapFromItem(&m_circle, point)); - const auto &projection = static_cast<const QGeoProjectionWebMercator&>( - m_circle.map()->geoProjection()); - return m_circle.m_circle.contains(crd) - || m_borderGeometry.contains(m_circle.mapToItem(m_circle.quickMap(), point), - m_circle.border()->width(), projection); - } else { - return true; - } - } - return false; -} - -QT_END_NAMESPACE - diff --git a/src/location/quickmapitems/rhi/qdeclarativecirclemapitem_rhi_p.h b/src/location/quickmapitems/rhi/qdeclarativecirclemapitem_rhi_p.h deleted file mode 100644 index 4e8ec442..00000000 --- a/src/location/quickmapitems/rhi/qdeclarativecirclemapitem_rhi_p.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Paolo Angelelli <paolo.angelelli@gmail.com> -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVECIRCLEMAPITEM_RHI_P_H -#define QDECLARATIVECIRCLEMAPITEM_RHI_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtLocation/private/qlocationglobal_p.h> -#include <QtLocation/private/qdeclarativecirclemapitem_p_p.h> -#include <QtLocation/private/qdeclarativepolygonmapitem_p_p.h> - -#include "qdeclarativepolygonmapitem_rhi_p.h" - -QT_BEGIN_NAMESPACE - -class Q_LOCATION_PRIVATE_EXPORT QDeclarativeCircleMapItemPrivateOpenGL: public QDeclarativeCircleMapItemPrivate -{ -public: - QDeclarativeCircleMapItemPrivateOpenGL(QDeclarativeCircleMapItem &circle) - : QDeclarativeCircleMapItemPrivate(circle) - { - } - - ~QDeclarativeCircleMapItemPrivateOpenGL() override; - - void onLinePropertiesChanged() override - { - m_circle.m_dirtyMaterial = true; - afterViewportChanged(); - } - void markScreenDirtyAndUpdate() - { - // preserveGeometry is cleared in updateMapItemPaintNode - m_geometry.markScreenDirty(); - m_borderGeometry.markScreenDirty(); - m_circle.polishAndUpdate(); - } - void markSourceDirtyAndUpdate() override - { - updateCirclePath(); - preserveGeometry(); - m_geometry.markSourceDirty(); - m_borderGeometry.markSourceDirty(); - m_circle.polishAndUpdate(); - } - void preserveGeometry() - { - m_geometry.setPreserveGeometry(true, m_leftBound); - m_borderGeometry.setPreserveGeometry(true, m_leftBound); - } - void onMapSet() override - { - markSourceDirtyAndUpdate(); - } - void onGeoGeometryChanged() override - { - - markSourceDirtyAndUpdate(); - } - void onItemGeometryChanged() override - { - onGeoGeometryChanged(); - } - void afterViewportChanged() override - { - preserveGeometry(); - markScreenDirtyAndUpdate(); - } - void updatePolish() override; - QSGNode * updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override; - bool contains(const QPointF &point) const override; - - QGeoMapPolygonGeometryOpenGL m_geometry; - QGeoMapPolylineGeometryOpenGL m_borderGeometry; - QDeclarativePolygonMapItemPrivateOpenGL::RootNode *m_rootNode = nullptr; - MapPolygonNodeGL *m_node = nullptr; - MapPolylineNodeOpenGL *m_polylinenode = nullptr; -}; - -QT_END_NAMESPACE - -#endif // QDECLARATIVECIRCLEMAPITEM_RHI_P_H diff --git a/src/location/quickmapitems/rhi/qdeclarativepolygonmapitem_rhi.cpp b/src/location/quickmapitems/rhi/qdeclarativepolygonmapitem_rhi.cpp deleted file mode 100644 index d09ce710..00000000 --- a/src/location/quickmapitems/rhi/qdeclarativepolygonmapitem_rhi.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/**************************************************************************** - ** - ** Copyright (C) 2022 The Qt Company Ltd. - ** Contact: https://www.qt.io/licensing/ - ** - ** 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 The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ - -#include "qdeclarativegeomapitemutils_p.h" -#include "qdeclarativepolygonmapitem_p.h" -#include "qdeclarativepolylinemapitem_p_p.h" -#include "qdeclarativepolygonmapitem_p_p.h" -#include "qdeclarativepolygonmapitem_rhi_p.h" -#include "qdeclarativerectanglemapitem_p_p.h" -#include "error_messages_p.h" - -#include <QtCore/QScopedValueRollback> -#include <qnumeric.h> -#include <QPainter> -#include <QPainterPath> -#include <QtQml/QQmlInfo> -#include <QtQuick/qsgnode.h> - -#include <QtQuick/private/qsgmaterialshader_p.h> -#include <QtLocation/private/qgeomap_p.h> -#include <QtPositioning/private/qlocationutils_p.h> -#include <QtPositioning/private/qdoublevector2d_p.h> -#include <QtPositioning/private/qclipperutils_p.h> -#include <QtPositioning/private/qgeopolygon_p.h> -#include <QtPositioning/private/qwebmercator_p.h> - -QT_BEGIN_NAMESPACE - -MapPolygonShader::MapPolygonShader() : QSGMaterialShader(*new QSGMaterialShaderPrivate(this)) -{ - setShaderFileName(VertexStage, QLatin1String(":/location/quickmapitems/rhi/shaders/polygon.vert.qsb")); - setShaderFileName(FragmentStage, QLatin1String(":/location/quickmapitems/rhi/shaders/polygon.frag.qsb")); -} - -bool MapPolygonShader::updateUniformData(RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); - MapPolygonMaterial *oldMaterial = static_cast<MapPolygonMaterial *>(oldEffect); - MapPolygonMaterial *newMaterial = static_cast<MapPolygonMaterial *>(newEffect); - - const QColor &c = newMaterial->color(); - const QMatrix4x4 &geoProjection = newMaterial->geoProjection(); - const QDoubleVector3D ¢er = newMaterial->center(); - - // It is safer to use vec4 instead on vec3, as described in: - // https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)#Memory_layout - QVector4D vecCenter, vecCenter_lowpart; - for (int i = 0; i < 3; i++) - QLocationUtils::split_double(center.get(i), &vecCenter[i], &vecCenter_lowpart[i]); - vecCenter[3] = 0; - vecCenter_lowpart[3] = 0; - - int offset = 0; - char *buf_p = state.uniformData()->data(); - - if (state.isMatrixDirty()) { - const QMatrix4x4 m = state.projectionMatrix(); - memcpy(buf_p + offset, m.constData(), 4*4*4); - } - offset += 4*4*4; - - memcpy(buf_p + offset, geoProjection.constData(), 4*4*4); offset+=4*4*4; - - memcpy(buf_p + offset, &vecCenter, 4*4); offset += 4*4; - - memcpy(buf_p + offset, &vecCenter_lowpart, 4*4); offset+=4*4; - - const float wrapOffset = newMaterial->wrapOffset(); - memcpy(buf_p + offset, &wrapOffset, 4); offset+=4; - - offset += 4+4+4; // Padding - - if (oldMaterial == nullptr || c != oldMaterial->color() || state.isOpacityDirty()) { - float opacity = state.opacity() * c.alphaF(); - QVector4D v(c.redF() * opacity, - c.greenF() * opacity, - c.blueF() * opacity, - opacity); - memcpy(buf_p + offset, &v, 4*4); - } - offset+=4*4; - - return true; -} - -QSGMaterialShader *MapPolygonMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const -{ - Q_UNUSED(renderMode); - return new MapPolygonShader(); -} - -int MapPolygonMaterial::compare(const QSGMaterial *other) const -{ - const MapPolygonMaterial &o = *static_cast<const MapPolygonMaterial *>(other); - if (o.m_center == m_center && o.m_geoProjection == m_geoProjection && o.m_wrapOffset == m_wrapOffset) - return QSGFlatColorMaterial::compare(other); - return -1; -} - -QSGMaterialType *MapPolygonMaterial::type() const -{ - static QSGMaterialType type; - return &type; -} - -MapPolygonNodeGL::MapPolygonNodeGL() : - //fill_material_(this), - fill_material_(), - geometry_(QSGGeometry::defaultAttributes_Point2D(), 0) -{ - geometry_.setDrawingMode(QSGGeometry::DrawTriangles); - QSGGeometryNode::setMaterial(&fill_material_); - QSGGeometryNode::setGeometry(&geometry_); -} - -MapPolygonNodeGL::~MapPolygonNodeGL() -{ -} - -/*! - \internal -*/ -void MapPolygonNodeGL::update(const QColor &fillColor, - const QGeoMapPolygonGeometryOpenGL *fillShape, - const QMatrix4x4 &geoProjection, - const QDoubleVector3D ¢er) -{ - if (fillShape->m_screenIndices.size() < 3 || fillColor.alpha() == 0) { - setSubtreeBlocked(true); - return; - } - setSubtreeBlocked(false); - - QSGGeometry *fill = QSGGeometryNode::geometry(); - if (fillShape->m_dataChanged || !fill->vertexCount()) { - fillShape->allocateAndFillPolygon(fill); - markDirty(DirtyGeometry); - fillShape->m_dataChanged = false; - } - - //if (fillColor != fill_material_.color()) // Any point in optimizing this? - { - fill_material_.setColor(fillColor); - fill_material_.setGeoProjection(geoProjection); - fill_material_.setCenter(center); - fill_material_.setWrapOffset(fillShape->m_wrapOffset - 1); - setMaterial(&fill_material_); - markDirty(DirtyMaterial); - } -} - -QDeclarativePolygonMapItemPrivateOpenGL::~QDeclarativePolygonMapItemPrivateOpenGL() {} - - -void QDeclarativePolygonMapItemPrivateOpenGL::updatePolish() -{ - if (m_poly.m_geopoly.perimeter().length() == 0) { // Possibly cleared - m_geometry.clear(); - m_borderGeometry.clear(); - m_poly.setWidth(0); - m_poly.setHeight(0); - return; - } - - QScopedValueRollback<bool> rollback(m_poly.m_updatingGeometry); - m_poly.m_updatingGeometry = true; - const qreal lineWidth = m_poly.m_border.width(); - const QColor &lineColor = m_poly.m_border.color(); - const QColor &fillColor = m_poly.color(); - if (fillColor.alpha() != 0) { - m_geometry.updateSourcePoints(*m_poly.map(), m_poly.m_geopoly); - m_geometry.markScreenDirty(); - m_geometry.updateScreenPoints(*m_poly.map(), lineWidth, lineColor); - } else { - m_geometry.clearBounds(); - } - - QGeoMapItemGeometry * geom = &m_geometry; - m_borderGeometry.clearScreen(); - if (lineColor.alpha() != 0 && lineWidth > 0) { - m_borderGeometry.updateSourcePoints(*m_poly.map(), m_poly.m_geopoly); - m_borderGeometry.markScreenDirty(); - m_borderGeometry.updateScreenPoints(*m_poly.map(), lineWidth); - geom = &m_borderGeometry; - } - m_poly.setWidth(geom->sourceBoundingBox().width()); - m_poly.setHeight(geom->sourceBoundingBox().height()); - m_poly.setPosition(1.0 * geom->firstPointOffset() - QPointF(lineWidth * 0.5,lineWidth * 0.5)); -} - -QSGNode *QDeclarativePolygonMapItemPrivateOpenGL::updateMapItemPaintNode(QSGNode *oldNode, - QQuickItem::UpdatePaintNodeData *data) -{ - Q_UNUSED(data); - - if (!m_rootNode || !oldNode) { - m_rootNode = new RootNode(); - m_node = new MapPolygonNodeGL(); - m_rootNode->appendChildNode(m_node); - m_polylinenode = new MapPolylineNodeOpenGL(); - m_rootNode->appendChildNode(m_polylinenode); - m_rootNode->markDirty(QSGNode::DirtyNodeAdded); - if (oldNode) - delete oldNode; - } else { - m_rootNode = static_cast<RootNode *>(oldNode); - } - - const QGeoMap *map = m_poly.map(); - const QMatrix4x4 &combinedMatrix = map->geoProjection().qsgTransform(); - const QDoubleVector3D &cameraCenter = map->geoProjection().centerMercator(); - - if (m_borderGeometry.isScreenDirty()) { - /* Do the border update first */ - m_polylinenode->update(m_poly.m_border.color(), - float(m_poly.m_border.width()), - &m_borderGeometry, - combinedMatrix, - cameraCenter, - Qt::SquareCap, - true, - 30); // No LOD for polygons just yet. - // First figure out what to do with holes. - m_borderGeometry.setPreserveGeometry(false); - m_borderGeometry.markClean(); - } else { - m_polylinenode->setSubtreeBlocked(true); - } - if (m_geometry.isScreenDirty()) { - m_node->update(m_poly.m_color, - &m_geometry, - combinedMatrix, - cameraCenter); - m_geometry.setPreserveGeometry(false); - m_geometry.markClean(); - } else { - m_node->setSubtreeBlocked(true); - } - - m_rootNode->setSubtreeBlocked(false); - return m_rootNode; -} - -bool QDeclarativePolygonMapItemPrivateOpenGL::contains(const QPointF &point) const -{ - const qreal lineWidth = m_poly.m_border.width(); - const QColor &lineColor = m_poly.m_border.color(); - const QRectF &bounds = (lineColor.alpha() != 0 && lineWidth > 0) - ? m_borderGeometry.sourceBoundingBox() - : m_geometry.sourceBoundingBox(); - if (bounds.contains(point)) { - QDeclarativeGeoMap *m = m_poly.quickMap(); - if (m) { - const QGeoCoordinate crd = m->toCoordinate(m->mapFromItem(&m_poly, point)); - const auto &projection = static_cast<const QGeoProjectionWebMercator&>( - m_poly.map()->geoProjection()); - return m_poly.m_geopoly.contains(crd) - || m_borderGeometry.contains(m_poly.mapToItem(m_poly.quickMap(), point), - m_poly.border()->width(), projection); - } else { - return true; - } - } - return false; -} - -QT_END_NAMESPACE diff --git a/src/location/quickmapitems/rhi/qdeclarativepolygonmapitem_rhi_p.h b/src/location/quickmapitems/rhi/qdeclarativepolygonmapitem_rhi_p.h deleted file mode 100644 index 5aeb625a..00000000 --- a/src/location/quickmapitems/rhi/qdeclarativepolygonmapitem_rhi_p.h +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Paolo Angelelli <paolo.angelelli@gmail.com> -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVEPOLYGONMAPITEM_RHI_P_H -#define QDECLARATIVEPOLYGONMAPITEM_RHI_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QList> -#include <QtCore/QScopedValueRollback> -#include <QtGui/QMatrix4x4> -#include <QColor> - -#include <QSGGeometryNode> -#include <QSGFlatColorMaterial> - -#include <QtPositioning/QGeoPath> -#include <QtPositioning/QGeoRectangle> -#include <QtPositioning/QGeoPolygon> - -#include <QtLocation/private/qlocationglobal_p.h> -#include <QtLocation/private/qgeomapitemgeometry_p.h> -#include <QtLocation/private/qdeclarativegeomapitembase_p.h> -#include <QtLocation/private/qdeclarativepolylinemapitem_p.h> -#include <QtLocation/private/qdeclarativepolygonmapitem_p.h> -#include <QtLocation/private/qdeclarativepolygonmapitem_p_p.h> -#include <QtLocation/private/qdeclarativepolylinemapitem_rhi_p.h> -#include <QtPositioning/private/qdoublevector2d_p.h> - -QT_BEGIN_NAMESPACE - -class Q_LOCATION_PRIVATE_EXPORT MapPolygonMaterial : public QSGFlatColorMaterial -{ -public: - MapPolygonMaterial() - : QSGFlatColorMaterial() - { - // Passing RequiresFullMatrix is essential in order to prevent the - // batch renderer from baking in simple, translate-only transforms into - // the vertex data. The shader will rely on the fact that - // vertexCoord.xy is the Shape-space coordinate and so no modifications - // are welcome. - setFlag(Blending | RequiresFullMatrix); - } - - QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override; - - void setGeoProjection(const QMatrix4x4 &p) - { - m_geoProjection = p; - } - - QMatrix4x4 geoProjection() const - { - return m_geoProjection; - } - - void setCenter(const QDoubleVector3D &c) - { - m_center = c; - } - - QDoubleVector3D center() const - { - return m_center; - } - - int wrapOffset() const - { - return m_wrapOffset; - } - - void setWrapOffset(int wrapOffset) - { - m_wrapOffset = wrapOffset; - } - - int compare(const QSGMaterial *other) const override; - QSGMaterialType *type() const override; - -protected: - QMatrix4x4 m_geoProjection; - QDoubleVector3D m_center; - int m_wrapOffset = 0; -}; - -class Q_LOCATION_PRIVATE_EXPORT MapPolygonShader : public QSGMaterialShader -{ -public: - MapPolygonShader(); - - bool updateUniformData(RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override; -}; - -class Q_LOCATION_PRIVATE_EXPORT MapPolygonNodeGL : public MapItemGeometryNode -{ - -public: - MapPolygonNodeGL(); - ~MapPolygonNodeGL() override; - - void update(const QColor &fillColor, - const QGeoMapPolygonGeometryOpenGL *fillShape, - const QMatrix4x4 &geoProjection, - const QDoubleVector3D ¢er); - - MapPolygonMaterial fill_material_; - QSGGeometry geometry_; -}; - -class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolygonMapItemPrivateOpenGL: public QDeclarativePolygonMapItemPrivate -{ -public: - struct RootNode : public QSGNode /*QSGTransformNode*/, public VisibleNode - { - RootNode() { } - - bool isSubtreeBlocked() const override - { - return subtreeBlocked(); - } - }; - - QDeclarativePolygonMapItemPrivateOpenGL(QDeclarativePolygonMapItem &polygon) - : QDeclarativePolygonMapItemPrivate(polygon) - { - } - - ~QDeclarativePolygonMapItemPrivateOpenGL() override; - - void markScreenDirtyAndUpdate() - { - // preserveGeometry is cleared in updateMapItemPaintNode - m_geometry.markScreenDirty(); - m_borderGeometry.markScreenDirty(); - m_poly.polishAndUpdate(); - } - void onLinePropertiesChanged() override - { - m_poly.m_dirtyMaterial = true; - afterViewportChanged(); - } - void markSourceDirtyAndUpdate() override - { - // preserveGeometry is cleared in updateMapItemPaintNode - m_geometry.markSourceDirty(); - m_borderGeometry.markSourceDirty(); - m_poly.polishAndUpdate(); - } - void preserveGeometry() - { - m_geometry.setPreserveGeometry(true, m_poly.m_geopoly.boundingGeoRectangle().topLeft()); - m_borderGeometry.setPreserveGeometry(true, m_poly.m_geopoly.boundingGeoRectangle().topLeft()); - } - void afterViewportChanged() override // This is called when the camera changes, or visibleArea changes. - { - // preserveGeometry is cleared in updateMapItemPaintNode - preserveGeometry(); - markScreenDirtyAndUpdate(); - } - void onMapSet() override - { - markSourceDirtyAndUpdate(); - } - void onGeoGeometryChanged() override - { - preserveGeometry(); - markSourceDirtyAndUpdate(); - } - void onGeoGeometryUpdated() override - { - preserveGeometry(); - markSourceDirtyAndUpdate(); - } - void onItemGeometryChanged() override - { - onGeoGeometryChanged(); - } - void updatePolish() override; - QSGNode * updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override; - bool contains(const QPointF &point) const override; - - QGeoMapPolygonGeometryOpenGL m_geometry; - QGeoMapPolylineGeometryOpenGL m_borderGeometry; - RootNode *m_rootNode = nullptr; - MapPolygonNodeGL *m_node = nullptr; - MapPolylineNodeOpenGL *m_polylinenode = nullptr; -}; - - -QT_END_NAMESPACE - -#endif // QDECLARATIVEPOLYGONMAPITEM_RHI_P_H diff --git a/src/location/quickmapitems/rhi/qdeclarativepolylinemapitem_rhi.cpp b/src/location/quickmapitems/rhi/qdeclarativepolylinemapitem_rhi.cpp deleted file mode 100644 index edcd4cfe..00000000 --- a/src/location/quickmapitems/rhi/qdeclarativepolylinemapitem_rhi.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/**************************************************************************** - ** - ** Copyright (C) 2022 The Qt Company Ltd. - ** Contact: https://www.qt.io/licensing/ - ** - ** 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 The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ - -#include "qdeclarativepolygonmapitem_rhi_p.h" - -#include <QtQuick/private/qsgmaterialshader_p.h> -#include <QtPositioning/private/qlocationutils_p.h> - -QT_BEGIN_NAMESPACE - -const QSGGeometry::AttributeSet &MapPolylineNodeOpenGL::attributesMapPolylineTriangulated() -{ - return MapPolylineEntry::attributes(); -} - -MapPolylineNodeOpenGL::MapPolylineNodeOpenGL() -: m_geometryTriangulating(MapPolylineNodeOpenGL::attributesMapPolylineTriangulated(), - 0 /* vtx cnt */, 0 /* index cnt */, QSGGeometry::UnsignedIntType /* index type */) -{ - m_geometryTriangulating.setDrawingMode(QSGGeometry::DrawTriangles); - QSGGeometryNode::setMaterial(&fill_material_); - QSGGeometryNode::setGeometry(&m_geometryTriangulating); -} - -MapPolylineNodeOpenGL::~MapPolylineNodeOpenGL() -{ - -} - -bool QGeoMapPolylineGeometryOpenGL::allocateAndFillEntries(QSGGeometry *geom, - bool closed, - unsigned int zoom) const -{ - // Select LOD. Generate if not present. Assign it to m_screenVertices; - if (m_dataChanged) { - // it means that the data really changed. - // So synchronously produce LOD 1, and enqueue the requested one if != 0 or 1. - // Select 0 if 0 is requested, or 1 in all other cases. - selectLODOnDataChanged(zoom, m_bboxLeftBoundWrapped.x()); - } else { - // Data has not changed, but active LOD != requested LOD. - // So, if there are no active tasks, try to change to the correct one. - if (!selectLODOnLODMismatch(zoom, m_bboxLeftBoundWrapped.x(), closed)) - return false; - } - - const QList<QDeclarativeGeoMapItemUtils::vec2> &v = *m_screenVertices; - if (v.size() < 2) { - geom->allocate(0, 0); - return true; - } - const int numSegments = (v.size() - 1); - - const int numIndices = numSegments * 6; // six vertices per line segment - geom->allocate(numIndices); - MapPolylineNodeOpenGL::MapPolylineEntry *vertices = - static_cast<MapPolylineNodeOpenGL::MapPolylineEntry *>(geom->vertexData()); - - for (int i = 0; i < numSegments; ++i) { - MapPolylineNodeOpenGL::MapPolylineEntry e; - const QDeclarativeGeoMapItemUtils::vec2 &cur = v[i]; - const QDeclarativeGeoMapItemUtils::vec2 &next = v[i+1]; - e.triangletype = 1.0; - e.next = next; - e.prev = cur; - e.pos = cur; - e.direction = 1.0; - e.vertextype = -1.0; - vertices[i*6] = e; - e.direction = -1.0; - vertices[i*6+1] = e; - e.pos = next; - e.vertextype = 1.0; - vertices[i*6+2] = e; - - // Second tri - e.triangletype = -1.0; - e.direction = -1.0; - vertices[i*6+3] = e; - e.direction = 1.0; - vertices[i*6+4] = e; - e.pos = cur; - e.vertextype = -1.0; - vertices[i*6+5] = e; - - if (i != 0) { - vertices[i*6].prev = vertices[i*6+1].prev = vertices[i*6+5].prev = v[i-1]; - } else { - if (closed) { - vertices[i*6].prev = vertices[i*6+1].prev = vertices[i*6+5].prev = v[numSegments - 1]; - } else { - vertices[i*6].triangletype = vertices[i*6+1].triangletype = vertices[i*6+5].triangletype = 2.0; - } - } - if (i != numSegments - 1) { - vertices[i*6+2].next = vertices[i*6+3].next = vertices[i*6+4].next = v[i+2]; - } else { - if (closed) { - vertices[i*6+2].next = vertices[i*6+3].next = vertices[i*6+4].next = v[1]; - } else { - vertices[i*6+2].triangletype = vertices[i*6+3].triangletype = vertices[i*6+4].triangletype = 3.0; - } - } - } - return true; -} - -void MapPolylineNodeOpenGL::update(const QColor &fillColor, - float lineWidth, - const QGeoMapPolylineGeometryOpenGL *shape, - const QMatrix4x4 &geoProjection, - const QDoubleVector3D ¢er, - const Qt::PenCapStyle capStyle, - bool closed, - unsigned int zoom) -{ - // shape->size() == number of triangles - if (shape->m_screenVertices->size() < 2 - || lineWidth < 0.5 || fillColor.alpha() == 0) { // number of points - setSubtreeBlocked(true); - return; - } else { - setSubtreeBlocked(false); - } - - QSGGeometry *fill = QSGGeometryNode::geometry(); - if (shape->m_dataChanged || !shape->isLODActive(zoom) || !fill->vertexCount()) { // fill->vertexCount for when node gets destroyed by MapItemBase bcoz of opacity, then recreated. - if (shape->allocateAndFillEntries(fill, closed, zoom)) { - markDirty(DirtyGeometry); - shape->m_dataChanged = false; - } - } - - // Update this -// if (fillColor != fill_material_.color()) - { - fill_material_.setWrapOffset(shape->m_wrapOffset - 1); - fill_material_.setColor(fillColor); - fill_material_.setGeoProjection(geoProjection); - fill_material_.setCenter(center); - fill_material_.setLineWidth(lineWidth); - fill_material_.setMiter(capStyle != Qt::FlatCap); - setMaterial(&fill_material_); - markDirty(DirtyMaterial); - } -} - -MapPolylineShader::MapPolylineShader() : QSGMaterialShader(*new QSGMaterialShaderPrivate(this)) -{ - // Heavily adapted from https://github.com/mattdesl/webgl-lines/blob/master/projected/vert.glsl, - // that is (c) Matt DesLauriers, and released under the MIT license. - setShaderFileName(VertexStage, QLatin1String(":/location/quickmapitems/rhi/shaders/polyline.vert.qsb")); - setShaderFileName(FragmentStage, QLatin1String(":/location/quickmapitems/rhi/shaders/polyline.frag.qsb")); -} - -bool MapPolylineShader::updateUniformData(QSGMaterialShader::RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); - MapPolylineMaterial *oldMaterial = static_cast<MapPolylineMaterial *>(oldEffect); - MapPolylineMaterial *newMaterial = static_cast<MapPolylineMaterial *>(newEffect); - - const QColor &c = newMaterial->color(); - const QMatrix4x4 &geoProjection = newMaterial->geoProjection(); - const QDoubleVector3D ¢er = newMaterial->center(); - - // It is safer to use vec4 instead on vec3, as described in: - // https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)#Memory_layout - QVector4D vecCenter, vecCenter_lowpart; - for (int i = 0; i < 3; i++) - QLocationUtils::split_double(center.get(i), &vecCenter[i], &vecCenter_lowpart[i]); - vecCenter[3] = 0; - vecCenter_lowpart[3] = 0; - - int offset = 0; - char *buf_p = state.uniformData()->data(); - - if (state.isMatrixDirty()) { - const QMatrix4x4 m = state.projectionMatrix(); - memcpy(buf_p + offset, m.constData(), 4*4*4); - } - offset += 4*4*4; - - memcpy(buf_p + offset, geoProjection.constData(), 4*4*4); offset+=4*4*4; - - memcpy(buf_p + offset, &vecCenter, 4*4); offset += 4*4; - - memcpy(buf_p + offset, &vecCenter_lowpart, 4*4); offset+=4*4; - - const float lineWidth = newMaterial->lineWidth(); - memcpy(buf_p + offset, &lineWidth, 4); offset+=4; - - const QRectF viewportRect = state.viewportRect(); - const float aspect = float(viewportRect.width() / viewportRect.height()); - memcpy(buf_p + offset, &aspect, 4); offset+=4; - - offset += 4; // Padding - - int miter = newMaterial->miter(); - memcpy(buf_p + offset, &miter, 4); offset+=4; - - if (oldMaterial == nullptr || c != oldMaterial->color() || state.isOpacityDirty()) { - float opacity = state.opacity() * c.alphaF(); - QVector4D v(c.redF() * opacity, - c.greenF() * opacity, - c.blueF() * opacity, - opacity); - memcpy(buf_p + offset, &v, 4*4); - } - offset+=4*4; - - const float wrapOffset = newMaterial->wrapOffset(); - memcpy(buf_p + offset, &wrapOffset, 4); offset+=4; - - return true; -} - -QSGMaterialShader *MapPolylineMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const -{ - Q_UNUSED(renderMode); - return new MapPolylineShader(); -} - -QSGMaterialType *MapPolylineMaterial::type() const -{ - static QSGMaterialType type; - return &type; -} - -int MapPolylineMaterial::compare(const QSGMaterial *other) const -{ - const MapPolylineMaterial &o = *static_cast<const MapPolylineMaterial *>(other); - if (o.m_center == m_center - && o.m_geoProjection == m_geoProjection - && o.m_wrapOffset == m_wrapOffset - && o.m_lineWidth == m_lineWidth - && o.m_miter == m_miter) - { - return QSGFlatColorMaterial::compare(other); - } - return -1; -} - -bool QDeclarativePolylineMapItemPrivateOpenGL::contains(const QPointF &point) const -{ - return m_geometry.contains(m_poly.mapToItem(m_poly.quickMap(), point), - m_poly.line()->width(), - static_cast<const QGeoProjectionWebMercator&>(m_poly.map()->geoProjection())); -} - -void QDeclarativePolylineMapItemPrivateOpenGL::updatePolish() -{ - if (m_poly.m_geopath.path().length() == 0) { // Possibly cleared - m_geometry.clear(); - m_geometry.clear(); - m_poly.setWidth(0); - m_poly.setHeight(0); - return; - } - - QScopedValueRollback<bool> rollback(m_poly.m_updatingGeometry); - m_poly.m_updatingGeometry = true; - const qreal lineWidth = m_poly.m_line.width(); - m_geometry.updateSourcePoints(*m_poly.map(), m_poly.m_geopath); - m_geometry.markScreenDirty(); - m_geometry.updateScreenPoints(*m_poly.map(), lineWidth); - - m_poly.setWidth(m_geometry.sourceBoundingBox().width()); - m_poly.setHeight(m_geometry.sourceBoundingBox().height()); - m_poly.setPosition(1.0 * m_geometry.firstPointOffset() - QPointF(lineWidth * 0.5,lineWidth * 0.5)); -} - -QDeclarativePolylineMapItemPrivateOpenGL::~QDeclarativePolylineMapItemPrivateOpenGL() {} - -QSGNode *QDeclarativePolylineMapItemPrivateOpenGL::updateMapItemPaintNode(QSGNode *oldNode, - QQuickItem::UpdatePaintNodeData *data) -{ - Q_UNUSED(data); - const QGeoMap *map = m_poly.map(); - const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map->geoProjection()); - const QMatrix4x4 &combinedMatrix = p.qsgTransform(); - const QDoubleVector3D &cameraCenter = p.centerMercator(); - const QColor &color = m_poly.m_line.color(); - const float lineWidth = m_poly.m_line.width(); - - MapPolylineNodeOpenGL *nodeTri = nullptr; - if (!m_nodeTri || !oldNode) { - if (oldNode) - delete oldNode; - nodeTri = new MapPolylineNodeOpenGL(); - } else { - nodeTri = static_cast<MapPolylineNodeOpenGL *>(oldNode); - } - - //TODO: update only material - if (m_geometry.isScreenDirty() || m_poly.m_dirtyMaterial) { - nodeTri->update(color, - lineWidth , - &m_geometry, - combinedMatrix, - cameraCenter, - Qt::FlatCap, - false, - m_poly.zoomForLOD(int(map->cameraData().zoomLevel()))); - m_geometry.setPreserveGeometry(false); - m_geometry.markClean(); - m_poly.m_dirtyMaterial = false; - } - m_nodeTri = nodeTri; - return nodeTri; -} - - -QT_END_NAMESPACE diff --git a/src/location/quickmapitems/rhi/qdeclarativepolylinemapitem_rhi_p.h b/src/location/quickmapitems/rhi/qdeclarativepolylinemapitem_rhi_p.h deleted file mode 100644 index 88e0692f..00000000 --- a/src/location/quickmapitems/rhi/qdeclarativepolylinemapitem_rhi_p.h +++ /dev/null @@ -1,267 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Paolo Angelelli <paolo.angelelli@gmail.com> -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVEPOLYLINEMAPITEM_RHI_P_H -#define QDECLARATIVEPOLYLINEMAPITEM_RHI_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/QScopedValueRollback> -#include <QSGMaterialShader> - -#include <QtLocation/private/qlocationglobal_p.h> -#include <QtLocation/private/qdeclarativepolylinemapitem_p.h> -#include <QtLocation/private/qdeclarativepolylinemapitem_p_p.h> -#include <QtLocation/private/qgeomapitemgeometry_p.h> -#include <QtLocation/private/qgeomapitemgeometry_rhi_p.h> - -#include <QtPositioning/private/qdoublevector2d_p.h> - -#include <array> - -QT_BEGIN_NAMESPACE - -class Q_LOCATION_PRIVATE_EXPORT MapPolylineShader : public QSGMaterialShader -{ -public: - MapPolylineShader(); - - bool updateUniformData(RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override; -}; - -class Q_LOCATION_PRIVATE_EXPORT MapPolylineMaterial : public QSGFlatColorMaterial -{ -public: - MapPolylineMaterial() : QSGFlatColorMaterial() - { - // Passing RequiresFullMatrix is essential in order to prevent the - // batch renderer from baking in simple, translate-only transforms into - // the vertex data. The shader will rely on the fact that - // vertexCoord.xy is the Shape-space coordinate and so no modifications - // are welcome. - setFlag(Blending | RequiresFullMatrix); - } - - QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override; - - void setGeoProjection(const QMatrix4x4 &p) - { - m_geoProjection = p; - } - - QMatrix4x4 geoProjection() const - { - return m_geoProjection; - } - - void setCenter(const QDoubleVector3D &c) - { - m_center = c; - } - - QDoubleVector3D center() const - { - return m_center; - } - - int wrapOffset() const - { - return m_wrapOffset; - } - - void setWrapOffset(int wrapOffset) - { - m_wrapOffset = wrapOffset; - } - - void setLineWidth(float lw) - { - m_lineWidth = lw; - } - - float lineWidth() const - { - return m_lineWidth; - } - - void setMiter(int m) - { - m_miter = m; - } - - int miter() const - { - return m_miter; - } - - QSGMaterialType *type() const override; - int compare(const QSGMaterial *other) const override; - - QMatrix4x4 m_geoProjection; - QDoubleVector3D m_center; - int m_wrapOffset = 0; - float m_lineWidth = 1.0; - int m_miter = 0; -}; - -class Q_LOCATION_PRIVATE_EXPORT MapPolylineNodeOpenGL : public MapItemGeometryNode -{ -public: - - typedef struct MapPolylineEntry { - QDeclarativeGeoMapItemUtils::vec2 pos; - QDeclarativeGeoMapItemUtils::vec2 prev; - QDeclarativeGeoMapItemUtils::vec2 next; - float direction; - float triangletype; // es2 does not support int attribs - float vertextype; - - static const QSGGeometry::AttributeSet &attributes() - { - static const QSGGeometry::Attribute dataTri[] = { - QSGGeometry::Attribute::createWithAttributeType(0, 2, - QSGGeometry::FloatType, QSGGeometry::PositionAttribute) // pos - ,QSGGeometry::Attribute::createWithAttributeType(1, 2, - QSGGeometry::FloatType, QSGGeometry::UnknownAttribute) // next - ,QSGGeometry::Attribute::createWithAttributeType(2, 2, - QSGGeometry::FloatType, QSGGeometry::UnknownAttribute) // previous - ,QSGGeometry::Attribute::createWithAttributeType(3, 1, - QSGGeometry::FloatType, QSGGeometry::UnknownAttribute) // direction - ,QSGGeometry::Attribute::createWithAttributeType(4, 1, - QSGGeometry::FloatType, QSGGeometry::UnknownAttribute) // triangletype - ,QSGGeometry::Attribute::createWithAttributeType(5, 1, - QSGGeometry::FloatType, QSGGeometry::UnknownAttribute) // vertextype - }; - static const QSGGeometry::AttributeSet attrsTri = { - 6, - sizeof(MapPolylineNodeOpenGL::MapPolylineEntry), - dataTri - }; - return attrsTri; - } - } MapPolylineEntry; - - MapPolylineNodeOpenGL(); - ~MapPolylineNodeOpenGL() override; - - void update(const QColor &fillColor, - float lineWidth, - const QGeoMapPolylineGeometryOpenGL *shape, - const QMatrix4x4 &geoProjection, - const QDoubleVector3D ¢er, - const Qt::PenCapStyle capStyle = Qt::FlatCap, - bool closed = false, - unsigned int zoom = 30); - - static const QSGGeometry::AttributeSet &attributesMapPolylineTriangulated(); - -protected: - MapPolylineMaterial fill_material_; - QSGGeometry m_geometryTriangulating; -}; - -class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolylineMapItemPrivateOpenGL: public QDeclarativePolylineMapItemPrivate -{ -public: - - QDeclarativePolylineMapItemPrivateOpenGL(QDeclarativePolylineMapItem &poly) - : QDeclarativePolylineMapItemPrivate(poly) - { - } - - ~QDeclarativePolylineMapItemPrivateOpenGL() override; - - void onLinePropertiesChanged() override - { - afterViewportChanged(); - } - void markSourceDirtyAndUpdate() override - { - m_geometry.markSourceDirty(); - m_poly.polishAndUpdate(); - } - void preserveGeometry() - { - m_geometry.setPreserveGeometry(true, m_poly.m_geopath.boundingGeoRectangle().topLeft()); - } - void onMapSet() override - { - markSourceDirtyAndUpdate(); - } - void onGeoGeometryChanged() override - { - preserveGeometry(); - markSourceDirtyAndUpdate(); - } - void onGeoGeometryUpdated() override - { - preserveGeometry(); - markSourceDirtyAndUpdate(); - } - void onItemGeometryChanged() override - { - onGeoGeometryChanged(); - } - void afterViewportChanged() override - { - preserveGeometry(); - m_poly.polishAndUpdate(); - } - - bool contains(const QPointF &point) const override; - void updatePolish() override; - QSGNode * updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override; - - QGeoMapPolylineGeometryOpenGL m_geometry; - MapPolylineNodeOpenGL *m_nodeTri = nullptr; -}; - -QT_END_NAMESPACE - -#endif // QDECLARATIVEPOLYLINEMAPITEM_RHI_P_H diff --git a/src/location/quickmapitems/rhi/qdeclarativerectanglemapitem_rhi.cpp b/src/location/quickmapitems/rhi/qdeclarativerectanglemapitem_rhi.cpp deleted file mode 100644 index 5bf81384..00000000 --- a/src/location/quickmapitems/rhi/qdeclarativerectanglemapitem_rhi.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** - ** - ** Copyright (C) 2022 The Qt Company Ltd. - ** Contact: https://www.qt.io/licensing/ - ** - ** 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 The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ - -#include "qdeclarativerectanglemapitem_rhi_p.h" - -QT_BEGIN_NAMESPACE - -QDeclarativeRectangleMapItemPrivateOpenGL::~QDeclarativeRectangleMapItemPrivateOpenGL() {} - - -void QDeclarativeRectangleMapItemPrivateOpenGL::updatePolish() -{ - if (!m_rect.topLeft().isValid() || !m_rect.bottomRight().isValid()) { - m_geometry.clear(); - m_borderGeometry.clear(); - m_rect.setWidth(0); - m_rect.setHeight(0); - return; - } - - QScopedValueRollback<bool> rollback(m_rect.m_updatingGeometry); - m_rect.m_updatingGeometry = true; - const qreal lineWidth = m_rect.m_border.width(); - const QColor &lineColor = m_rect.m_border.color(); - const QColor &fillColor = m_rect.color(); - if (fillColor.alpha() != 0) { - m_geometry.updateSourcePoints(*m_rect.map(), m_rect.m_rectangle); - m_geometry.markScreenDirty(); - m_geometry.updateScreenPoints(*m_rect.map(), lineWidth, lineColor); - } else { - m_geometry.clearBounds(); - } - - QGeoMapItemGeometry * geom = &m_geometry; - m_borderGeometry.clearScreen(); - if (lineColor.alpha() != 0 && lineWidth > 0) { - m_borderGeometry.updateSourcePoints(*m_rect.map(), m_rect.m_rectangle); - m_borderGeometry.markScreenDirty(); - m_borderGeometry.updateScreenPoints(*m_rect.map(), lineWidth); - geom = &m_borderGeometry; - } - m_rect.setWidth(geom->sourceBoundingBox().width()); - m_rect.setHeight(geom->sourceBoundingBox().height()); - m_rect.setPosition(1.0 * geom->firstPointOffset() - QPointF(lineWidth * 0.5,lineWidth * 0.5)); -} - -QSGNode *QDeclarativeRectangleMapItemPrivateOpenGL::updateMapItemPaintNode(QSGNode *oldNode, - QQuickItem::UpdatePaintNodeData *data) -{ - Q_UNUSED(data); - - if (!m_rootNode || !oldNode) { - m_rootNode = new QDeclarativePolygonMapItemPrivateOpenGL::RootNode(); - m_node = new MapPolygonNodeGL(); - m_rootNode->appendChildNode(m_node); - m_polylinenode = new MapPolylineNodeOpenGL(); - m_rootNode->appendChildNode(m_polylinenode); - m_rootNode->markDirty(QSGNode::DirtyNodeAdded); - if (oldNode) - delete oldNode; - } else { - m_rootNode = static_cast<QDeclarativePolygonMapItemPrivateOpenGL::RootNode *>(oldNode); - } - - const QGeoMap *map = m_rect.map(); - const QMatrix4x4 &combinedMatrix = map->geoProjection().qsgTransform(); - const QDoubleVector3D &cameraCenter = map->geoProjection().centerMercator(); - - if (m_borderGeometry.isScreenDirty()) { - /* Do the border update first */ - m_polylinenode->update(m_rect.m_border.color(), - float(m_rect.m_border.width()), - &m_borderGeometry, - combinedMatrix, - cameraCenter, - Qt::SquareCap, - true, - 30); // No LOD for rectangles - m_borderGeometry.setPreserveGeometry(false); - m_borderGeometry.markClean(); - } else { - m_polylinenode->setSubtreeBlocked(true); - } - if (m_geometry.isScreenDirty()) { - m_node->update(m_rect.m_color, - &m_geometry, - combinedMatrix, - cameraCenter); - m_geometry.setPreserveGeometry(false); - m_geometry.markClean(); - } else { - m_node->setSubtreeBlocked(true); - } - - m_rootNode->setSubtreeBlocked(false); - return m_rootNode; -} - -bool QDeclarativeRectangleMapItemPrivateOpenGL::contains(const QPointF &point) const -{ - const qreal lineWidth = m_rect.m_border.width(); - const QColor &lineColor = m_rect.m_border.color(); - const QRectF &bounds = (lineColor.alpha() != 0 && lineWidth > 0) - ? m_borderGeometry.sourceBoundingBox() - : m_geometry.sourceBoundingBox(); - if (bounds.contains(point)) { - QDeclarativeGeoMap *m = m_rect.quickMap(); - if (m) { - const QGeoCoordinate crd = m->toCoordinate(m->mapFromItem(&m_rect, point)); - const auto &projection = static_cast<const QGeoProjectionWebMercator&>( - m_rect.map()->geoProjection()); - return m_rect.m_rectangle.contains(crd) - || m_borderGeometry.contains(m_rect.mapToItem(m_rect.quickMap(), point), - m_rect.border()->width(), projection); - } else { - return true; - } - } - return false; -} - -QT_END_NAMESPACE - diff --git a/src/location/quickmapitems/rhi/qdeclarativerectanglemapitem_rhi_p.h b/src/location/quickmapitems/rhi/qdeclarativerectanglemapitem_rhi_p.h deleted file mode 100644 index f3554669..00000000 --- a/src/location/quickmapitems/rhi/qdeclarativerectanglemapitem_rhi_p.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Paolo Angelelli <paolo.angelelli@gmail.com> -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVERECTANGLEMAPITEM_RHI_P_H -#define QDECLARATIVERECTANGLEMAPITEM_RHI_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtLocation/private/qlocationglobal_p.h> -#include <QtLocation/private/qdeclarativerectanglemapitem_p_p.h> -#include <QtLocation/private/qdeclarativepolygonmapitem_p_p.h> - -#include "qdeclarativepolygonmapitem_rhi_p.h" - -QT_BEGIN_NAMESPACE - -class Q_LOCATION_PRIVATE_EXPORT QDeclarativeRectangleMapItemPrivateOpenGL: public QDeclarativeRectangleMapItemPrivate -{ -public: - QDeclarativeRectangleMapItemPrivateOpenGL(QDeclarativeRectangleMapItem &rect) - : QDeclarativeRectangleMapItemPrivate(rect) - { - } - - ~QDeclarativeRectangleMapItemPrivateOpenGL() override; - - void markScreenDirtyAndUpdate() - { - // preserveGeometry is cleared in updateMapItemPaintNode - m_geometry.markScreenDirty(); - m_borderGeometry.markScreenDirty(); - m_rect.polishAndUpdate(); - } - void onLinePropertiesChanged() override - { - m_rect.m_dirtyMaterial = true; - afterViewportChanged(); - } - void markSourceDirtyAndUpdate() override - { - m_geometry.markSourceDirty(); - m_borderGeometry.markSourceDirty(); - m_rect.polishAndUpdate(); - } - void preserveGeometry() - { - m_geometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft()); - m_borderGeometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft()); - } - void onMapSet() override - { - markSourceDirtyAndUpdate(); - } - void onGeoGeometryChanged() override - { - preserveGeometry(); - markSourceDirtyAndUpdate(); - } - void onItemGeometryChanged() override - { - onGeoGeometryChanged(); - } - void afterViewportChanged() override - { - preserveGeometry(); - markScreenDirtyAndUpdate(); - } - void updatePolish() override; - QSGNode *updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override; - bool contains(const QPointF &point) const override; - - QGeoMapPolygonGeometryOpenGL m_geometry; - QGeoMapPolylineGeometryOpenGL m_borderGeometry; - QDeclarativePolygonMapItemPrivateOpenGL::RootNode *m_rootNode = nullptr; - MapPolygonNodeGL *m_node = nullptr; - MapPolylineNodeOpenGL *m_polylinenode = nullptr; -}; - -QT_END_NAMESPACE - -#endif // QDECLARATIVERECTANGLEMAPITEM_RHI_P_H diff --git a/src/location/quickmapitems/rhi/qgeomapitemgeometry_rhi.cpp b/src/location/quickmapitems/rhi/qgeomapitemgeometry_rhi.cpp deleted file mode 100644 index dddd9d07..00000000 --- a/src/location/quickmapitems/rhi/qgeomapitemgeometry_rhi.cpp +++ /dev/null @@ -1,729 +0,0 @@ -/**************************************************************************** - ** - ** Copyright (C) 2022 The Qt Company Ltd. - ** Contact: https://www.qt.io/licensing/ - ** - ** 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 The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ - -#include "qgeomapitemgeometry_rhi_p.h" - -#include <QThreadPool> -#include <QRunnable> - -#include <QtQuick/QSGGeometry> -#include <QtPositioning/private/qwebmercator_p.h> -#include <QtPositioning/private/qlocationutils_p.h> -#include <QtPositioning/QGeoCircle> -#include <QtPositioning/QGeoPolygon> -#include <QtPositioning/QGeoPath> -#include <QtPositioning/QGeoRectangle> - -#include <QtLocation/private/qgeomap_p.h> -#include <QtLocation/private/qdeclarativecirclemapitem_p_p.h> -#include <QtLocation/private/qgeosimplify_p.h> - -/* poly2tri triangulator includes */ -#include <earcut.hpp> -#include <array> - -QT_BEGIN_NAMESPACE - -/*! - \internal - Implementation of QGeoMapItemLODGeometry -*/ - -struct ThreadPool // to have a thread pool with max 1 thread for geometry processing -{ - ThreadPool () - { - m_threadPool.setMaxThreadCount(1); - } - - void start(QRunnable *runnable, int priority = 0) - { - m_threadPool.start(runnable, priority); - } - - QThreadPool m_threadPool; -}; - -Q_GLOBAL_STATIC(ThreadPool, threadPool) - -class PolylineSimplifyTask : public QRunnable -{ -public: - PolylineSimplifyTask(const QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>> - &input, // reference as it gets copied in the nested call - const QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>> &output, - double leftBound, unsigned int zoom, QSharedPointer<unsigned int> &working) - : m_zoom(zoom), m_leftBound(leftBound), m_input(input), m_output(output), m_working(working) - { - Q_ASSERT(!input.isNull()); - Q_ASSERT(!output.isNull()); - } - - void run() override - { - // Skip sending notifications for now. Updated data will be picked up eventually. - // ToDo: figure out how to connect a signal from here to a slot in the item. - *m_working = QGeoMapItemLODGeometry::zoomToLOD(m_zoom); - const QList<QDeclarativeGeoMapItemUtils::vec2> res = - QGeoMapItemLODGeometry::getSimplified( - *m_input, m_leftBound, QGeoMapItemLODGeometry::zoomForLOD(m_zoom)); - *m_output = res; - *m_working = 0; - } - - unsigned int m_zoom; - double m_leftBound; - QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>> m_input, m_output; - QSharedPointer<unsigned int> m_working; -}; - - -QGeoMapItemLODGeometry::QGeoMapItemLODGeometry() -{ - resetLOD(); -} - -void QGeoMapItemLODGeometry::resetLOD() -{ - // New pointer, some old LOD task might still be running and operating on the old pointers. - m_verticesLOD[0] = QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>>( - new QList<QDeclarativeGeoMapItemUtils::vec2>); - for (unsigned int i = 1; i < m_verticesLOD.size(); ++i) - m_verticesLOD[i] = nullptr; // allocate on first use - m_screenVertices = m_verticesLOD.front().data(); // resetting pointer to data to be LOD 0 -} - -QList<QDeclarativeGeoMapItemUtils::vec2> QGeoMapItemLODGeometry::getSimplified( - QList<QDeclarativeGeoMapItemUtils::vec2> - &wrappedPath, // reference as it gets copied in the nested call - double leftBoundWrapped, unsigned int zoom) -{ - // Try a simplify step - QList<QDoubleVector2D> data; - for (auto e: wrappedPath) - data << e.toDoubleVector2D(); - const QList<QDoubleVector2D> simplified = QGeoSimplify::geoSimplifyZL(data, - leftBoundWrapped, - zoom); - - data.clear(); - QList<QDeclarativeGeoMapItemUtils::vec2> simple; - for (auto e: simplified) - simple << e; - return simple; -} - -bool QGeoMapItemLODGeometry::isLODActive(unsigned int lod) const -{ - return m_screenVertices == m_verticesLOD[zoomToLOD(lod)].data(); -} - -bool QGeoMapItemLODGeometry::selectLODOnLODMismatch(unsigned int zoom, double leftBound, - bool closed) const -{ - if (*m_working > 0) - return false; - const_cast<QGeoMapItemLODGeometry *>(this)->selectLOD(zoom, leftBound, closed); - return true; -} - -void QGeoMapItemLODGeometry::enqueueSimplificationTask( - const QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>> &input, - const QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>> &output, double leftBound, - unsigned int zoom, QSharedPointer<unsigned int> &working) -{ - Q_ASSERT(!input.isNull()); - Q_ASSERT(!output.isNull()); - PolylineSimplifyTask *task = new PolylineSimplifyTask(input, - output, - leftBound, - zoom, - working); - threadPool->start(task); -} - -void QGeoMapItemLODGeometry::selectLOD(unsigned int zoom, double leftBound, bool /* closed */) // closed to tell if this is a polygon or a polyline. -{ - unsigned int requestedLod = zoomToLOD(zoom); - if (!m_verticesLOD[requestedLod].isNull()) { - m_screenVertices = m_verticesLOD[requestedLod].data(); - } else if (!m_verticesLOD.at(0)->isEmpty()) { - // if here, zoomToLOD != 0 and no current working task. - // So select the last filled LOD != m_working (lower-bounded by 1, - // guaranteed to exist), and enqueue the right one - m_verticesLOD[requestedLod] = QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>>( - new QList<QDeclarativeGeoMapItemUtils::vec2>); - - for (unsigned int i = requestedLod - 1; i >= 1; i--) { - if (*m_working != i && !m_verticesLOD[i].isNull()) { - m_screenVertices = m_verticesLOD[i].data(); - break; - } else if (i == 1) { - // get 1 synchronously if not computed already - m_verticesLOD[1] = QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>>( - new QList<QDeclarativeGeoMapItemUtils::vec2>); - *m_verticesLOD[1] = getSimplified(*m_verticesLOD[0], leftBound, zoomForLOD(0)); - if (requestedLod == 1) - return; - } - } - - enqueueSimplificationTask(m_verticesLOD.at(0), - m_verticesLOD[requestedLod], - leftBound, - zoom, - m_working); - - } -} - -void QGeoMapItemLODGeometry::selectLODOnDataChanged(unsigned int zoom, double leftBound) const -{ - unsigned int lod = zoomToLOD(zoom); - if (lod > 0) { - // Generate ZL 1 as fallback for all cases != 0. Do not do if 0 is requested - // (= old behavior, LOD disabled) - m_verticesLOD[1] = QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>>( - new QList<QDeclarativeGeoMapItemUtils::vec2>); - *m_verticesLOD[1] = getSimplified( *m_verticesLOD[0], leftBound, zoomForLOD(0)); - } - if (lod > 1) { - if (!m_verticesLOD[lod]) { - m_verticesLOD[lod] = QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>>( - new QList<QDeclarativeGeoMapItemUtils::vec2>); - } - enqueueSimplificationTask(m_verticesLOD.at(0), - m_verticesLOD[lod], - leftBound, - zoom, - m_working); - } - m_screenVertices = m_verticesLOD[qMin<unsigned int>(lod, 1)].data(); // return only 0,1 synchronously -} - -unsigned int QGeoMapItemLODGeometry::zoomToLOD(unsigned int zoom) -{ - unsigned int res; - if (zoom > 20) - res = 0; - else - res = qBound<unsigned int>(3, zoom, 20) / 3; // bound LOD'ing between ZL 3 and 20. Every 3 ZoomLevels - return res; -} - -unsigned int QGeoMapItemLODGeometry::zoomForLOD(unsigned int zoom) -{ - unsigned int res = (qBound<unsigned int>(3, zoom, 20) / 3) * 3; - if (zoom < 6) - return res; - return res + 1; // give more resolution when closing in -} - -// wrapPath always preserves the geometry -// This one handles holes -static void wrapPath(const QGeoPolygon &poly - ,const QGeoCoordinate &geoLeftBound - ,const QGeoProjectionWebMercator &p - ,QList<QList<QDoubleVector2D> > &wrappedPaths - ,QDoubleVector2D *leftBoundWrapped = nullptr) -{ - QList<QList<QDoubleVector2D> > paths; - for (qsizetype i = 0; i < 1 + poly.holesCount(); ++i) { - QList<QDoubleVector2D> path; - if (!i) { - for (const QGeoCoordinate &c : poly.perimeter()) - path << p.geoToMapProjection(c); - } else { - for (const QGeoCoordinate &c : poly.holePath(i-1)) - path << p.geoToMapProjection(c); - } - paths.append(path); - } - - const QDoubleVector2D leftBound = p.geoToMapProjection(geoLeftBound); - wrappedPaths.clear(); - - QList<QDoubleVector2D> wrappedPath; - // compute 3 sets of "wrapped" coordinates: one w regular mercator, one w regular mercator +- 1.0 - for (const auto &path : paths) { - wrappedPath.clear(); - for (QDoubleVector2D coord : path) { - // We can get NaN if the map isn't set up correctly, or the projection - // is faulty -- probably best thing to do is abort - if (!qIsFinite(coord.x()) || !qIsFinite(coord.y())) { - wrappedPaths.clear(); - return; - } - - const bool isPointLessThanUnwrapBelowX = (coord.x() < leftBound.x()); - // unwrap x to preserve geometry if moved to border of map - if (isPointLessThanUnwrapBelowX) - coord.setX(coord.x() + 1.0); - wrappedPath.append(coord); - } - wrappedPaths.append(wrappedPath); - } - - if (leftBoundWrapped) - *leftBoundWrapped = leftBound; -} - -static void cutPathEars(const QList<QList<QDoubleVector2D>> &wrappedPaths, - QList<QDeclarativeGeoMapItemUtils::vec2> &screenVertices, - QList<quint32> &screenIndices) -{ - using Coord = double; - using N = uint32_t; - using Point = std::array<Coord, 2>; - screenVertices.clear(); - screenIndices.clear(); - - std::vector<std::vector<Point>> polygon; - std::vector<Point> poly; - - for (const QList<QDoubleVector2D> &wrappedPath: wrappedPaths) { - poly.clear(); - for (const QDoubleVector2D &v: wrappedPath) { - screenVertices << v; - Point pt = {{ v.x(), v.y() }}; - poly.push_back( pt ); - } - polygon.push_back(poly); - } - - std::vector<N> indices = qt_mapbox::earcut<N>(polygon); - - for (const auto &i: indices) - screenIndices << quint32(i); -} - -static void cutPathEars(const QList<QDoubleVector2D> &wrappedPath, - QList<QDeclarativeGeoMapItemUtils::vec2> &screenVertices, - QList<quint32> &screenIndices) -{ - using Coord = double; - using N = uint32_t; - using Point = std::array<Coord, 2>; - screenVertices.clear(); - screenIndices.clear(); - - std::vector<std::vector<Point>> polygon; - std::vector<Point> poly; - - for (const QDoubleVector2D &v: wrappedPath) { - screenVertices << v; - Point pt = {{ v.x(), v.y() }}; - poly.push_back( pt ); - } - polygon.push_back(poly); - - std::vector<N> indices = qt_mapbox::earcut<N>(polygon); - - for (const auto &i: indices) - screenIndices << quint32(i); -} - -void QGeoMapPolygonGeometryOpenGL::allocateAndFillPolygon(QSGGeometry *geom) const -{ - - const QList<QDeclarativeGeoMapItemUtils::vec2> &vx = m_screenVertices; - const QList<quint32> &ix = m_screenIndices; - - geom->allocate(vx.size(), ix.size()); - if (geom->indexType() == QSGGeometry::UnsignedShortType) { - quint16 *its = geom->indexDataAsUShort(); - for (qsizetype i = 0; i < ix.size(); ++i) - its[i] = ix[i]; - } else if (geom->indexType() == QSGGeometry::UnsignedIntType) { - quint32 *its = geom->indexDataAsUInt(); - for (qsizetype i = 0; i < ix.size(); ++i) - its[i] = ix[i]; - } - - QSGGeometry::Point2D *pts = geom->vertexDataAsPoint2D(); - for (qsizetype i = 0; i < vx.size(); ++i) - pts[i].set(vx[i].x, vx[i].y); -} - - -QGeoMapPolygonGeometryOpenGL::QGeoMapPolygonGeometryOpenGL() -{ -} - -void QGeoMapPolygonGeometryOpenGL::updateSourcePoints(const QGeoMap &map, const QList<QDoubleVector2D> &path) -{ - QList<QGeoCoordinate> geopath; - for (const auto &c: path) - geopath.append(QWebMercator::mercatorToCoord(c)); - updateSourcePoints(map, geopath); -} - -/*! - \internal -*/ -// This one does only a perimeter -void QGeoMapPolygonGeometryOpenGL::updateSourcePoints(const QGeoMap &map, - const QList<QGeoCoordinate> &perimeter) -{ - if (!sourceDirty_) - return; - const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection()); - - // build the actual path - // The approach is the same as described in QGeoMapPolylineGeometry::updateSourcePoints - srcOrigin_ = geoLeftBound_; - - QDoubleVector2D leftBoundWrapped; - // 1) pre-compute 3 sets of "wrapped" coordinates: one w regular mercator, one w regular mercator +- 1.0 - QList<QDoubleVector2D> wrappedPath; - QDeclarativeGeoMapItemUtils::wrapPath(perimeter, geoLeftBound_, p, - wrappedPath, &leftBoundWrapped); - - // 1.1) do the same for the bbox - QList<QDoubleVector2D> wrappedBbox, wrappedBboxPlus1, wrappedBboxMinus1; - QGeoPolygon bbox(QGeoPath(perimeter).boundingGeoRectangle()); - QDeclarativeGeoMapItemUtils::wrapPath(bbox.perimeter(), bbox.boundingGeoRectangle().topLeft(), p, - wrappedBbox, wrappedBboxMinus1, wrappedBboxPlus1, &m_bboxLeftBoundWrapped); - - // 2) Store the triangulated polygon, and the wrapped bbox paths. - // the triangulations can be used as they are, as they "bypass" the QtQuick display chain - // the bbox wraps have to be however clipped, and then projected, in order to figure out the geometry. - // Note that this might still cause the geometryChange method to fail under some extreme conditions. - cutPathEars(wrappedPath, m_screenVertices, m_screenIndices); - - m_wrappedPolygons.resize(3); - m_wrappedPolygons[0].wrappedBboxes = wrappedBboxMinus1; - m_wrappedPolygons[1].wrappedBboxes = wrappedBbox; - m_wrappedPolygons[2].wrappedBboxes = wrappedBboxPlus1; -} - -// This one handles whole QGeoPolygon w. holes -void QGeoMapPolygonGeometryOpenGL::updateSourcePoints(const QGeoMap &map, const QGeoPolygon &poly) -{ - if (!sourceDirty_) - return; - const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection()); - - // build the actual path - // The approach is the same as described in QGeoMapPolylineGeometry::updateSourcePoints - srcOrigin_ = geoLeftBound_; - - QDoubleVector2D leftBoundWrapped; - QList<QList<QDoubleVector2D>> wrappedPath; - // 1) pre-compute 3 sets of "wrapped" coordinates: one w regular mercator, one w regular mercator +- 1.0 - wrapPath(poly, geoLeftBound_, p, - wrappedPath, &leftBoundWrapped); - - // 1.1) do the same for the bbox - QList<QDoubleVector2D> wrappedBbox, wrappedBboxPlus1, wrappedBboxMinus1; - QGeoPolygon bbox(poly.boundingGeoRectangle()); - QDeclarativeGeoMapItemUtils::wrapPath(bbox.perimeter(), bbox.boundingGeoRectangle().topLeft(), p, - wrappedBbox, wrappedBboxMinus1, wrappedBboxPlus1, &m_bboxLeftBoundWrapped); - - // 2) Store the triangulated polygon, and the wrapped bbox paths. - // the triangulations can be used as they are, as they "bypass" the QtQuick display chain - // the bbox wraps have to be however clipped, and then projected, in order to figure out the geometry. - // Note that this might still cause the geometryChange method to fail under some extreme conditions. - cutPathEars(wrappedPath, m_screenVertices, m_screenIndices); - m_wrappedPolygons.resize(3); - m_wrappedPolygons[0].wrappedBboxes = wrappedBboxMinus1; - m_wrappedPolygons[1].wrappedBboxes = wrappedBbox; - m_wrappedPolygons[2].wrappedBboxes = wrappedBboxPlus1; -} - -void QGeoMapPolygonGeometryOpenGL::updateSourcePoints(const QGeoMap &map, const QGeoRectangle &rect) -{ - if (!sourceDirty_) - return; - const QList<QGeoCoordinate> perimeter = QGeoMapItemGeometry::path(rect); - updateSourcePoints(map, perimeter); -} - -/*! - \internal -*/ -void QGeoMapPolygonGeometryOpenGL::updateScreenPoints(const QGeoMap &map, qreal strokeWidth , const QColor &strokeColor) -{ - if (map.viewportWidth() == 0 || map.viewportHeight() == 0) { - clear(); - return; - } - - // 1) identify which set to use: std, +1 or -1 - const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection()); - const QDoubleVector2D leftBoundMercator = p.geoToMapProjection(srcOrigin_); - m_wrapOffset = p.projectionWrapFactor(leftBoundMercator) + 1; // +1 to get the offset into QLists - - // 1.1) select geometry set - // This could theoretically be skipped for those polygons whose bbox is not even projectable. - // However, such optimization could only be introduced if not calculating bboxes lazily. - // Hence not doing it. - if (sourceDirty_) { - m_dataChanged = true; - } - - if (strokeWidth == 0.0 || strokeColor.alpha() == 0) // or else the geometry of the border is used, so no point in calculating 2 of them - updateQuickGeometry(p, strokeWidth); -} - -void QGeoMapPolygonGeometryOpenGL::updateQuickGeometry(const QGeoProjectionWebMercator &p, qreal /*strokeWidth*/) -{ - // 2) clip bbox - // BBox handling -- this is related to the bounding box geometry - // that has to inevitably follow the old projection codepath - // As it needs to provide projected coordinates for QtQuick interaction. - // This could be futher optimized to be updated in a lazy fashion. - const QList<QDoubleVector2D> &wrappedBbox = m_wrappedPolygons.at(m_wrapOffset).wrappedBboxes; - QList<QList<QDoubleVector2D> > clippedBbox; - QDoubleVector2D bboxLeftBoundWrapped = m_bboxLeftBoundWrapped; - bboxLeftBoundWrapped.setX(bboxLeftBoundWrapped.x() + double(m_wrapOffset - 1)); - QDeclarativeGeoMapItemUtils::clipPolygon(wrappedBbox, p, clippedBbox, &bboxLeftBoundWrapped); - - // 3) project bbox - QPainterPath ppi; - if (!clippedBbox.size() || clippedBbox.first().size() < 3) { - sourceBounds_ = screenBounds_ = QRectF(); - firstPointOffset_ = QPointF(); - screenOutline_ = ppi; - return; - } - - QDeclarativeGeoMapItemUtils::projectBbox(clippedBbox.first(), p, ppi); // Using first because a clipped box should always result in one polygon - const QRectF brect = ppi.boundingRect(); - firstPointOffset_ = QPointF(brect.topLeft()); - screenOutline_ = ppi; - - // 4) Set Screen bbox - screenBounds_ = brect; - sourceBounds_.setX(0); - sourceBounds_.setY(0); - sourceBounds_.setWidth(brect.width()); - sourceBounds_.setHeight(brect.height()); -} - - -void QGeoMapPolylineGeometryOpenGL::updateSourcePoints(const QGeoMap &map, const QGeoPolygon &poly) -{ - if (!sourceDirty_) - return; - QGeoPath p(poly.perimeter()); - if (poly.perimeter().size() && poly.perimeter().last() != poly.perimeter().first()) - p.addCoordinate(poly.perimeter().first()); - updateSourcePoints(map, p); -} - -void QGeoMapPolylineGeometryOpenGL::updateSourcePoints(const QGeoMap &map, const QGeoPath &poly) -{ - if (!sourceDirty_) - return; - const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection()); - - // build the actual path - // The approach is the same as described in QGeoMapPolylineGeometry::updateSourcePoints - - - QDoubleVector2D leftBoundWrapped; - // 1) pre-compute 3 sets of "wrapped" coordinates: one w regular mercator, one w regular mercator +- 1.0 - QList<QDoubleVector2D> wrappedPath; - QDeclarativeGeoMapItemUtils::wrapPath(poly.path(), geoLeftBound_, p, - wrappedPath, &leftBoundWrapped); - - const QGeoRectangle &boundingRectangle = poly.boundingGeoRectangle(); - updateSourcePoints(p, wrappedPath, boundingRectangle); -} - -void QGeoMapPolylineGeometryOpenGL::updateSourcePoints(const QGeoProjectionWebMercator &p, - const QList<QDoubleVector2D> &wrappedPath, - const QGeoRectangle &boundingRectangle) { - if (!sourceDirty_) - return; - // 1.1) do the same for the bbox - // Beware: vertical lines (or horizontal lines) might have an "empty" bbox. Check for that - - QGeoCoordinate topLeft = boundingRectangle.topLeft(); - QGeoCoordinate bottomRight = boundingRectangle.bottomRight(); - const qreal epsilon = 0.000001; - if (qFuzzyCompare(topLeft.latitude(), bottomRight.latitude())) { - topLeft.setLatitude(qBound(-90.0, topLeft.latitude() + epsilon ,90.0)); - bottomRight.setLatitude(qBound(-90.0, bottomRight.latitude() - epsilon ,90.0)); - } - if (qFuzzyCompare(topLeft.longitude(), bottomRight.longitude())) { - topLeft.setLongitude(QLocationUtils::wrapLong(topLeft.longitude() - epsilon)); - bottomRight.setLongitude(QLocationUtils::wrapLong(bottomRight.longitude() + epsilon)); - } - QGeoPolygon bbox(QGeoRectangle(topLeft, bottomRight)); - QList<QDoubleVector2D> wrappedBbox, wrappedBboxPlus1, wrappedBboxMinus1; - QDeclarativeGeoMapItemUtils::wrapPath(bbox.perimeter(), bbox.boundingGeoRectangle().topLeft(), p, - wrappedBbox, wrappedBboxMinus1, wrappedBboxPlus1, &m_bboxLeftBoundWrapped); - - // New pointers, some old LOD task might still be running and operating on the old pointers. - resetLOD(); - - for (const auto &v: qAsConst(wrappedPath)) m_screenVertices->append(v); - - m_wrappedPolygons.resize(3); - m_wrappedPolygons[0].wrappedBboxes = wrappedBboxMinus1; - m_wrappedPolygons[1].wrappedBboxes = wrappedBbox; - m_wrappedPolygons[2].wrappedBboxes = wrappedBboxPlus1; - srcOrigin_ = geoLeftBound_; -} - -void QGeoMapPolylineGeometryOpenGL::updateSourcePoints(const QGeoMap &map, const QGeoRectangle &rect) -{ - const QList<QGeoCoordinate> perimeter = QGeoMapItemGeometry::perimeter(rect); - updateSourcePoints(map, QGeoPath(perimeter)); -} - -void QGeoMapPolylineGeometryOpenGL::updateSourcePoints(const QGeoMap &map, const QGeoCircle &circle) -{ - if (!sourceDirty_) - return; - const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection()); - - QDoubleVector2D leftBoundWrapped; - // 1) pre-compute 3 sets of "wrapped" coordinates: one w regular mercator, one w regular mercator +- 1.0 - QList<QGeoCoordinate> path; - QGeoCoordinate leftBound; - QList<QDoubleVector2D> wrappedPath; - QDeclarativeCircleMapItemPrivate::calculatePeripheralPoints(path, circle.center(), circle.radius(), QDeclarativeCircleMapItemPrivate::CircleSamples, leftBound); - path << path.first(); - geoLeftBound_ = leftBound; - QDeclarativeGeoMapItemUtils::wrapPath(path, leftBound, p, wrappedPath, &leftBoundWrapped); - const QGeoRectangle &boundingRectangle = circle.boundingGeoRectangle(); - updateSourcePoints(p, wrappedPath, boundingRectangle); -} - -void QGeoMapPolylineGeometryOpenGL::updateScreenPoints(const QGeoMap &map, qreal strokeWidth, bool /*adjustTranslation*/) -{ - if (map.viewportWidth() == 0 || map.viewportHeight() == 0) { - clear(); - return; - } - - // 1) identify which set to use: std, +1 or -1 - const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection()); - const QDoubleVector2D leftBoundMercator = p.geoToMapProjection(srcOrigin_); - m_wrapOffset = p.projectionWrapFactor(leftBoundMercator) + 1; // +1 to get the offset into QLists - - if (sourceDirty_) { - // 1.1) select geometry set - // This could theoretically be skipped for those polylines whose bbox is not even projectable. - // However, such optimization could only be introduced if not calculating bboxes lazily. - // Hence not doing it. -// if (m_screenVertices.size() > 1) - m_dataChanged = true; - } - - updateQuickGeometry(p, strokeWidth); -} - -void QGeoMapPolylineGeometryOpenGL::updateQuickGeometry(const QGeoProjectionWebMercator &p, qreal strokeWidth) -{ - // 2) clip bbox - // BBox handling -- this is related to the bounding box geometry - // that has to inevitably follow the old projection codepath - // As it needs to provide projected coordinates for QtQuick interaction. - // This could be futher optimized to be updated in a lazy fashion. - const QList<QDoubleVector2D> &wrappedBbox = m_wrappedPolygons.at(m_wrapOffset).wrappedBboxes; - QList<QList<QDoubleVector2D> > clippedBbox; - QDoubleVector2D bboxLeftBoundWrapped = m_bboxLeftBoundWrapped; - bboxLeftBoundWrapped.setX(bboxLeftBoundWrapped.x() + double(m_wrapOffset - 1)); - QDeclarativeGeoMapItemUtils::clipPolygon(wrappedBbox, p, clippedBbox, &bboxLeftBoundWrapped, false); - - // 3) project bbox - QPainterPath ppi; - - if ( !clippedBbox.size() || - clippedBbox.first().size() < 3) { - sourceBounds_ = screenBounds_ = QRectF(); - firstPointOffset_ = QPointF(); - screenOutline_ = ppi; - return; - } - - QDeclarativeGeoMapItemUtils::projectBbox(clippedBbox.first(), p, ppi); // Using first because a clipped box should always result in one polygon - const QRectF brect = ppi.boundingRect(); - firstPointOffset_ = QPointF(brect.topLeft()); - sourceBounds_ = brect; - screenOutline_ = ppi; - - // 4) Set Screen bbox - screenBounds_ = brect; - sourceBounds_.setX(0); - sourceBounds_.setY(0); - sourceBounds_.setWidth(brect.width() + strokeWidth); - sourceBounds_.setHeight(brect.height() + strokeWidth); -} - -// Note: this is also slightly incorrect on joins and in the beginning/end of the line -bool QGeoMapPolylineGeometryOpenGL::contains(const QPointF &point, qreal lineWidth, const QGeoProjectionWebMercator &p) const -{ - const double lineHalfWidth = lineWidth * 0.5; - const QDoubleVector2D pt(point); - QDoubleVector2D a; - if (m_screenVertices->size()) - a = p.wrappedMapProjectionToItemPosition(p.wrapMapProjection(m_screenVertices->first().toDoubleVector2D())); - QDoubleVector2D b; - for (qsizetype i = 1; i < m_screenVertices->size(); ++i) { - const auto &screenVertice = m_screenVertices->at(i); - if (!a.isFinite()) { - a = p.wrappedMapProjectionToItemPosition(p.wrapMapProjection(screenVertice.toDoubleVector2D())); - continue; - } - - b = p.wrappedMapProjectionToItemPosition(p.wrapMapProjection(screenVertice.toDoubleVector2D())); - if (!b.isFinite()) { - a = b; - continue; - } - - if (b == a) - continue; - - // Heavily simplifying it here: if a point is not projectable, skip the segment. - // For a correct solution, the segment should be clipped instead. - if (distanceTo(a, b, pt) <= lineHalfWidth) - return true; - - a = b; - } - return false; -} - -QT_END_NAMESPACE diff --git a/src/location/quickmapitems/rhi/qgeomapitemgeometry_rhi_p.h b/src/location/quickmapitems/rhi/qgeomapitemgeometry_rhi_p.h deleted file mode 100644 index a6ae5af4..00000000 --- a/src/location/quickmapitems/rhi/qgeomapitemgeometry_rhi_p.h +++ /dev/null @@ -1,219 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGEOMAPITEMGEOMETRY_RHI_P_H -#define QGEOMAPITEMGEOMETRY_RHI_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/QList> -#include <QtCore/QSharedPointer> -#include <QtGui/QColor> -#include <QtPositioning/private/qdoublevector2d_p.h> -#include <QtLocation/private/qdeclarativegeomapitemutils_p.h> -#include <QtLocation/private/qgeomapitemgeometry_p.h> - -QT_BEGIN_NAMESPACE - -class QPointF; -class QSGGeometry; -class QGeoCircle; -class QGeoMap; -class QGeoPath; -class QGeoPolygon; -class QGeoProjectionWebMercator; -class QGeoRectangle; - -class QGeoMapItemLODGeometry -{ - Q_DISABLE_COPY(QGeoMapItemLODGeometry); -public: - mutable std::array<QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>>, 7> - m_verticesLOD; // fix it to 7, - // do not allow simplifications beyond ZL 20. This could actually be - // limited even further - mutable QList<QDeclarativeGeoMapItemUtils::vec2> *m_screenVertices; - mutable QSharedPointer<unsigned int> m_working; - - QGeoMapItemLODGeometry(); - - void resetLOD(); - - static unsigned int zoomToLOD(unsigned int zoom); - - static unsigned int zoomForLOD(unsigned int zoom); - - bool isLODActive(unsigned int lod) const; - - void selectLOD(unsigned int zoom, double leftBound, bool /*closed*/); - - static QList<QDeclarativeGeoMapItemUtils::vec2> - getSimplified(QList<QDeclarativeGeoMapItemUtils::vec2> &wrappedPath, double leftBoundWrapped, - unsigned int zoom); - - static void enqueueSimplificationTask( - const QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>> - &input, // reference as it gets copied in the nested call - const QSharedPointer<QList<QDeclarativeGeoMapItemUtils::vec2>> &output, - double leftBound, unsigned int zoom, QSharedPointer<unsigned int> &working); - - void selectLODOnDataChanged(unsigned int zoom, double leftBound) const; - bool selectLODOnLODMismatch(unsigned int zoom, double leftBound, bool closed) const; -}; - -class Q_LOCATION_PRIVATE_EXPORT QGeoMapPolylineGeometryOpenGL : public QGeoMapItemGeometry, - public QGeoMapItemLODGeometry -{ -public: - typedef struct { - QList<QDoubleVector2D> wrappedBboxes; - } WrappedPolyline; - - QGeoMapPolylineGeometryOpenGL() - { - m_working = QSharedPointer<unsigned int>(new unsigned int(0)); - } - - void updateSourcePoints(const QGeoMap &map, - const QGeoPolygon &poly); - - void updateSourcePoints(const QGeoMap &map, - const QGeoPath &poly); - - void updateSourcePoints(const QGeoProjectionWebMercator &p, - const QList<QDoubleVector2D> &wrappedPath, - const QGeoRectangle &boundingRectangle); - - void updateSourcePoints(const QGeoMap &map, - const QGeoRectangle &rect); - - void updateSourcePoints(const QGeoMap &map, - const QGeoCircle &circle); - - void updateScreenPoints(const QGeoMap &map, - qreal strokeWidth, - bool adjustTranslation = true); - - void updateQuickGeometry(const QGeoProjectionWebMercator &p, qreal strokeWidth = 0.0); - - bool allocateAndFillEntries(QSGGeometry *geom, - bool closed = false, - unsigned int zoom = 0) const; - - bool contains(const QPointF &point) const override - { - Q_UNUSED(point); - return false; - } - - static double distanceTo(const QDoubleVector2D &a, const QDoubleVector2D &b, const QDoubleVector2D &p) - { - double u = ((p.x() - a.x()) * (b.x() - a.x()) + (p.y() - a.y()) * (b.y() - a.y())) - / (b - a).lengthSquared(); - QDoubleVector2D intersection(a.x() + u * (b.x() - a.x()) , a.y() + u * (b.y() - a.y())); - - QDoubleVector2D candidate = ( (p-a).length() < (p-b).length() ) ? a : b; - - // And it falls in the segment - if (u > 0 && u < 1 && (p-intersection).length() < (p-candidate).length()) { - candidate = intersection; - } - - return qAbs((candidate - p).length()); - } - // Note: this is also slightly incorrect on joins and in the beginning/end of the line - bool contains(const QPointF &point, qreal lineWidth, const QGeoProjectionWebMercator &p) const; - -public: - QDoubleVector2D m_bboxLeftBoundWrapped; - QList<WrappedPolyline> m_wrappedPolygons; - int m_wrapOffset; - - friend class QDeclarativeCircleMapItem; - friend class QDeclarativePolygonMapItem; - friend class QDeclarativeRectangleMapItem; -}; - -class Q_LOCATION_PRIVATE_EXPORT QGeoMapPolygonGeometryOpenGL : public QGeoMapItemGeometry -{ -public: - typedef struct { - QList<QDoubleVector2D> wrappedBboxes; - } WrappedPolygon; - QGeoMapPolygonGeometryOpenGL(); - ~QGeoMapPolygonGeometryOpenGL() override {} - - // Temporary method for compatibility in MapCircleObject. Remove when MapObjects are ported. - void updateSourcePoints(const QGeoMap &map, - const QList<QDoubleVector2D> &path); - - void updateSourcePoints(const QGeoMap &map, - const QList<QGeoCoordinate> &perimeter); - - void updateSourcePoints(const QGeoMap &map, - const QGeoPolygon &poly); - - void updateSourcePoints(const QGeoMap &map, - const QGeoRectangle &rect); - - void updateScreenPoints(const QGeoMap &map, qreal strokeWidth = 0.0, - const QColor &strokeColor = Qt::transparent); - void updateQuickGeometry(const QGeoProjectionWebMercator &p, qreal strokeWidth = 0.0); - - void allocateAndFillPolygon(QSGGeometry *geom) const; - - QList<QDeclarativeGeoMapItemUtils::vec2> m_screenVertices; - QList<quint32> m_screenIndices; - QDoubleVector2D m_bboxLeftBoundWrapped; - QList<WrappedPolygon> m_wrappedPolygons; - int m_wrapOffset = 0; -}; - -QT_END_NAMESPACE - -#endif // QGEOMAPITEMGEOMETRY_RHI_P_H diff --git a/src/location/quickmapitems/rhi/qgeosimplify.cpp b/src/location/quickmapitems/rhi/qgeosimplify.cpp deleted file mode 100644 index ad5a3c5d..00000000 --- a/src/location/quickmapitems/rhi/qgeosimplify.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Qt adaptation of geosimplify-js -** Copyright (C) 2017 Daniel Patterson -** See 3rdParty/geosimplify.js for the original license. -** -** Copyright (C) 2020 Paolo Angelelli <paolo.angelelli@gmail.com> -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgeosimplify_p.h" -#include <QtPositioning/private/qlocationutils_p.h> -#include <QtPositioning/private/qdoublevector2d_p.h> -#include <QtPositioning/private/qwebmercator_p.h> - -QT_BEGIN_NAMESPACE - -namespace { - -// p, a and b are intended as "unwrapped" around the left bound -inline QDoubleVector2D closestPoint(const QDoubleVector2D &p, - const QDoubleVector2D &a, - const QDoubleVector2D &b) -{ - if (a == b) - return a; - - const double u = ((p.x() - a.x()) * (b.x() - a.x()) + (p.y() - a.y()) * (b.y() - a.y())) - / (b - a).lengthSquared(); - const QDoubleVector2D intersection(a.x() + u * (b.x() - a.x()) , a.y() + u * (b.y() - a.y())); - QDoubleVector2D candidate = ((p - a).length() < (p - b).length()) ? a : b; - if (u > 0 && u < 1 - && (p - intersection).length() < (p - candidate).length()) { // And it falls in the segment - candidate = intersection; - } - return candidate; -} - -inline double getDist(QDoubleVector2D a, QDoubleVector2D b, double leftBound) -{ - if (a.x() > 1.0) - a.setX(a.x() - leftBound); // wrap X - if (b.x() > 1.0) - b.setX(b.x() - leftBound); // wrap X - return QWebMercator::mercatorToCoord(a).distanceTo(QWebMercator::mercatorToCoord(b)); -} - -// doublevectors Intended as wrapped -inline double getSegDist(const QDoubleVector2D &p, - const QDoubleVector2D &a, - const QDoubleVector2D &b, - double leftBound) -{ - const QDoubleVector2D intersection = closestPoint(p, a, b); - return getDist(intersection, p, leftBound); -} - -inline QGeoCoordinate unwrappedToGeo(QDoubleVector2D p, double leftBound) -{ - if (p.x() > 1.0) - p.setX(p.x() - leftBound); - return QWebMercator::mercatorToCoord(p); -} - -double pixelDistanceAtZoomAndLatitude(int zoom, double latitude) -{ - const double den = double((1 << (zoom + 8))); - const double pixelDist = (QLocationUtils::earthMeanCircumference() - * std::cos(QLocationUtils::radians(latitude))) - / den; - return pixelDist; -} - -// simplification using Ramer-Douglas-Peucker algorithm -void simplifyDouglasPeuckerStepZL(const QList<QDoubleVector2D> &points, double leftBound, - qsizetype first, qsizetype last, int zoomLevel, - QList<QDoubleVector2D> &simplified) -{ - const QGeoCoordinate firstC = unwrappedToGeo(points.at(first), leftBound); - const QGeoCoordinate lastC = unwrappedToGeo(points.at(last), leftBound); - double maxDistanceFound = (pixelDistanceAtZoomAndLatitude(zoomLevel, firstC.latitude()) - + pixelDistanceAtZoomAndLatitude(zoomLevel, lastC.latitude())) * 0.5; - qsizetype index = -1; - - const auto &firstPoint = points.at(first); - const auto &lastPoint = points.at(last); - for (qsizetype i = first + 1; i < last; i++) { - const double distance = getSegDist(points.at(i), - firstPoint, - lastPoint, - leftBound); - - if (distance > maxDistanceFound) { - index = i; - maxDistanceFound = distance; - } - } - - if (index > 0) { - if (index - first > 1) { - simplifyDouglasPeuckerStepZL(points, leftBound, - first, index, zoomLevel, - simplified); - } - simplified.append(points.at(index)); - if (last - index > 1) { - simplifyDouglasPeuckerStepZL(points, leftBound, - index, last, zoomLevel, - simplified); - } - } -} - -} // anonymous namespace - -namespace QGeoSimplify { - -QList<QDoubleVector2D> geoSimplifyZL(const QList<QDoubleVector2D> &points, - double leftBound, int zoomLevel) -{ - if (points.size() <= 2) - return points; - - const qsizetype last = points.size() - 1; - QList<QDoubleVector2D> simplified { points.first() }; - simplifyDouglasPeuckerStepZL(points, leftBound, 0, last, zoomLevel, simplified); - simplified.append(points.at(last)); - return simplified; -} - -} - -QT_END_NAMESPACE diff --git a/src/location/quickmapitems/rhi/qgeosimplify_p.h b/src/location/quickmapitems/rhi/qgeosimplify_p.h deleted file mode 100644 index 1f5c9783..00000000 --- a/src/location/quickmapitems/rhi/qgeosimplify_p.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Qt adaptation of geosimplify.js, https://github.com/mapbox/geosimplify-js, (c) 2017, Mapbox -** -** Copyright (C) 2020 Paolo Angelelli <paolo.angelelli@gmail.com> -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGEOSIMPLIFY_P_H -#define QGEOSIMPLIFY_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/QList> - -QT_BEGIN_NAMESPACE - -class QDoubleVector2D; - -namespace QGeoSimplify -{ - // offsetTolerance - how far outside the straight line a point - // needs to be for it to be "kept" - // This function tries to be adaptive in the offsetTolerance across latitudes, - // and return a simplification adequate for the given zoomLevel. - QList<QDoubleVector2D> geoSimplifyZL(const QList<QDoubleVector2D> &points, - double leftBound, int zoomLevel); // in meters -} - -QT_END_NAMESPACE - -#endif // QGEOSIMPLIFY_P_H diff --git a/src/location/quickmapitems/rhi/shaders/polygon.frag b/src/location/quickmapitems/rhi/shaders/polygon.frag deleted file mode 100644 index 9b9727b6..00000000 --- a/src/location/quickmapitems/rhi/shaders/polygon.frag +++ /dev/null @@ -1,16 +0,0 @@ -#version 440 - -layout(location = 0) out vec4 fragColor; - -layout(std140, binding = 0) uniform buf { - mat4 qt_Matrix; - mat4 mapProjection; - vec4 center; - vec4 center_lowpart; - float wrapOffset; - vec4 color; -}; - -void main() { - fragColor = color; -} diff --git a/src/location/quickmapitems/rhi/shaders/polygon.vert b/src/location/quickmapitems/rhi/shaders/polygon.vert deleted file mode 100644 index 06dab03e..00000000 --- a/src/location/quickmapitems/rhi/shaders/polygon.vert +++ /dev/null @@ -1,20 +0,0 @@ -#version 440 - -layout(location = 0) in highp vec4 vertex; - -layout(std140, binding = 0) uniform buf { - mat4 qt_Matrix; - mat4 mapProjection; - vec4 center; - vec4 center_lowpart; - float wrapOffset; - vec4 color; -}; - -vec4 wrapped(in vec4 v) { return vec4(v.x + wrapOffset, v.y, 0.0, 1.0); } - -void main() { - vec4 vtx = wrapped(vertex) - center; - vtx = vtx - center_lowpart; - gl_Position = qt_Matrix * mapProjection * vtx; -} diff --git a/src/location/quickmapitems/rhi/shaders/polyline.frag b/src/location/quickmapitems/rhi/shaders/polyline.frag deleted file mode 100644 index 3530f093..00000000 --- a/src/location/quickmapitems/rhi/shaders/polyline.frag +++ /dev/null @@ -1,20 +0,0 @@ -#version 440 - -layout(location = 0) in vec4 primitivecolor; -layout(location = 0) out vec4 fragColor; - -layout(std140, binding = 0) uniform buf { - mat4 qt_Matrix; - mat4 mapProjection; - vec4 center; - vec4 center_lowpart; - float lineWidth; - float aspect; - int miter; // currently unused - vec4 color; - float wrapOffset; -}; - -void main() { - fragColor = primitivecolor; -} diff --git a/src/location/quickmapitems/rhi/shaders/polyline.vert b/src/location/quickmapitems/rhi/shaders/polyline.vert deleted file mode 100644 index 27b69b60..00000000 --- a/src/location/quickmapitems/rhi/shaders/polyline.vert +++ /dev/null @@ -1,104 +0,0 @@ -#version 440 - -layout(location = 0) in vec4 vertex; -layout(location = 1) in vec4 previous; -layout(location = 2) in vec4 next; -layout(location = 3) in float direction; -layout(location = 4) in float triangletype; -layout(location = 5) in float vertextype; // -1.0 if it is the "left" end of the segment, 1.0 if it is the "right" end. -layout(location = 0) out vec4 primitivecolor; - -layout(std140, binding = 0) uniform buf { - mat4 qt_Matrix; - mat4 mapProjection; - vec4 center; - vec4 center_lowpart; - float lineWidth; - float aspect; - int miter; // currently unused - vec4 color; - float wrapOffset; -}; - - -vec4 wrapped(in vec4 v) { return vec4(v.x + wrapOffset, v.y, 0.0, 1.0); } -void main() { // ln 22 - primitivecolor = color; - vec2 aspectVec = vec2(aspect, 1.0); - mat4 projViewModel = qt_Matrix * mapProjection; - vec4 cur = wrapped(vertex) - center; - cur = cur - center_lowpart; - vec4 prev = wrapped(previous) - center; - prev = prev - center_lowpart; - vec4 nex = wrapped(next) - center; - nex = nex - center_lowpart; - - vec4 centerProjected = projViewModel * (center + vec4(0.0, 0.0, 0.0, 1.0)); - vec4 previousProjected = projViewModel * prev; - vec4 currentProjected = projViewModel * cur; - vec4 nextProjected = projViewModel * nex; - - //get 2D screen space with W divide and aspect correction - vec2 currentScreen = (currentProjected.xy / currentProjected.w) * aspectVec; - vec2 previousScreen = (previousProjected.xy / previousProjected.w) * aspectVec; - vec2 nextScreen = (nextProjected.xy / nextProjected.w) * aspectVec; - float len = (lineWidth); - float orientation = direction; - bool clipped = false; - bool otherEndBelowFrustum = false; - //starting point uses (next - current) - vec2 dir = vec2(0.0); - if (vertextype < 0.0) { - dir = normalize(nextScreen - currentScreen); - if (nextProjected.z < 0.0) dir = -dir; - } else { - dir = normalize(currentScreen - previousScreen); - if (previousProjected.z < 0.0) dir = -dir; - } -// first, clip current, and make sure currentProjected.z is > 0 - if (currentProjected.z < 0.0) { - if ((nextProjected.z > 0.0 && vertextype < 0.0) || (vertextype > 0.0 && previousProjected.z > 0.0)) { - dir = -dir; - clipped = true; - if (vertextype < 0.0 && nextProjected.y / nextProjected.w < -1.0) otherEndBelowFrustum = true; - else if (vertextype > 0.0 && previousProjected.y / previousProjected.w < -1.0) otherEndBelowFrustum = true; - } else { - primitivecolor = vec4(0.0,0.0,0.0,0.0); - gl_Position = vec4(-10000000.0, -1000000000.0, -1000000000.0, 1); // get the vertex out of the way if the segment is fully invisible - return; - } - } else if (triangletype < 2.0) { // vertex in the view, try to miter - //get directions from (C - B) and (B - A) - vec2 dirA = normalize((currentScreen - previousScreen)); - if (previousProjected.z < 0.0) dirA = -dirA; - vec2 dirB = normalize((nextScreen - currentScreen)); - //now compute the miter join normal and length - if (nextProjected.z < 0.0) dirB = -dirB; - vec2 tangent = normalize(dirA + dirB); - vec2 perp = vec2(-dirA.y, dirA.x); - vec2 vmiter = vec2(-tangent.y, tangent.x); - len = lineWidth / dot(vmiter, perp); -// The following is an attempt to have a segment-length based miter threshold. -// A mediocre workaround until better mitering will be added. - float lenTreshold = clamp( min(length((currentProjected.xy - previousProjected.xy) / aspectVec), - length((nextProjected.xy - currentProjected.xy) / aspectVec)), 3.0, 6.0 ) * 0.5; - if (len < lineWidth * lenTreshold && len > -lineWidth * lenTreshold) { - dir = tangent; - } else { - len = lineWidth; - } - } - vec4 offset; - if (!clipped) { - vec2 normal = normalize(vec2(-dir.y, dir.x)); - normal *= len; // fracZL apparently was needed before the (-2.0 / qt_Matrix[1][1]) factor was introduced - normal /= aspectVec; // straighten the normal up again - float scaleFactor = currentProjected.w / centerProjected.w; - offset = vec4(normal * orientation * scaleFactor * (centerProjected.w / (-2.0 / qt_Matrix[1][1])), 0.0, 0.0); // ToDo: figure out why (-2.0 / qt_Matrix[1][1]), that is empirically what works - gl_Position = currentProjected + offset; - } else { - if (otherEndBelowFrustum) offset = vec4((dir * 1.0) / aspectVec, 0.0, 0.0); // the if is necessary otherwise it seems the direction vector still flips in some obscure cases. - else offset = vec4((dir * 500000000000.0) / aspectVec, 0.0, 0.0); // Hack alert: just 1 triangle, long enough to look like a rectangle. - if (vertextype < 0.0) gl_Position = nextProjected - offset; else gl_Position = previousProjected + offset; - } -} |