| 1 | // Copyright (C) 2016 The Qt Company Ltd. |
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
| 3 | |
| 4 | // |
| 5 | // W A R N I N G |
| 6 | // ------------- |
| 7 | // |
| 8 | // This file is not part of the QtDataVisualization API. It exists purely as an |
| 9 | // implementation detail. This header file may change from version to |
| 10 | // version without notice, or even be removed. |
| 11 | // |
| 12 | // We mean it. |
| 13 | |
| 14 | #ifndef ABSTRACT3DRENDERER_P_H |
| 15 | #define ABSTRACT3DRENDERER_P_H |
| 16 | |
| 17 | #include <QtGui/QOpenGLFunctions> |
| 18 | #if !QT_CONFIG(opengles2) |
| 19 | # include <QtOpenGL/QOpenGLFunctions_2_1> |
| 20 | #endif |
| 21 | #include "datavisualizationglobal_p.h" |
| 22 | #include "abstract3dcontroller_p.h" |
| 23 | #include "axisrendercache_p.h" |
| 24 | #include "seriesrendercache_p.h" |
| 25 | #include "customrenderitem_p.h" |
| 26 | |
| 27 | #include <QtGui/qquaternion.h> |
| 28 | |
| 29 | #include <QtCore/qpointer.h> |
| 30 | |
| 31 | QT_FORWARD_DECLARE_CLASS(QOffscreenSurface) |
| 32 | |
| 33 | QT_BEGIN_NAMESPACE |
| 34 | |
| 35 | class TextureHelper; |
| 36 | class Theme; |
| 37 | class Drawer; |
| 38 | |
| 39 | class Abstract3DRenderer : public QObject, protected QOpenGLFunctions |
| 40 | { |
| 41 | Q_OBJECT |
| 42 | |
| 43 | protected: |
| 44 | enum SelectionState { |
| 45 | SelectNone = 0, |
| 46 | SelectOnScene, |
| 47 | SelectOnOverview, |
| 48 | SelectOnSlice |
| 49 | }; |
| 50 | |
| 51 | enum RenderingState { |
| 52 | RenderingNormal = 0, |
| 53 | RenderingSelection, |
| 54 | RenderingDepth |
| 55 | }; |
| 56 | |
| 57 | public: |
| 58 | virtual ~Abstract3DRenderer(); |
| 59 | |
| 60 | virtual void updateData() = 0; |
| 61 | virtual void updateSeries(const QList<QAbstract3DSeries *> &seriesList); |
| 62 | virtual void updateCustomData(const QList<QCustom3DItem *> &customItems); |
| 63 | virtual void updateCustomItems(); |
| 64 | virtual void updateCustomItemPositions(); |
| 65 | virtual SeriesRenderCache *createNewCache(QAbstract3DSeries *series); |
| 66 | virtual void cleanCache(SeriesRenderCache *cache); |
| 67 | virtual void render(GLuint defaultFboHandle); |
| 68 | |
| 69 | virtual void updateTheme(Q3DTheme *theme); |
| 70 | virtual void updateSelectionMode(QAbstract3DGraph::SelectionFlags newMode); |
| 71 | virtual void updateOptimizationHint(QAbstract3DGraph::OptimizationHints hint); |
| 72 | virtual void updateScene(Q3DScene *scene); |
| 73 | virtual void updateTextures(); |
| 74 | virtual void initSelectionBuffer() = 0; |
| 75 | virtual void updateSelectionState(SelectionState state); |
| 76 | |
| 77 | virtual void updateDepthBuffer() = 0; |
| 78 | virtual void updateShadowQuality(QAbstract3DGraph::ShadowQuality quality) = 0; |
| 79 | virtual void initShaders(const QString &vertexShader, const QString &fragmentShader) = 0; |
| 80 | virtual void initGradientShaders(const QString &vertexShader, const QString &fragmentShader); |
| 81 | virtual void initStaticSelectedItemShaders(const QString &vertexShader, |
| 82 | const QString &fragmentShader, |
| 83 | const QString &gradientVertexShader, |
| 84 | const QString &gradientFragmentShader); |
| 85 | virtual void initBackgroundShaders(const QString &vertexShader, |
| 86 | const QString &fragmentShader) = 0; |
| 87 | virtual void initCustomItemShaders(const QString &vertexShader, |
| 88 | const QString &fragmentShader); |
| 89 | virtual void initVolumeTextureShaders(const QString &vertexShader, |
| 90 | const QString &fragmentShader, |
| 91 | const QString &fragmentLowDefShader, |
| 92 | const QString &sliceShader, |
| 93 | const QString &sliceFrameVertexShader, |
| 94 | const QString &sliceFrameShader); |
| 95 | virtual void initLabelShaders(const QString &vertexShader, const QString &fragmentShader); |
| 96 | virtual void initCursorPositionShaders(const QString &vertexShader, |
| 97 | const QString &fragmentShader); |
| 98 | virtual void initCursorPositionBuffer(); |
| 99 | |
| 100 | virtual void updateAxisType(QAbstract3DAxis::AxisOrientation orientation, |
| 101 | QAbstract3DAxis::AxisType type); |
| 102 | virtual void updateAxisTitle(QAbstract3DAxis::AxisOrientation orientation, |
| 103 | const QString &title); |
| 104 | virtual void updateAxisLabels(QAbstract3DAxis::AxisOrientation orientation, |
| 105 | const QStringList &labels); |
| 106 | virtual void updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, |
| 107 | float max); |
| 108 | virtual void updateAxisSegmentCount(QAbstract3DAxis::AxisOrientation orientation, int count); |
| 109 | virtual void updateAxisSubSegmentCount(QAbstract3DAxis::AxisOrientation orientation, |
| 110 | int count); |
| 111 | virtual void updateAxisLabelFormat(QAbstract3DAxis::AxisOrientation orientation, |
| 112 | const QString &format); |
| 113 | virtual void updateAxisReversed(QAbstract3DAxis::AxisOrientation orientation, |
| 114 | bool enable); |
| 115 | virtual void updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation, |
| 116 | QValue3DAxisFormatter *formatter); |
| 117 | virtual void updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrientation orientation, |
| 118 | float angle); |
| 119 | virtual void updateAxisTitleVisibility(QAbstract3DAxis::AxisOrientation orientation, |
| 120 | bool visible); |
| 121 | virtual void updateAxisTitleFixed(QAbstract3DAxis::AxisOrientation orientation, |
| 122 | bool fixed); |
| 123 | virtual void modifiedSeriesList(const QList<QAbstract3DSeries *> &seriesList); |
| 124 | |
| 125 | virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); |
| 126 | |
| 127 | virtual CustomRenderItem *addCustomItem(QCustom3DItem *item); |
| 128 | virtual void updateCustomItem(CustomRenderItem *renderItem); |
| 129 | |
| 130 | virtual void updateAspectRatio(float ratio); |
| 131 | virtual void updateHorizontalAspectRatio(float ratio); |
| 132 | virtual void updatePolar(bool enable); |
| 133 | virtual void updateRadialLabelOffset(float offset); |
| 134 | virtual void updateMargin(float margin); |
| 135 | |
| 136 | virtual QVector3D convertPositionToTranslation(const QVector3D &position, |
| 137 | bool isAbsolute) = 0; |
| 138 | |
| 139 | void generateBaseColorTexture(const QColor &color, GLuint *texture); |
| 140 | void fixGradientAndGenerateTexture(QLinearGradient *gradient, GLuint *gradientTexture); |
| 141 | |
| 142 | inline bool isClickQueryResolved() const { return m_clickResolved; } |
| 143 | inline void clearClickQueryResolved() { m_clickResolved = false; } |
| 144 | inline QPoint cachedClickQuery() const { return m_cachedScene->selectionQueryPosition(); } |
| 145 | inline QAbstract3DSeries *clickedSeries() const { return m_clickedSeries; } |
| 146 | inline QAbstract3DGraph::ElementType clickedType() { return m_clickedType; } |
| 147 | inline bool isGraphPositionQueryResolved() const { return m_graphPositionQueryResolved; } |
| 148 | inline void clearGraphPositionQueryResolved() { m_graphPositionQueryResolved = false; } |
| 149 | inline QVector3D queriedGraphPosition() const { return m_queriedGraphPosition; } |
| 150 | inline QPoint cachedGraphPositionQuery() const { return m_cachedScene->graphPositionQuery(); } |
| 151 | |
| 152 | LabelItem &selectionLabelItem(); |
| 153 | void setSelectionLabel(const QString &label); |
| 154 | QString &selectionLabel(); |
| 155 | |
| 156 | void drawCustomItems(RenderingState state, ShaderHelper *regularShader, |
| 157 | const QMatrix4x4 &viewMatrix, |
| 158 | const QMatrix4x4 &projectionViewMatrix, |
| 159 | const QMatrix4x4 &depthProjectionViewMatrix, |
| 160 | GLuint depthTexture, GLfloat shadowQuality, GLfloat reflection = 1.0f); |
| 161 | |
| 162 | QVector4D indexToSelectionColor(GLint index); |
| 163 | void calculatePolarXZ(const QVector3D &dataPos, float &x, float &z) const; |
| 164 | |
| 165 | Q_SIGNALS: |
| 166 | void needRender(); // Emit this if something in renderer causes need for another render pass. |
| 167 | void requestShadowQuality(QAbstract3DGraph::ShadowQuality quality); // For automatic quality adjustments |
| 168 | |
| 169 | protected: |
| 170 | Abstract3DRenderer(Abstract3DController *controller); |
| 171 | |
| 172 | virtual void contextCleanup(); |
| 173 | virtual void initializeOpenGL(); |
| 174 | |
| 175 | void reInitShaders(); |
| 176 | virtual void handleShadowQualityChange(); |
| 177 | virtual void handleResize(); |
| 178 | |
| 179 | AxisRenderCache &axisCacheForOrientation(QAbstract3DAxis::AxisOrientation orientation); |
| 180 | |
| 181 | virtual void lowerShadowQuality(); |
| 182 | |
| 183 | void fixGradient(QLinearGradient *gradient, GLuint *gradientTexture); |
| 184 | |
| 185 | void calculateZoomLevel(); |
| 186 | void drawAxisTitleY(const QVector3D &sideLabelRotation, const QVector3D &backLabelRotation, |
| 187 | const QVector3D &sideLabelTrans, const QVector3D &backLabelTrans, |
| 188 | const QQuaternion &totalSideRotation, const QQuaternion &totalBackRotation, |
| 189 | AbstractRenderItem &dummyItem, const Q3DCamera *activeCamera, |
| 190 | float labelsMaxWidth, |
| 191 | const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix, |
| 192 | ShaderHelper *shader); |
| 193 | void drawAxisTitleX(const QVector3D &labelRotation, const QVector3D &labelTrans, |
| 194 | const QQuaternion &totalRotation, AbstractRenderItem &dummyItem, |
| 195 | const Q3DCamera *activeCamera, float labelsMaxWidth, |
| 196 | const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix, |
| 197 | ShaderHelper *shader, bool radial = false); |
| 198 | void drawAxisTitleZ(const QVector3D &labelRotation, const QVector3D &labelTrans, |
| 199 | const QQuaternion &totalRotation, AbstractRenderItem &dummyItem, |
| 200 | const Q3DCamera *activeCamera, float labelsMaxWidth, |
| 201 | const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix, |
| 202 | ShaderHelper *shader); |
| 203 | |
| 204 | void loadGridLineMesh(); |
| 205 | void loadLabelMesh(); |
| 206 | void loadPositionMapperMesh(); |
| 207 | |
| 208 | void drawRadialGrid(ShaderHelper *shader, float yFloorLinePos, |
| 209 | const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &depthMatrix); |
| 210 | void drawAngularGrid(ShaderHelper *shader, float yFloorLinePos, |
| 211 | const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &depthMatrix); |
| 212 | |
| 213 | float calculatePolarBackgroundMargin(); |
| 214 | virtual void fixCameraTarget(QVector3D &target) = 0; |
| 215 | void updateCameraViewport(); |
| 216 | |
| 217 | void recalculateCustomItemScalingAndPos(CustomRenderItem *item); |
| 218 | virtual void getVisibleItemBounds(QVector3D &minBounds, QVector3D &maxBounds) = 0; |
| 219 | void drawVolumeSliceFrame(const CustomRenderItem *item, Qt::Axis axis, |
| 220 | const QMatrix4x4 &projectionViewMatrix); |
| 221 | void queriedGraphPosition(const QMatrix4x4 &projectionViewMatrix, const QVector3D &scaling, |
| 222 | GLuint defaultFboHandle); |
| 223 | |
| 224 | bool m_hasNegativeValues; |
| 225 | Q3DTheme *m_cachedTheme; |
| 226 | Drawer *m_drawer; |
| 227 | QRect m_viewport; |
| 228 | QAbstract3DGraph::ShadowQuality m_cachedShadowQuality; |
| 229 | GLfloat m_autoScaleAdjustment; |
| 230 | |
| 231 | QAbstract3DGraph::SelectionFlags m_cachedSelectionMode; |
| 232 | QAbstract3DGraph::OptimizationHints m_cachedOptimizationHint; |
| 233 | |
| 234 | AxisRenderCache m_axisCacheX; |
| 235 | AxisRenderCache m_axisCacheY; |
| 236 | AxisRenderCache m_axisCacheZ; |
| 237 | TextureHelper *m_textureHelper; |
| 238 | GLuint m_depthTexture; |
| 239 | |
| 240 | Q3DScene *m_cachedScene; |
| 241 | bool m_selectionDirty; |
| 242 | SelectionState m_selectionState; |
| 243 | QPoint m_inputPosition; |
| 244 | QHash<QAbstract3DSeries *, SeriesRenderCache *> m_renderCacheList; |
| 245 | CustomRenderItemArray m_customRenderCache; |
| 246 | QList<QCustom3DItem *> m_customItemDrawOrder; |
| 247 | QRect m_primarySubViewport; |
| 248 | QRect m_secondarySubViewport; |
| 249 | float m_devicePixelRatio; |
| 250 | bool m_selectionLabelDirty; |
| 251 | bool m_clickResolved; |
| 252 | bool m_graphPositionQueryPending; |
| 253 | bool m_graphPositionQueryResolved; |
| 254 | QAbstract3DSeries *m_clickedSeries; |
| 255 | QAbstract3DGraph::ElementType m_clickedType; |
| 256 | int m_selectedLabelIndex; |
| 257 | int m_selectedCustomItemIndex; |
| 258 | QVector3D m_queriedGraphPosition; |
| 259 | QPoint m_graphPositionQuery; |
| 260 | |
| 261 | QString m_selectionLabel; |
| 262 | LabelItem *m_selectionLabelItem; |
| 263 | int m_visibleSeriesCount; |
| 264 | |
| 265 | ShaderHelper *m_customItemShader; |
| 266 | ShaderHelper *m_volumeTextureShader; |
| 267 | ShaderHelper *m_volumeTextureLowDefShader; |
| 268 | ShaderHelper *m_volumeTextureSliceShader; |
| 269 | ShaderHelper *m_volumeSliceFrameShader; |
| 270 | ShaderHelper *m_labelShader; |
| 271 | ShaderHelper *m_cursorPositionShader; |
| 272 | GLuint m_cursorPositionFrameBuffer; |
| 273 | GLuint m_cursorPositionTexture; |
| 274 | |
| 275 | bool m_useOrthoProjection; |
| 276 | bool m_xFlipped; |
| 277 | bool m_yFlipped; |
| 278 | bool m_zFlipped; |
| 279 | bool m_yFlippedForGrid; |
| 280 | |
| 281 | ObjectHelper *m_backgroundObj; // Shared reference |
| 282 | ObjectHelper *m_gridLineObj; // Shared reference |
| 283 | ObjectHelper *m_labelObj; // Shared reference |
| 284 | ObjectHelper *m_positionMapperObj; // Shared reference |
| 285 | |
| 286 | float m_graphAspectRatio; |
| 287 | float m_graphHorizontalAspectRatio; |
| 288 | bool m_polarGraph; |
| 289 | float m_radialLabelOffset; |
| 290 | float m_polarRadius; |
| 291 | |
| 292 | QQuaternion m_xRightAngleRotation; |
| 293 | QQuaternion m_yRightAngleRotation; |
| 294 | QQuaternion m_zRightAngleRotation; |
| 295 | QQuaternion m_xRightAngleRotationNeg; |
| 296 | QQuaternion m_yRightAngleRotationNeg; |
| 297 | QQuaternion m_zRightAngleRotationNeg; |
| 298 | QQuaternion m_xFlipRotation; |
| 299 | QQuaternion m_zFlipRotation; |
| 300 | |
| 301 | float m_requestedMargin; |
| 302 | float m_vBackgroundMargin; |
| 303 | float m_hBackgroundMargin; |
| 304 | float m_scaleXWithBackground; |
| 305 | float m_scaleYWithBackground; |
| 306 | float m_scaleZWithBackground; |
| 307 | |
| 308 | QVector3D m_oldCameraTarget; |
| 309 | |
| 310 | bool m_reflectionEnabled; |
| 311 | qreal m_reflectivity; |
| 312 | |
| 313 | QLocale m_locale; |
| 314 | #if !QT_CONFIG(opengles2) |
| 315 | QOpenGLFunctions_2_1 *m_funcs_2_1; |
| 316 | #endif |
| 317 | QPointer<QOpenGLContext> m_context; // Not owned |
| 318 | bool m_isOpenGLES; |
| 319 | |
| 320 | private: |
| 321 | friend class Abstract3DController; |
| 322 | }; |
| 323 | |
| 324 | QT_END_NAMESPACE |
| 325 | |
| 326 | #endif |
| 327 | |