From 8ff45fe94c3f3f6916f8f673c3ce0b574a69cfdf Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 6 May 2014 09:52:24 +0300 Subject: Value axis reversing support Task-number: QTRD-2428 Change-Id: I51b3a1f8f974d5b72b36ee1188b7557539b9609b Reviewed-by: Titta Heikkala Reviewed-by: Mika Salmela --- src/datavisualization/axis/qvalue3daxis.cpp | 33 ++++- src/datavisualization/axis/qvalue3daxis.h | 5 + src/datavisualization/axis/qvalue3daxis_p.h | 1 + .../engine/abstract3dcontroller.cpp | 54 +++++++++ .../engine/abstract3dcontroller_p.h | 8 ++ .../engine/abstract3drenderer.cpp | 8 ++ .../engine/abstract3drenderer_p.h | 2 + src/datavisualization/engine/axisrendercache.cpp | 20 ++- src/datavisualization/engine/axisrendercache_p.h | 8 +- src/datavisualization/engine/bars3dcontroller.cpp | 14 +++ src/datavisualization/engine/bars3drenderer.cpp | 135 ++++++++++++--------- src/datavisualization/engine/bars3drenderer_p.h | 4 +- src/datavisualization/engine/q3dscene.h | 1 + src/datavisualization/engine/surface3drenderer.cpp | 6 + 14 files changed, 231 insertions(+), 68 deletions(-) (limited to 'src/datavisualization') diff --git a/src/datavisualization/axis/qvalue3daxis.cpp b/src/datavisualization/axis/qvalue3daxis.cpp index 79d374ea..1c7b647a 100644 --- a/src/datavisualization/axis/qvalue3daxis.cpp +++ b/src/datavisualization/axis/qvalue3daxis.cpp @@ -82,6 +82,15 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * */ +/*! + * \qmlproperty bool ValueAxis3D::reversed + * \since QtDataVisualization 1.1 + * + * If \c{true}, the axis will be rendered in reverse, i.e. the positions of minimum and maximum + * values are swapped when the graph is rendered. This property doesn't affect the actual + * minimum and maximum values of the axis. + */ + /*! * Constructs QValue3DAxis with the given \a parent. */ @@ -203,6 +212,27 @@ QValue3DAxisFormatter *QValue3DAxis::formatter() const return dptrc()->m_formatter; } +/*! + * \property QValue3DAxis::reversed + * \since Qt Data Visualization 1.1 + * + * If \c{true}, the axis will be rendered in reverse, i.e. the positions of minimum and maximum + * values are swapped when the graph is rendered. This property doesn't affect the actual + * minimum and maximum values of the axis. + */ +void QValue3DAxis::setReversed(bool enable) +{ + if (dptr()->m_reversed != enable) { + dptr()->m_reversed = enable; + emit reversedChanged(enable); + } +} + +bool QValue3DAxis::reversed() const +{ + return dptrc()->m_reversed; +} + /*! * \internal */ @@ -225,7 +255,8 @@ QValue3DAxisPrivate::QValue3DAxisPrivate(QValue3DAxis *q) m_subSegmentCount(1), m_labelFormat(Utils::defaultLabelFormat()), m_labelsDirty(true), - m_formatter(0) + m_formatter(0), + m_reversed(false) { } diff --git a/src/datavisualization/axis/qvalue3daxis.h b/src/datavisualization/axis/qvalue3daxis.h index 39a4a886..f552269c 100644 --- a/src/datavisualization/axis/qvalue3daxis.h +++ b/src/datavisualization/axis/qvalue3daxis.h @@ -33,6 +33,7 @@ class QT_DATAVISUALIZATION_EXPORT QValue3DAxis : public QAbstract3DAxis Q_PROPERTY(int subSegmentCount READ subSegmentCount WRITE setSubSegmentCount NOTIFY subSegmentCountChanged) Q_PROPERTY(QString labelFormat READ labelFormat WRITE setLabelFormat NOTIFY labelFormatChanged) Q_PROPERTY(QValue3DAxisFormatter* formatter READ formatter WRITE setFormatter NOTIFY formatterChanged REVISION 1) + Q_PROPERTY(bool reversed READ reversed WRITE setReversed NOTIFY reversedChanged REVISION 1) public: explicit QValue3DAxis(QObject *parent = 0); @@ -50,11 +51,15 @@ public: void setFormatter(QValue3DAxisFormatter *formatter); QValue3DAxisFormatter *formatter() const; + void setReversed(bool enable); + bool reversed() const; + signals: void segmentCountChanged(int count); void subSegmentCountChanged(int count); void labelFormatChanged(const QString &format); Q_REVISION(1) void formatterChanged(QValue3DAxisFormatter *formatter); + Q_REVISION(1) void reversedChanged(bool enable); protected: QValue3DAxisPrivate *dptr(); diff --git a/src/datavisualization/axis/qvalue3daxis_p.h b/src/datavisualization/axis/qvalue3daxis_p.h index eeccf527..47fd7e06 100644 --- a/src/datavisualization/axis/qvalue3daxis_p.h +++ b/src/datavisualization/axis/qvalue3daxis_p.h @@ -63,6 +63,7 @@ protected: QString m_labelFormat; bool m_labelsDirty; QValue3DAxisFormatter *m_formatter; + bool m_reversed; private: QValue3DAxis *qptr(); diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 31dcab95..2b566a91 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -357,6 +357,33 @@ void Abstract3DController::synchDataToRenderer() } } + if (m_changeTracker.axisXReversedChanged) { + m_changeTracker.axisXReversedChanged = false; + if (m_axisX->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisX = static_cast(m_axisX); + m_renderer->updateAxisReversed(QAbstract3DAxis::AxisOrientationX, + valueAxisX->reversed()); + } + } + + if (m_changeTracker.axisYReversedChanged) { + m_changeTracker.axisYReversedChanged = false; + if (m_axisY->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisY = static_cast(m_axisY); + m_renderer->updateAxisReversed(QAbstract3DAxis::AxisOrientationY, + valueAxisY->reversed()); + } + } + + if (m_changeTracker.axisZReversedChanged) { + m_changeTracker.axisZReversedChanged = false; + if (m_axisZ->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisZ = static_cast(m_axisZ); + m_renderer->updateAxisReversed(QAbstract3DAxis::AxisOrientationZ, + valueAxisZ->reversed()); + } + } + if (m_changedSeriesList.size()) { m_renderer->modifiedSeriesList(m_changedSeriesList); m_changedSeriesList.clear(); @@ -985,6 +1012,12 @@ void Abstract3DController::handleAxisLabelFormatChanged(const QString &format) handleAxisLabelFormatChangedBySender(sender()); } +void Abstract3DController::handleAxisReversedChanged(bool enable) +{ + Q_UNUSED(enable) + handleAxisReversedChangedBySender(sender()); +} + void Abstract3DController::handleAxisFormatterDirty() { handleAxisFormatterDirtyBySender(sender()); @@ -1052,6 +1085,24 @@ void Abstract3DController::handleAxisLabelFormatChangedBySender(QObject *sender) emitNeedRender(); } +void Abstract3DController::handleAxisReversedChangedBySender(QObject *sender) +{ + // Reversing change needs to dirty the data so item positions are recalculated + if (sender == m_axisX) { + m_isDataDirty = true; + m_changeTracker.axisXReversedChanged = true; + } else if (sender == m_axisY) { + m_isDataDirty = true; + m_changeTracker.axisYReversedChanged = true; + } else if (sender == m_axisZ) { + m_isDataDirty = true; + m_changeTracker.axisZReversedChanged = true; + } else { + qWarning() << __FUNCTION__ << "invoked for invalid axis"; + } + emitNeedRender(); +} + void Abstract3DController::handleAxisFormatterDirtyBySender(QObject *sender) { // Sender is QValue3DAxisPrivate @@ -1149,12 +1200,15 @@ void Abstract3DController::setAxisHelper(QAbstract3DAxis::AxisOrientation orient this, &Abstract3DController::handleAxisSubSegmentCountChanged); QObject::connect(valueAxis, &QValue3DAxis::labelFormatChanged, this, &Abstract3DController::handleAxisLabelFormatChanged); + QObject::connect(valueAxis, &QValue3DAxis::reversedChanged, + this, &Abstract3DController::handleAxisReversedChanged); QObject::connect(valueAxis->dptr(), &QValue3DAxisPrivate::formatterDirty, this, &Abstract3DController::handleAxisFormatterDirty); handleAxisSegmentCountChangedBySender(valueAxis); handleAxisSubSegmentCountChangedBySender(valueAxis); handleAxisLabelFormatChangedBySender(valueAxis); + handleAxisReversedChangedBySender(valueAxis); handleAxisFormatterDirtyBySender(valueAxis->dptr()); } } diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index 07aa9ca3..78c6c81c 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -76,6 +76,9 @@ struct Abstract3DChangeBitField { bool axisXLabelFormatChanged : 1; bool axisYLabelFormatChanged : 1; bool axisZLabelFormatChanged : 1; + bool axisXReversedChanged : 1; + bool axisYReversedChanged : 1; + bool axisZReversedChanged : 1; bool axisXFormatterChanged : 1; bool axisYFormatterChanged : 1; bool axisZFormatterChanged : 1; @@ -107,6 +110,9 @@ struct Abstract3DChangeBitField { axisXLabelFormatChanged(true), axisYLabelFormatChanged(true), axisZLabelFormatChanged(true), + axisXReversedChanged(true), + axisYReversedChanged(true), + axisZReversedChanged(true), axisXFormatterChanged(true), axisYFormatterChanged(true), axisZFormatterChanged(true) @@ -254,6 +260,7 @@ public: virtual void handleAxisAutoAdjustRangeChangedInOrientation( QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust) = 0; virtual void handleAxisLabelFormatChangedBySender(QObject *sender); + virtual void handleAxisReversedChangedBySender(QObject *sender); virtual void handleAxisFormatterDirtyBySender(QObject *sender); virtual void handleSeriesVisibilityChangedBySender(QObject *sender); virtual void handlePendingClick() = 0; @@ -269,6 +276,7 @@ public slots: void handleAxisSubSegmentCountChanged(int count); void handleAxisAutoAdjustRangeChanged(bool autoAdjust); void handleAxisLabelFormatChanged(const QString &format); + void handleAxisReversedChanged(bool enable); void handleAxisFormatterDirty(); void handleInputViewChanged(QAbstract3DInputHandler::InputView view); void handleInputPositionChanged(const QPoint &position); diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index bd19959b..95cecbd3 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -333,6 +333,14 @@ void Abstract3DRenderer::updateAxisLabelFormat(QAbstract3DAxis::AxisOrientation axisCacheForOrientation(orientation).setLabelFormat(format); } +void Abstract3DRenderer::updateAxisReversed(QAbstract3DAxis::AxisOrientation orientation, + bool enable) +{ + axisCacheForOrientation(orientation).setReversed(enable); + foreach (SeriesRenderCache *cache, m_renderCacheList) + cache->setDataDirty(true); +} + void Abstract3DRenderer::updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation, QValue3DAxisFormatter *formatter) { diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index ecbbebac..65dcd8f6 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -103,6 +103,8 @@ public: int count); virtual void updateAxisLabelFormat(QAbstract3DAxis::AxisOrientation orientation, const QString &format); + virtual void updateAxisReversed(QAbstract3DAxis::AxisOrientation orientation, + bool enable); virtual void updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation, QValue3DAxisFormatter *formatter); virtual void modifiedSeriesList(const QVector &seriesList); diff --git a/src/datavisualization/engine/axisrendercache.cpp b/src/datavisualization/engine/axisrendercache.cpp index 8e78522a..baa733b3 100644 --- a/src/datavisualization/engine/axisrendercache.cpp +++ b/src/datavisualization/engine/axisrendercache.cpp @@ -29,6 +29,7 @@ AxisRenderCache::AxisRenderCache() m_max(10.0f), m_segmentCount(5), m_subSegmentCount(1), + m_reversed(false), m_font(QFont(QStringLiteral("Arial"))), m_formatter(0), m_ctrlFormatter(0), @@ -129,17 +130,24 @@ void AxisRenderCache::updateAllPositions() int index = 0; int grid = 0; int label = 0; + float position = 0.0f; for (; label < labelCount; label++) { - m_adjustedLabelPositions[label] = - m_formatter->labelPositions().at(label) * m_scale + m_translate; + position = m_formatter->labelPositions().at(label); + if (m_reversed) + position = 1.0f - position; + m_adjustedLabelPositions[label] = position * m_scale + m_translate; } for (; grid < gridCount; grid++) { - m_adjustedGridLinePositions[index++] = - m_formatter->gridPositions().at(grid) * m_scale + m_translate; + position = m_formatter->gridPositions().at(grid); + if (m_reversed) + position = 1.0f - position; + m_adjustedGridLinePositions[index++] = position * m_scale + m_translate; } for (int subGrid = 0; subGrid < subGridCount; subGrid++) { - m_adjustedGridLinePositions[index++] = - m_formatter->subGridPositions().at(subGrid) * m_scale + m_translate; + position = m_formatter->subGridPositions().at(subGrid); + if (m_reversed) + position = 1.0f - position; + m_adjustedGridLinePositions[index++] = position * m_scale + m_translate; } m_positionsDirty = false; diff --git a/src/datavisualization/engine/axisrendercache_p.h b/src/datavisualization/engine/axisrendercache_p.h index f37857d9..800421b1 100644 --- a/src/datavisualization/engine/axisrendercache_p.h +++ b/src/datavisualization/engine/axisrendercache_p.h @@ -62,6 +62,8 @@ public: inline int subSegmentCount() const { return m_subSegmentCount; } inline void setLabelFormat(const QString &format) { m_labelFormat = format; } inline const QString &labelFormat() const { return m_labelFormat; } + inline void setReversed(bool enable) { m_reversed = enable; m_positionsDirty = true; } + inline bool reversed() const { return m_reversed; } inline void setFormatter(QValue3DAxisFormatter *formatter) { m_formatter = formatter; m_positionsDirty = true; @@ -88,7 +90,10 @@ public: inline float scale() { return m_scale; } inline float positionAt(float value) { - return m_formatter->positionAt(value) * m_scale + m_translate; + if (m_reversed) + return (1.0f - m_formatter->positionAt(value)) * m_scale + m_translate; + else + return m_formatter->positionAt(value) * m_scale + m_translate; } public slots: @@ -106,6 +111,7 @@ private: int m_segmentCount; int m_subSegmentCount; QString m_labelFormat; + bool m_reversed; QFont m_font; QValue3DAxisFormatter *m_formatter; QPointer m_ctrlFormatter; diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp index 35b24218..c394ad2f 100644 --- a/src/datavisualization/engine/bars3dcontroller.cpp +++ b/src/datavisualization/engine/bars3dcontroller.cpp @@ -80,6 +80,13 @@ void Bars3DController::synchDataToRenderer() series->d_ptr->m_changeTracker.meshChanged = true; } + // If y range or reverse changed, scene needs to be updated to update camera limits + bool needSceneUpdate = false; + if (Abstract3DController::m_changeTracker.axisYRangeChanged + || Abstract3DController::m_changeTracker.axisYReversedChanged) { + needSceneUpdate = true; + } + Abstract3DController::synchDataToRenderer(); // Notify changes to renderer @@ -110,6 +117,13 @@ void Bars3DController::synchDataToRenderer() m_renderer->updateSelectedBar(m_selectedBar, m_selectedBarSeries); m_changeTracker.selectedBarChanged = false; } + + if (needSceneUpdate) { + // Since scene is updated before axis updates are handled, + // do another render pass for scene update + m_scene->d_ptr->m_sceneDirty = true; + emitNeedRender(); + } } void Bars3DController::handleArrayReset() diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index f93d20b6..a6f893e5 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -75,7 +75,7 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_shadowQualityToShader(100.0f), m_shadowQualityMultiplier(3), m_heightNormalizer(1.0f), - m_negativeBackgroundAdjustment(0.0f), + m_backgroundAdjustment(0.0f), m_rowWidth(0), m_columnDepth(0), m_maxDimension(0), @@ -266,6 +266,9 @@ void Bars3DRenderer::updateRenderItem(const QBarDataItem &dataItem, BarRenderIte } else { heightValue -= m_zeroPosition; } + if (m_axisCacheY.reversed()) + heightValue = -heightValue; + renderItem.setValue(value); renderItem.setHeight(heightValue); @@ -387,10 +390,19 @@ void Bars3DRenderer::updateItems(const QVector &it void Bars3DRenderer::updateScene(Q3DScene *scene) { - if (m_hasNegativeValues) + if (!m_noZeroInRange) { scene->activeCamera()->d_ptr->setMinYRotation(-90.0); - else - scene->activeCamera()->d_ptr->setMinYRotation(0.0f); + scene->activeCamera()->d_ptr->setMaxYRotation(90.0); + } else { + if ((m_hasNegativeValues && !m_axisCacheY.reversed()) + || (!m_hasNegativeValues && m_axisCacheY.reversed())) { + scene->activeCamera()->d_ptr->setMinYRotation(-90.0f); + scene->activeCamera()->d_ptr->setMaxYRotation(0.0); + } else { + scene->activeCamera()->d_ptr->setMinYRotation(0.0f); + scene->activeCamera()->d_ptr->setMaxYRotation(90.0); + } + } if (m_resetCameraBaseOrientation) { // Set initial camera position. Also update if height adjustment has changed. @@ -455,7 +467,7 @@ void Bars3DRenderer::drawSlicedScene() bool itemMode = m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem); GLfloat barPosYAdjustment = -0.8f; // Translate to -1.0 + 0.2 for row/column labels - GLfloat gridAdjustment = 1.0f + barPosYAdjustment - m_negativeBackgroundAdjustment; + GLfloat gridAdjustment = 1.0f + barPosYAdjustment - m_backgroundAdjustment; GLfloat scaleFactor = 0.0f; if (rowMode) scaleFactor = (1.1f * m_rowWidth) / m_scaleFactor; @@ -463,10 +475,15 @@ void Bars3DRenderer::drawSlicedScene() scaleFactor = (1.1f * m_columnDepth) / m_scaleFactor; GLfloat barLabelYPos = barPosYAdjustment - 0.4f - labelMargin; // 0.4 for labels GLfloat zeroPosAdjustment = 0.0f; - if (!m_noZeroInRange) - zeroPosAdjustment = 2.0f * m_axisCacheY.min() / m_heightNormalizer; - else if (m_hasNegativeValues) - zeroPosAdjustment = -2.0f; + GLfloat directionMultiplier = 2.0f; + GLfloat directionBase = 0.0f; + if (m_axisCacheY.reversed()) { + directionMultiplier = -2.0f; + directionBase = -2.0f; + } + zeroPosAdjustment = directionBase + + directionMultiplier * m_axisCacheY.min() / m_heightNormalizer; + zeroPosAdjustment = qBound(-2.0f, zeroPosAdjustment, 0.0f); // Draw grid lines if (m_cachedTheme->isGridEnabled()) { @@ -624,7 +641,9 @@ void Bars3DRenderer::drawSlicedScene() QQuaternion seriesRotation; foreach (SeriesRenderCache *baseCache, m_renderCacheList) { - if (baseCache->isVisible()) { + if (baseCache->isVisible() + && (baseCache == m_selectedSeriesCache + || m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries))) { BarSeriesRenderCache *cache = static_cast(baseCache); QVector &sliceArray = cache->sliceArray(); int sliceCount = sliceArray.size(); @@ -768,6 +787,7 @@ void Bars3DRenderer::drawSlicedScene() m_dummyBarRenderItem.setTranslation(QVector3D(item.translation().x(), barLabelYPos, item.translation().z())); + // Draw labels m_drawer->drawLabel(m_dummyBarRenderItem, *m_sliceCache->labelItems().at(labelNo), viewMatrix, projectionMatrix, positionComp, sliceLabelRotation, @@ -811,7 +831,7 @@ void Bars3DRenderer::drawSlicedScene() } } } - } else { + } else if (selectedItem) { // Only draw value for selected item when grid labels are on // Create label texture if we need it if (selectedItem->sliceLabel().isNull() || m_updateLabels) { @@ -1468,7 +1488,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) QMatrix4x4 itModelMatrix; QVector3D backgroundScaler(rowScaleFactor, 1.0f, columnScaleFactor); - modelMatrix.translate(0.0f, m_negativeBackgroundAdjustment, 0.0f); + modelMatrix.translate(0.0f, m_backgroundAdjustment, 0.0f); modelMatrix.scale(backgroundScaler); itModelMatrix.scale(backgroundScaler); @@ -1517,44 +1537,42 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_drawer->drawObject(m_backgroundShader, m_backgroundObj); } - // Draw floor for graph with negatives - if (m_hasNegativeValues) { - modelMatrix = QMatrix4x4(); - itModelMatrix = QMatrix4x4(); + // Draw floor + modelMatrix = QMatrix4x4(); + itModelMatrix = QMatrix4x4(); - modelMatrix.scale(backgroundScaler); + modelMatrix.scale(backgroundScaler); - if (m_yFlipped) - modelMatrix.rotate(90.0f, 1.0f, 0.0f, 0.0f); - else - modelMatrix.rotate(-90.0f, 1.0f, 0.0f, 0.0f); + if (m_yFlipped) + modelMatrix.rotate(90.0f, 1.0f, 0.0f, 0.0f); + else + modelMatrix.rotate(-90.0f, 1.0f, 0.0f, 0.0f); - itModelMatrix = modelMatrix; + itModelMatrix = modelMatrix; #ifdef SHOW_DEPTH_TEXTURE_SCENE - MVPMatrix = depthProjectionViewMatrix * modelMatrix; + MVPMatrix = depthProjectionViewMatrix * modelMatrix; #else - MVPMatrix = projectionViewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; #endif - // Set changed shader bindings - m_backgroundShader->setUniformValue(m_backgroundShader->model(), modelMatrix); - m_backgroundShader->setUniformValue(m_backgroundShader->nModel(), - itModelMatrix.inverted().transposed()); - m_backgroundShader->setUniformValue(m_backgroundShader->MVP(), MVPMatrix); + // Set changed shader bindings + m_backgroundShader->setUniformValue(m_backgroundShader->model(), modelMatrix); + m_backgroundShader->setUniformValue(m_backgroundShader->nModel(), + itModelMatrix.inverted().transposed()); + m_backgroundShader->setUniformValue(m_backgroundShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { - // Set shadow shader bindings - QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; - m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix); - // Draw the object - m_drawer->drawObject(m_backgroundShader, m_gridLineObj, 0, m_depthTexture); - } else + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { + // Set shadow shader bindings + QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; + m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix); + // Draw the object + m_drawer->drawObject(m_backgroundShader, m_gridLineObj, 0, m_depthTexture); + } else #endif - { - // Draw the object - m_drawer->drawObject(m_backgroundShader, m_gridLineObj); - } + { + // Draw the object + m_drawer->drawObject(m_backgroundShader, m_gridLineObj); } } @@ -2047,21 +2065,22 @@ void Bars3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientatio if (orientation == QAbstract3DAxis::AxisOrientationY) { // Check if we have negative values - if (min < 0 && !m_hasNegativeValues) { + if (min < 0) m_hasNegativeValues = true; - // Reload background - loadBackgroundMesh(); - emit needRender(); - } else if (min >= 0 && m_hasNegativeValues) { + else if (min >= 0) m_hasNegativeValues = false; - // Reload background - loadBackgroundMesh(); - emit needRender(); - } calculateHeightAdjustment(); } } +void Bars3DRenderer::updateAxisReversed(QAbstract3DAxis::AxisOrientation orientation, bool enable) +{ + Abstract3DRenderer::updateAxisReversed(orientation, enable); + if (orientation == QAbstract3DAxis::AxisOrientationY) + calculateHeightAdjustment(); +} + + void Bars3DRenderer::updateSelectedBar(const QPoint &position, QBar3DSeries *series) { m_selectedBarPos = position; @@ -2142,10 +2161,7 @@ void Bars3DRenderer::loadBackgroundMesh() { if (m_backgroundObj) delete m_backgroundObj; - if (m_hasNegativeValues) - m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/negativeBackground")); - else - m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background")); + m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/negativeBackground")); m_backgroundObj->load(); } @@ -2216,13 +2232,14 @@ void Bars3DRenderer::calculateHeightAdjustment() m_gradientFraction = qMax(minAbs, maxAbs) / m_heightNormalizer * 2.0f; } - // Calculate translation adjustment for negative background - if (m_hasNegativeValues) - newAdjustment = (qBound(0.0f, (maxAbs / m_heightNormalizer), 1.0f) - 0.5f) * 2.0f; + // Calculate translation adjustment for background floor + newAdjustment = (qBound(0.0f, (maxAbs / m_heightNormalizer), 1.0f) - 0.5f) * 2.0f; + if (m_axisCacheY.reversed()) + newAdjustment = -newAdjustment; - if (newAdjustment != m_negativeBackgroundAdjustment) { - m_negativeBackgroundAdjustment = newAdjustment; - m_axisCacheY.setTranslate(m_negativeBackgroundAdjustment - 1.0f); + if (newAdjustment != m_backgroundAdjustment) { + m_backgroundAdjustment = newAdjustment; + m_axisCacheY.setTranslate(m_backgroundAdjustment - 1.0f); } } diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 8e39ee11..68848673 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -86,7 +86,7 @@ private: GLint m_shadowQualityMultiplier; GLfloat m_heightNormalizer; GLfloat m_gradientFraction; - GLfloat m_negativeBackgroundAdjustment; + GLfloat m_backgroundAdjustment; GLfloat m_rowWidth; GLfloat m_columnDepth; GLfloat m_maxDimension; @@ -140,6 +140,8 @@ public slots: // Overloaded from abstract renderer virtual void updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, float max); + virtual void updateAxisReversed(QAbstract3DAxis::AxisOrientation orientation, + bool enable); private: virtual void initShaders(const QString &vertexShader, const QString &fragmentShader); diff --git a/src/datavisualization/engine/q3dscene.h b/src/datavisualization/engine/q3dscene.h index 39c9791f..1699b125 100644 --- a/src/datavisualization/engine/q3dscene.h +++ b/src/datavisualization/engine/q3dscene.h @@ -95,6 +95,7 @@ private: friend class QAbstract3DGraph; friend class QAbstract3DGraphPrivate; friend class Abstract3DController; + friend class Bars3DController; friend class Q3DScenePrivate; friend class Abstract3DRenderer; friend class Bars3DRenderer; diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 198a034d..56219104 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -747,6 +747,9 @@ void Surface3DRenderer::drawSlicedScene() GLfloat scaleXBackground = 0.0f; + // Disable culling to avoid ugly conditionals with reversed axes and data + glDisable(GL_CULL_FACE); + if (!m_renderCacheList.isEmpty()) { bool drawGrid = false; @@ -825,6 +828,9 @@ void Surface3DRenderer::drawSlicedScene() // Disable textures glDisable(GL_TEXTURE_2D); + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + // Grid lines if (m_cachedTheme->isGridEnabled() && m_heightNormalizer) { #if !(defined QT_OPENGL_ES_2) -- cgit v1.2.3