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