| 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 | |