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