1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Data Visualization module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 or (at your option) any later version |
20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by |
21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include "seriesrendercache_p.h" |
31 | #include "abstract3drenderer_p.h" |
32 | #include "texturehelper_p.h" |
33 | #include "utils_p.h" |
34 | |
35 | QT_BEGIN_NAMESPACE_DATAVISUALIZATION |
36 | |
37 | const QString smoothString(QStringLiteral("Smooth" )); |
38 | |
39 | SeriesRenderCache::SeriesRenderCache(QAbstract3DSeries *series, Abstract3DRenderer *renderer) |
40 | : m_series(series), |
41 | m_object(0), |
42 | m_mesh(QAbstract3DSeries::MeshCube), |
43 | m_baseUniformTexture(0), |
44 | m_baseGradientTexture(0), |
45 | m_gradientImage(0), |
46 | m_singleHighlightGradientTexture(0), |
47 | m_multiHighlightGradientTexture(0), |
48 | m_valid(false), |
49 | m_visible(false), |
50 | m_renderer(renderer), |
51 | m_objectDirty(true), |
52 | m_staticObjectUVDirty(false) |
53 | { |
54 | } |
55 | |
56 | SeriesRenderCache::~SeriesRenderCache() |
57 | { |
58 | } |
59 | |
60 | void SeriesRenderCache::populate(bool newSeries) |
61 | { |
62 | QAbstract3DSeriesChangeBitField &changeTracker = m_series->d_ptr->m_changeTracker; |
63 | |
64 | if (newSeries || changeTracker.meshChanged || changeTracker.meshSmoothChanged |
65 | || changeTracker.userDefinedMeshChanged) { |
66 | m_mesh = m_series->mesh(); |
67 | changeTracker.meshChanged = false; |
68 | changeTracker.meshSmoothChanged = false; |
69 | changeTracker.userDefinedMeshChanged = false; |
70 | |
71 | QString meshFileName; |
72 | |
73 | // Compose mesh filename |
74 | if (m_mesh == QAbstract3DSeries::MeshUserDefined) { |
75 | // Always use the supplied mesh directly |
76 | meshFileName = m_series->userDefinedMesh(); |
77 | } else { |
78 | switch (m_mesh) { |
79 | case QAbstract3DSeries::MeshBar: |
80 | case QAbstract3DSeries::MeshCube: |
81 | meshFileName = QStringLiteral(":/defaultMeshes/bar" ); |
82 | break; |
83 | case QAbstract3DSeries::MeshPyramid: |
84 | meshFileName = QStringLiteral(":/defaultMeshes/pyramid" ); |
85 | break; |
86 | case QAbstract3DSeries::MeshCone: |
87 | meshFileName = QStringLiteral(":/defaultMeshes/cone" ); |
88 | break; |
89 | case QAbstract3DSeries::MeshCylinder: |
90 | meshFileName = QStringLiteral(":/defaultMeshes/cylinder" ); |
91 | break; |
92 | case QAbstract3DSeries::MeshBevelBar: |
93 | case QAbstract3DSeries::MeshBevelCube: |
94 | meshFileName = QStringLiteral(":/defaultMeshes/bevelbar" ); |
95 | break; |
96 | case QAbstract3DSeries::MeshSphere: |
97 | meshFileName = QStringLiteral(":/defaultMeshes/sphere" ); |
98 | break; |
99 | case QAbstract3DSeries::MeshMinimal: |
100 | meshFileName = QStringLiteral(":/defaultMeshes/minimal" ); |
101 | break; |
102 | case QAbstract3DSeries::MeshArrow: |
103 | meshFileName = QStringLiteral(":/defaultMeshes/arrow" ); |
104 | break; |
105 | case QAbstract3DSeries::MeshPoint: |
106 | if (Utils::isOpenGLES()) |
107 | qWarning(msg: "QAbstract3DSeries::MeshPoint is not fully supported on OpenGL ES2" ); |
108 | break; |
109 | default: |
110 | // Default to cube |
111 | meshFileName = QStringLiteral(":/defaultMeshes/bar" ); |
112 | break; |
113 | } |
114 | |
115 | if (m_series->isMeshSmooth() && m_mesh != QAbstract3DSeries::MeshPoint) |
116 | meshFileName += smoothString; |
117 | |
118 | // Give renderer an opportunity to customize the mesh |
119 | m_renderer->fixMeshFileName(fileName&: meshFileName, mesh: m_mesh); |
120 | } |
121 | |
122 | ObjectHelper::resetObjectHelper(cacheId: m_renderer, obj&: m_object, meshFile: meshFileName); |
123 | } |
124 | |
125 | if (newSeries || changeTracker.meshRotationChanged) { |
126 | m_meshRotation = m_series->meshRotation().normalized(); |
127 | if (m_series->type() == QAbstract3DSeries::SeriesTypeBar |
128 | && (m_meshRotation.x() || m_meshRotation.z())) { |
129 | m_meshRotation = identityQuaternion; |
130 | } |
131 | changeTracker.meshRotationChanged = false; |
132 | } |
133 | |
134 | if (newSeries || changeTracker.colorStyleChanged) { |
135 | m_colorStyle = m_series->colorStyle(); |
136 | changeTracker.colorStyleChanged = false; |
137 | } |
138 | |
139 | if (newSeries || changeTracker.baseColorChanged) { |
140 | m_baseColor = Utils::vectorFromColor(color: m_series->baseColor()); |
141 | if (m_series->type() == QAbstract3DSeries::SeriesTypeSurface) |
142 | m_renderer->generateBaseColorTexture(color: m_series->baseColor(), texture: &m_baseUniformTexture); |
143 | changeTracker.baseColorChanged = false; |
144 | } |
145 | |
146 | if (newSeries || changeTracker.baseGradientChanged) { |
147 | QLinearGradient gradient = m_series->baseGradient(); |
148 | m_gradientImage = Utils::getGradientImage(gradient); |
149 | m_renderer->fixGradientAndGenerateTexture(gradient: &gradient, gradientTexture: &m_baseGradientTexture); |
150 | changeTracker.baseGradientChanged = false; |
151 | } |
152 | |
153 | if (newSeries || changeTracker.singleHighlightColorChanged) { |
154 | m_singleHighlightColor = Utils::vectorFromColor(color: m_series->singleHighlightColor()); |
155 | changeTracker.singleHighlightColorChanged = false; |
156 | } |
157 | |
158 | if (newSeries || changeTracker.singleHighlightGradientChanged) { |
159 | QLinearGradient gradient = m_series->singleHighlightGradient(); |
160 | m_renderer->fixGradientAndGenerateTexture(gradient: &gradient, gradientTexture: &m_singleHighlightGradientTexture); |
161 | changeTracker.singleHighlightGradientChanged = false; |
162 | } |
163 | |
164 | if (newSeries || changeTracker.multiHighlightColorChanged) { |
165 | m_multiHighlightColor = Utils::vectorFromColor(color: m_series->multiHighlightColor()); |
166 | changeTracker.multiHighlightColorChanged = false; |
167 | } |
168 | |
169 | if (newSeries || changeTracker.multiHighlightGradientChanged) { |
170 | QLinearGradient gradient = m_series->multiHighlightGradient(); |
171 | m_renderer->fixGradientAndGenerateTexture(gradient: &gradient, gradientTexture: &m_multiHighlightGradientTexture); |
172 | changeTracker.multiHighlightGradientChanged = false; |
173 | } |
174 | |
175 | if (newSeries || changeTracker.nameChanged) { |
176 | m_name = m_series->name(); |
177 | changeTracker.nameChanged = false; |
178 | } |
179 | |
180 | if (newSeries || changeTracker.itemLabelChanged |
181 | || changeTracker.itemLabelVisibilityChanged) { |
182 | changeTracker.itemLabelChanged = false; |
183 | changeTracker.itemLabelVisibilityChanged = false; |
184 | // series->itemLabel() call resolves the item label and emits the changed signal |
185 | // if it is dirty, so we need to call it even if m_itemLabel is eventually set |
186 | // to an empty string. |
187 | m_itemLabel = m_series->itemLabel(); |
188 | if (!m_series->isItemLabelVisible()) |
189 | m_itemLabel = QString(); |
190 | } |
191 | |
192 | if (newSeries || changeTracker.visibilityChanged) { |
193 | m_visible = m_series->isVisible(); |
194 | changeTracker.visibilityChanged = false; |
195 | } |
196 | } |
197 | |
198 | void SeriesRenderCache::cleanup(TextureHelper *texHelper) |
199 | { |
200 | ObjectHelper::releaseObjectHelper(cacheId: m_renderer, obj&: m_object); |
201 | if (QOpenGLContext::currentContext()) { |
202 | texHelper->deleteTexture(texture: &m_baseUniformTexture); |
203 | texHelper->deleteTexture(texture: &m_baseGradientTexture); |
204 | texHelper->deleteTexture(texture: &m_singleHighlightGradientTexture); |
205 | texHelper->deleteTexture(texture: &m_multiHighlightGradientTexture); |
206 | } |
207 | } |
208 | |
209 | QT_END_NAMESPACE_DATAVISUALIZATION |
210 | |