1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Copyright (C) 2017 Mapbox, Inc.
5** Contact: http://www.qt.io/licensing/
6**
7** This file is part of the QtLocation module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL3$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see http://www.qt.io/terms-conditions. For further
16** information use the contact form at http://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPLv3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or later as published by the Free
29** Software Foundation and appearing in the file LICENSE.GPL included in
30** the packaging of this file. Please review the following information to
31** ensure the GNU General Public License version 2.0 requirements will be
32** met: http://www.gnu.org/licenses/gpl-2.0.html.
33**
34** $QT_END_LICENSE$
35**
36****************************************************************************/
37
38#include "qsgmapboxglnode.h"
39#include "qgeomapmapboxgl.h"
40
41#if QT_HAS_INCLUDE(<QtQuick/private/qsgplaintexture_p.h>)
42#include <QtQuick/private/qsgplaintexture_p.h>
43#endif
44
45#include <QtGui/QOpenGLContext>
46#include <QtGui/QOpenGLFunctions>
47
48// QSGMapboxGLTextureNode
49
50static const QSize minTextureSize = QSize(64, 64);
51
52QSGMapboxGLTextureNode::QSGMapboxGLTextureNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap)
53 : QSGSimpleTextureNode()
54{
55 setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
56 setFiltering(QSGTexture::Linear);
57
58 m_map.reset(other: new QMapboxGL(nullptr, settings, size.expandedTo(otherSize: minTextureSize), pixelRatio));
59
60 QObject::connect(sender: m_map.data(), signal: &QMapboxGL::needsRendering, receiver: geoMap, slot: &QGeoMap::sgNodeChanged);
61 QObject::connect(sender: m_map.data(), signal: &QMapboxGL::copyrightsChanged, receiver: geoMap,
62 slot: static_cast<void (QGeoMap::*)(const QString &)>(&QGeoMapMapboxGL::copyrightsChanged));
63}
64
65void QSGMapboxGLTextureNode::resize(const QSize &size, qreal pixelRatio)
66{
67 const QSize& minSize = size.expandedTo(otherSize: minTextureSize);
68 const QSize fbSize = minSize * pixelRatio;
69 m_map->resize(size: minSize);
70
71 m_fbo.reset(other: new QOpenGLFramebufferObject(fbSize, QOpenGLFramebufferObject::CombinedDepthStencil));
72 m_map->setFramebufferObject(fbo: m_fbo->handle(), size: fbSize);
73
74 QSGPlainTexture *fboTexture = static_cast<QSGPlainTexture *>(texture());
75 if (!fboTexture) {
76 fboTexture = new QSGPlainTexture;
77 fboTexture->setHasAlphaChannel(true);
78 }
79
80 fboTexture->setTextureId(m_fbo->texture());
81 fboTexture->setTextureSize(fbSize);
82
83 if (!texture()) {
84 setTexture(fboTexture);
85 setOwnsTexture(true);
86 }
87
88 setRect(QRectF(QPointF(), minSize));
89 markDirty(bits: QSGNode::DirtyGeometry);
90}
91
92void QSGMapboxGLTextureNode::render(QQuickWindow *window)
93{
94 QOpenGLFunctions *f = window->openglContext()->functions();
95 f->glViewport(x: 0, y: 0, width: m_fbo->width(), height: m_fbo->height());
96
97 GLint alignment;
98 f->glGetIntegerv(GL_UNPACK_ALIGNMENT, params: &alignment);
99
100 m_fbo->bind();
101
102 f->glClearColor(red: 0.f, green: 0.f, blue: 0.f, alpha: 0.f);
103 f->glColorMask(red: true, green: true, blue: true, alpha: true);
104 f->glClear(GL_COLOR_BUFFER_BIT);
105
106 m_map->render();
107 m_fbo->release();
108
109 // QTBUG-62861
110 f->glPixelStorei(GL_UNPACK_ALIGNMENT, param: alignment);
111
112 window->resetOpenGLState();
113 markDirty(bits: QSGNode::DirtyMaterial);
114}
115
116QMapboxGL* QSGMapboxGLTextureNode::map() const
117{
118 return m_map.data();
119}
120
121// QSGMapboxGLRenderNode
122
123QSGMapboxGLRenderNode::QSGMapboxGLRenderNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap)
124 : QSGRenderNode()
125{
126 m_map.reset(other: new QMapboxGL(nullptr, settings, size, pixelRatio));
127 QObject::connect(sender: m_map.data(), signal: &QMapboxGL::needsRendering, receiver: geoMap, slot: &QGeoMap::sgNodeChanged);
128 QObject::connect(sender: m_map.data(), signal: &QMapboxGL::copyrightsChanged, receiver: geoMap,
129 slot: static_cast<void (QGeoMap::*)(const QString &)>(&QGeoMapMapboxGL::copyrightsChanged));
130}
131
132QMapboxGL* QSGMapboxGLRenderNode::map() const
133{
134 return m_map.data();
135}
136
137void QSGMapboxGLRenderNode::render(const RenderState *state)
138{
139 // QMapboxGL assumes we've prepared the viewport prior to render().
140 QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
141 f->glViewport(x: state->scissorRect().x(), y: state->scissorRect().y(), width: state->scissorRect().width(), height: state->scissorRect().height());
142 f->glScissor(x: state->scissorRect().x(), y: state->scissorRect().y(), width: state->scissorRect().width(), height: state->scissorRect().height());
143 f->glEnable(GL_SCISSOR_TEST);
144
145 GLint alignment;
146 f->glGetIntegerv(GL_UNPACK_ALIGNMENT, params: &alignment);
147
148 m_map->render();
149
150 // QTBUG-62861
151 f->glPixelStorei(GL_UNPACK_ALIGNMENT, param: alignment);
152}
153
154QSGRenderNode::StateFlags QSGMapboxGLRenderNode::changedStates() const
155{
156 return QSGRenderNode::DepthState
157 | QSGRenderNode::StencilState
158 | QSGRenderNode::ScissorState
159 | QSGRenderNode::ColorState
160 | QSGRenderNode::BlendState
161 | QSGRenderNode::ViewportState
162 | QSGRenderNode::RenderTargetState;
163}
164
165

source code of qtlocation/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp