From cf0b67d06249ad2472e2a5ea4de0918079dff7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kera=CC=88nen=20Pasi?= Date: Fri, 9 Aug 2013 16:05:10 +0300 Subject: Rearchitecting to ensure we transfer the data model to renderer in correct step in declarative components. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7d7e646c5e0aed13199e011d5f5f898c21c28095 Reviewed-by: Tomi Korpipää Reviewed-by: Miikka Heikkinen --- src/datavis3d/data/barrenderitem.cpp | 2 +- src/datavis3d/data/scatterrenderitem.cpp | 2 +- src/datavis3d/engine/abstract3dcontroller.cpp | 318 +++++++++++++++++++++-- src/datavis3d/engine/abstract3dcontroller_p.h | 100 ++++++- src/datavis3d/engine/abstract3drenderer.cpp | 47 +--- src/datavis3d/engine/abstract3drenderer_p.h | 31 ++- src/datavis3d/engine/bars3dcontroller.cpp | 91 +++++-- src/datavis3d/engine/bars3dcontroller_p.h | 32 ++- src/datavis3d/engine/bars3drenderer.cpp | 125 +++------ src/datavis3d/engine/bars3drenderer_p.h | 7 +- src/datavis3d/engine/maps3dcontroller.cpp | 10 +- src/datavis3d/engine/maps3dcontroller_p.h | 1 + src/datavis3d/engine/maps3drenderer.cpp | 6 + src/datavis3d/engine/maps3drenderer_p.h | 6 +- src/datavis3d/engine/q3dbars.cpp | 3 +- src/datavis3d/engine/q3dscatter.cpp | 1 + src/datavis3d/engine/scatter3dcontroller.cpp | 98 ++++--- src/datavis3d/engine/scatter3dcontroller_p.h | 37 ++- src/datavis3d/engine/scatter3drenderer.cpp | 100 +++---- src/datavis3d/engine/scatter3drenderer_p.h | 7 +- src/datavis3d/engine/surface3dcontroller.cpp | 13 + src/datavis3d/engine/surface3dcontroller_p.h | 2 + src/datavis3d/engine/surface3drenderer.cpp | 72 ++--- src/datavis3dqml2/declarativebars.cpp | 3 - src/datavis3dqml2/declarativebars_p.h | 3 +- src/datavis3dqml2/declarativebarsrenderer.cpp | 11 +- src/datavis3dqml2/declarativebarsrenderer_p.h | 5 +- src/datavis3dqml2/declarativemaps_p.h | 2 +- src/datavis3dqml2/declarativescatter.cpp | 7 +- src/datavis3dqml2/declarativescatterrenderer.cpp | 11 +- src/datavis3dqml2/declarativescatterrenderer_p.h | 5 +- 31 files changed, 775 insertions(+), 383 deletions(-) diff --git a/src/datavis3d/data/barrenderitem.cpp b/src/datavis3d/data/barrenderitem.cpp index 404e5027..db377aa3 100644 --- a/src/datavis3d/data/barrenderitem.cpp +++ b/src/datavis3d/data/barrenderitem.cpp @@ -40,7 +40,7 @@ void BarRenderItem::formatLabel() // TODO actually format instead of just prepending the value m_label.clear(); // Just in case m_label.append(numStr); - m_label.append(m_renderer->m_dataProxy->itemLabelFormat()); // TODO format needs to be cached + m_label.append(m_renderer->itemLabelFormat()); // TODO format needs to be cached } QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/scatterrenderitem.cpp b/src/datavis3d/data/scatterrenderitem.cpp index 2167c973..15281c0a 100644 --- a/src/datavis3d/data/scatterrenderitem.cpp +++ b/src/datavis3d/data/scatterrenderitem.cpp @@ -45,7 +45,7 @@ void ScatterRenderItem::formatLabel() //m_label.append(m_itemLabel); //m_label.append(QStringLiteral(" ")); m_label.append(numStr); - m_label.append(m_renderer->m_dataProxy->itemLabelFormat()); + m_label.append(m_renderer->itemLabelFormat()); } QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/abstract3dcontroller.cpp b/src/datavis3d/engine/abstract3dcontroller.cpp index 81fd8537..83d89051 100644 --- a/src/datavis3d/engine/abstract3dcontroller.cpp +++ b/src/datavis3d/engine/abstract3dcontroller.cpp @@ -20,6 +20,7 @@ #include "camerahelper_p.h" #include "qabstractaxis_p.h" #include "qvalueaxis.h" +#include "abstract3drenderer_p.h" QT_DATAVIS3D_BEGIN_NAMESPACE @@ -36,7 +37,9 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) : m_zoomLevel(100), m_axisX(0), m_axisY(0), - m_axisZ(0) + m_axisZ(0), + m_renderer(0), + m_isDataDirty(false) { m_theme.useColorTheme(QDataVis::ThemeSystem); } @@ -49,12 +52,180 @@ Abstract3DController::~Abstract3DController() delete m_axisZ; } +void Abstract3DController::setRenderer(Abstract3DRenderer *renderer) +{ + m_renderer = renderer; +} + +void Abstract3DController::synchDataToRenderer() +{ + // If we don't have a renderer, don't do anything + if (!m_renderer) + return; + + if (m_changeTracker.positionChanged) { + m_renderer->updatePosition(m_boundingRect); + m_changeTracker.positionChanged = false; + } + + if (m_changeTracker.themeChanged) { + m_renderer->updateTheme(m_theme); + m_changeTracker.themeChanged = false; + } + + if (m_changeTracker.fontChanged) { + m_renderer->updateFont(m_font); + m_changeTracker.fontChanged = false; + } + + if (m_changeTracker.labelTransparencyChanged) { + m_renderer->updateLabelTransparency(m_labelTransparency); + m_changeTracker.labelTransparencyChanged = false; + } + + if (m_changeTracker.boundingRectChanged || m_changeTracker.sizeChanged) { + m_renderer->updateBoundingRect(m_boundingRect); + m_changeTracker.boundingRectChanged = false; + m_changeTracker.sizeChanged = false; + } + + if (m_changeTracker.shadowQualityChanged) { + m_renderer->updateShadowQuality(m_shadowQuality); + m_changeTracker.shadowQualityChanged = false; + } + + if (m_changeTracker.axisXTypeChanged) { + m_renderer->updateAxisType(QAbstractAxis::AxisOrientation::AxisOrientationX, m_axisX->type()); + m_changeTracker.axisXTypeChanged = false; + } + + if (m_changeTracker.axisYTypeChanged) { + m_renderer->updateAxisType(QAbstractAxis::AxisOrientation::AxisOrientationY, m_axisY->type()); + m_changeTracker.axisYTypeChanged = false; + } + + if (m_changeTracker.axisZTypeChanged) { + m_renderer->updateAxisType(QAbstractAxis::AxisOrientation::AxisOrientationZ, m_axisZ->type()); + m_changeTracker.axisZTypeChanged = false; + } + + if (m_changeTracker.axisXTitleChanged) { + m_renderer->updateAxisTitle(QAbstractAxis::AxisOrientation::AxisOrientationX, m_axisX->title()); + m_changeTracker.axisXTitleChanged = false; + } + + if (m_changeTracker.axisYTitleChanged) { + m_renderer->updateAxisTitle(QAbstractAxis::AxisOrientation::AxisOrientationY, m_axisY->title()); + m_changeTracker.axisYTitleChanged = false; + } + + if (m_changeTracker.axisZTitleChanged) { + m_renderer->updateAxisTitle(QAbstractAxis::AxisOrientation::AxisOrientationZ, m_axisZ->title()); + m_changeTracker.axisZTitleChanged = false; + } + + if (m_changeTracker.axisXLabelsChanged) { + m_renderer->updateAxisLabels(QAbstractAxis::AxisOrientation::AxisOrientationX, m_axisX->labels()); + m_changeTracker.axisXLabelsChanged = false; + } + + if (m_changeTracker.axisYLabelsChanged) { + m_renderer->updateAxisLabels(QAbstractAxis::AxisOrientation::AxisOrientationY, m_axisY->labels()); + m_changeTracker.axisYLabelsChanged = false; + } + if (m_changeTracker.axisZLabelsChanged) { + m_renderer->updateAxisLabels(QAbstractAxis::AxisOrientation::AxisOrientationZ, m_axisZ->labels()); + m_changeTracker.axisZLabelsChanged = false; + } + + if (m_changeTracker.axisXRangeChanged) { + m_changeTracker.axisXRangeChanged = false; + if (m_axisX->type() & QAbstractAxis::AxisTypeValue) { + QValueAxis *valueAxisX = static_cast(m_axisX); + m_renderer->updateAxisRange(QAbstractAxis::AxisOrientation::AxisOrientationX, valueAxisX->min(), valueAxisX->max()); + } + } + + if (m_changeTracker.axisYRangeChanged) { + m_changeTracker.axisYRangeChanged = false; + if (m_axisY->type() & QAbstractAxis::AxisTypeValue) { + QValueAxis *valueAxisY = static_cast(m_axisY); + m_renderer->updateAxisRange(QAbstractAxis::AxisOrientation::AxisOrientationY, valueAxisY->min(), valueAxisY->max()); + } + } + + if (m_changeTracker.axisZRangeChanged) { + m_changeTracker.axisZRangeChanged = false; + if (m_axisZ->type() & QAbstractAxis::AxisTypeValue) { + QValueAxis *valueAxisZ = static_cast(m_axisZ); + m_renderer->updateAxisRange(QAbstractAxis::AxisOrientation::AxisOrientationZ, valueAxisZ->min(), valueAxisZ->max()); + } + } + + if (m_changeTracker.axisXSegmentCountChanged) { + m_changeTracker.axisXSegmentCountChanged = false; + if (m_axisX->type() & QAbstractAxis::AxisTypeValue) { + QValueAxis *valueAxisX = static_cast(m_axisX); + m_renderer->updateAxisSegmentCount(QAbstractAxis::AxisOrientation::AxisOrientationX, valueAxisX->segmentCount()); + } + } + + if (m_changeTracker.axisYSegmentCountChanged) { + m_changeTracker.axisYSegmentCountChanged = false; + if (m_axisY->type() & QAbstractAxis::AxisTypeValue) { + QValueAxis *valueAxisY = static_cast(m_axisY); + m_renderer->updateAxisSegmentCount(QAbstractAxis::AxisOrientation::AxisOrientationY, valueAxisY->segmentCount()); + } + } + + if (m_changeTracker.axisZSegmentCountChanged) { + m_changeTracker.axisZSegmentCountChanged = false; + if (m_axisZ->type() & QAbstractAxis::AxisTypeValue) { + QValueAxis *valueAxisZ = static_cast(m_axisZ); + m_renderer->updateAxisSegmentCount(QAbstractAxis::AxisOrientation::AxisOrientationZ, valueAxisZ->segmentCount()); + } + } + + if (m_changeTracker.axisXSubSegmentCountChanged) { + m_changeTracker.axisXSubSegmentCountChanged = false; + if (m_axisX->type() & QAbstractAxis::AxisTypeValue) { + QValueAxis *valueAxisX = static_cast(m_axisX); + m_renderer->updateAxisSubSegmentCount(QAbstractAxis::AxisOrientation::AxisOrientationX, valueAxisX->subSegmentCount()); + } + } + + if (m_changeTracker.axisYSubSegmentCountChanged) { + m_changeTracker.axisYSubSegmentCountChanged = false; + if (m_axisY->type() & QAbstractAxis::AxisTypeValue) { + QValueAxis *valueAxisY = static_cast(m_axisY); + m_renderer->updateAxisSubSegmentCount(QAbstractAxis::AxisOrientation::AxisOrientationY, valueAxisY->subSegmentCount()); + } + } + + if (m_changeTracker.axisZSubSegmentCountChanged) { + m_changeTracker.axisZSubSegmentCountChanged = false; + if (m_axisZ->type() & QAbstractAxis::AxisTypeValue) { + QValueAxis *valueAxisZ = static_cast(m_axisZ); + m_renderer->updateAxisSubSegmentCount(QAbstractAxis::AxisOrientation::AxisOrientationZ, valueAxisZ->subSegmentCount()); + } + } +} + +void Abstract3DController::render(const GLuint defaultFboHandle) +{ + // If not initialized, do nothing. + if (!m_renderer) + return; + + m_renderer->render(m_cameraHelper, defaultFboHandle); +} + void Abstract3DController::setSize(const int width, const int height) { m_boundingRect.setWidth(width); m_boundingRect.setHeight(height); - //qDebug() << "Abstract3DController::setSize " << m_boundingRect.width() << "x" <labels()); - else if (sender() == m_axisY) + } else if (sender == m_axisY) { + m_changeTracker.axisYLabelsChanged = true; emit axisLabelsChanged(QAbstractAxis::AxisOrientationY, m_axisY->labels()); - else if (sender() == m_axisZ) + } else if (sender == m_axisZ) { + m_changeTracker.axisZLabelsChanged = true; emit axisLabelsChanged(QAbstractAxis::AxisOrientationZ, m_axisZ->labels()); - else + } else { qWarning() << __FUNCTION__ << "invoked for invalid axis"; + } } void Abstract3DController::handleAxisRangeChanged(qreal min, qreal max) { - if (sender() == m_axisX) + handleAxisRangeChangedBySender(sender(), min, max); +} + +void Abstract3DController::handleAxisRangeChangedBySender(QObject *sender, qreal min, qreal max) +{ + if (sender == m_axisX) { + m_isDataDirty = true; + m_changeTracker.axisXRangeChanged = true; emit axisRangeChanged(QAbstractAxis::AxisOrientationX, min, max); - else if (sender() == m_axisY) + } else if (sender == m_axisY) { + m_isDataDirty = true; + m_changeTracker.axisYRangeChanged = true; emit axisRangeChanged(QAbstractAxis::AxisOrientationY, min, max); - else if (sender() == m_axisZ) + } else if (sender == m_axisZ) { + m_isDataDirty = true; + + m_changeTracker.axisZRangeChanged = true; emit axisRangeChanged(QAbstractAxis::AxisOrientationZ, min, max); - else + } else { qWarning() << __FUNCTION__ << "invoked for invalid axis"; + } } void Abstract3DController::handleAxisSegmentCountChanged(int count) { - if (sender() == m_axisX) + handleAxisSegmentCountChangedBySender(sender(), count); +} + +void Abstract3DController::handleAxisSegmentCountChangedBySender(QObject *sender, int count) +{ + if (sender == m_axisX) { + m_changeTracker.axisXSegmentCountChanged = true; emit axisSegmentCountChanged(QAbstractAxis::AxisOrientationX, count); - else if (sender() == m_axisY) + } else if (sender == m_axisY) { + m_changeTracker.axisYSegmentCountChanged = true; emit axisSegmentCountChanged(QAbstractAxis::AxisOrientationY, count); - else if (sender() == m_axisZ) + } else if (sender == m_axisZ) { + m_changeTracker.axisZSegmentCountChanged = true; emit axisSegmentCountChanged(QAbstractAxis::AxisOrientationZ, count); - else + } else { qWarning() << __FUNCTION__ << "invoked for invalid axis"; + } } void Abstract3DController::handleAxisSubSegmentCountChanged(int count) { - if (sender() == m_axisX) + handleAxisSubSegmentCountChangedBySender(sender(), count); +} + +void Abstract3DController::handleAxisSubSegmentCountChangedBySender(QObject *sender, int count) +{ + if (sender == m_axisX) { + m_changeTracker.axisXSubSegmentCountChanged = true; emit axisSubSegmentCountChanged(QAbstractAxis::AxisOrientationX, count); - else if (sender() == m_axisY) + } else if (sender == m_axisY) { + m_changeTracker.axisYSubSegmentCountChanged = true; emit axisSubSegmentCountChanged(QAbstractAxis::AxisOrientationY, count); - else if (sender() == m_axisZ) + } else if (sender == m_axisZ) { + m_changeTracker.axisZSubSegmentCountChanged = true; emit axisSubSegmentCountChanged(QAbstractAxis::AxisOrientationZ, count); - else + } else { qWarning() << __FUNCTION__ << "invoked for invalid axis"; + } } void Abstract3DController::handleAxisAutoAdjustRangeChanged(bool autoAdjust) { - Q_UNUSED(autoAdjust) - // Adjust axis range according to data. Default implementation does nothing, - // This needs to be implemented by subclass. + QObject *sender = QObject::sender(); + if (sender != m_axisX && sender != m_axisY && sender != m_axisZ) + return; + + QAbstractAxis *axis = static_cast(sender); + handleAxisAutoAdjustRangeChangedInOrientation(axis->orientation(), autoAdjust); } void Abstract3DController::setAxisHelper(QAbstractAxis::AxisOrientation orientation, @@ -325,8 +569,19 @@ void Abstract3DController::setAxisHelper(QAbstractAxis::AxisOrientation orientat QObject::connect(axis, &QAbstractAxis::labelsChanged, this, &Abstract3DController::handleAxisLabelsChanged); + + if (orientation == QAbstractAxis::AxisOrientation::AxisOrientationX) + m_changeTracker.axisXTypeChanged = true; + else if (orientation == QAbstractAxis::AxisOrientation::AxisOrientationY) + m_changeTracker.axisYTypeChanged = true; + else if (orientation == QAbstractAxis::AxisOrientation::AxisOrientationZ) + m_changeTracker.axisZTypeChanged = true; emit axisTypeChanged(orientation, axis->type()); + + handleAxisTitleChangedBySender(axis, axis->title()); emit axisTitleChanged(orientation, axis->title()); + + handleAxisLabelsChangedBySender(axis); emit axisLabelsChanged(orientation, axis->labels()); if (axis->type() & QAbstractAxis::AxisTypeValue) { @@ -339,10 +594,17 @@ void Abstract3DController::setAxisHelper(QAbstractAxis::AxisOrientation orientat this, &Abstract3DController::handleAxisSubSegmentCountChanged); QObject::connect(valueAxis, &QValueAxis::autoAdjustRangeChanged, this, &Abstract3DController::handleAxisAutoAdjustRangeChanged); + + handleAxisRangeChangedBySender(valueAxis, valueAxis->min(), valueAxis->max()); emit axisRangeChanged(orientation, valueAxis->min(), valueAxis->max()); + + handleAxisSegmentCountChangedBySender(valueAxis, valueAxis->segmentCount()); emit axisSegmentCountChanged(orientation, valueAxis->segmentCount()); + + handleAxisSubSegmentCountChangedBySender(valueAxis, valueAxis->subSegmentCount()); emit axisSubSegmentCountChanged(orientation, valueAxis->subSegmentCount()); - handleAxisAutoAdjustRangeChanged(valueAxis->isAutoAdjustRange()); + + handleAxisAutoAdjustRangeChangedInOrientation(valueAxis->orientation(), valueAxis->isAutoAdjustRange()); } } diff --git a/src/datavis3d/engine/abstract3dcontroller_p.h b/src/datavis3d/engine/abstract3dcontroller_p.h index c5f8da7c..ed201c66 100644 --- a/src/datavis3d/engine/abstract3dcontroller_p.h +++ b/src/datavis3d/engine/abstract3dcontroller_p.h @@ -41,6 +41,66 @@ class QFont; QT_DATAVIS3D_BEGIN_NAMESPACE class CameraHelper; +class Abstract3DRenderer; + +struct Abstract3DChangeBitField { + bool positionChanged : 1; + bool zoomLevelChanged : 1; + bool themeChanged : 1; + bool fontChanged : 1; + bool labelTransparencyChanged : 1; + bool boundingRectChanged : 1; + bool sizeChanged : 1; + bool shadowQualityChanged : 1; + bool axisXTypeChanged : 1; + bool axisYTypeChanged : 1; + bool axisZTypeChanged : 1; + bool axisXTitleChanged : 1; + bool axisYTitleChanged : 1; + bool axisZTitleChanged : 1; + bool axisXLabelsChanged : 1; + bool axisYLabelsChanged : 1; + bool axisZLabelsChanged : 1; + bool axisXRangeChanged : 1; + bool axisYRangeChanged : 1; + bool axisZRangeChanged : 1; + bool axisXSegmentCountChanged : 1; + bool axisYSegmentCountChanged : 1; + bool axisZSegmentCountChanged : 1; + bool axisXSubSegmentCountChanged : 1; + bool axisYSubSegmentCountChanged : 1; + bool axisZSubSegmentCountChanged : 1; + + Abstract3DChangeBitField() : + positionChanged(true), + zoomLevelChanged(true), + themeChanged(true), + fontChanged(true), + labelTransparencyChanged(true), + boundingRectChanged(true), + sizeChanged(true), + shadowQualityChanged(true), + axisXTypeChanged(true), + axisYTypeChanged(true), + axisZTypeChanged(true), + axisXTitleChanged(true), + axisYTitleChanged(true), + axisZTitleChanged(true), + axisXLabelsChanged(true), + axisYLabelsChanged(true), + axisZLabelsChanged(true), + axisXRangeChanged(true), + axisYRangeChanged(true), + axisZRangeChanged(true), + axisXSegmentCountChanged(true), + axisYSegmentCountChanged(true), + axisZSegmentCountChanged(true), + axisXSubSegmentCountChanged(true), + axisYSubSegmentCountChanged(true), + axisZSubSegmentCountChanged(true) + { + } +}; class QT_DATAVIS3D_EXPORT Abstract3DController : public QObject { @@ -57,6 +117,7 @@ public: }; private: + Abstract3DChangeBitField m_changeTracker; QRect m_boundingRect; GLfloat m_horizontalRotation; GLfloat m_verticalRotation; @@ -71,13 +132,29 @@ protected: QAbstractAxis *m_axisX; QAbstractAxis *m_axisY; QAbstractAxis *m_axisZ; + Abstract3DRenderer *m_renderer; + bool m_isDataDirty; explicit Abstract3DController(QRect boundRect, QObject *parent = 0); ~Abstract3DController(); public: - virtual void render(const GLuint defaultFboHandle)=0; + inline bool isInitialized() { return (m_renderer != 0); } + + /** + * @brief synchDataToRenderer Called on the render thread while main GUI thread is blocked before rendering. + */ + virtual void synchDataToRenderer(); + + + virtual void render(const GLuint defaultFboHandle = 0); + + /** + * @brief setRenderer Sets the renderer to be used. isInitialized returns true from this point onwards. + * @param renderer Renderer to be used. + */ + void setRenderer(Abstract3DRenderer *renderer); // Size virtual void setSize(const int width, const int height); @@ -137,13 +214,20 @@ public: virtual void setLabelTransparency(QDataVis::LabelTransparency transparency); virtual QDataVis::LabelTransparency labelTransparency(); + virtual void handleAxisTitleChangedBySender(QObject *sender, const QString &title); + virtual void handleAxisLabelsChangedBySender(QObject *sender); + virtual void handleAxisRangeChangedBySender(QObject *sender, qreal min, qreal max); + virtual void handleAxisSegmentCountChangedBySender(QObject *sender, int count); + virtual void handleAxisSubSegmentCountChangedBySender(QObject *sender, int count); + virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust) = 0; + public slots: - virtual void handleAxisTitleChanged(const QString &title); - virtual void handleAxisLabelsChanged(); - virtual void handleAxisRangeChanged(qreal min, qreal max); - virtual void handleAxisSegmentCountChanged(int count); - virtual void handleAxisSubSegmentCountChanged(int count); - virtual void handleAxisAutoAdjustRangeChanged(bool autoAdjust); + void handleAxisTitleChanged(const QString &title); + void handleAxisLabelsChanged(); + void handleAxisRangeChanged(qreal min, qreal max); + void handleAxisSegmentCountChanged(int count); + void handleAxisSubSegmentCountChanged(int count); + void handleAxisAutoAdjustRangeChanged(bool autoAdjust); signals: void boundingRectChanged(QRect boundingRect); @@ -153,7 +237,7 @@ signals: void themeChanged(Theme theme); void fontChanged(QFont font); // TODO should be handled via axis?? What about font for selection label? void shadowQualityChanged(QDataVis::ShadowQuality quality); - void labelTransparencyUpdated(QDataVis::LabelTransparency transparency); + void labelTransparencyChanged(QDataVis::LabelTransparency transparency); void axisTypeChanged(QAbstractAxis::AxisOrientation orientation, QAbstractAxis::AxisType type); void axisTitleChanged(QAbstractAxis::AxisOrientation orientation, QString title); void axisLabelsChanged(QAbstractAxis::AxisOrientation orientation, QStringList labels); diff --git a/src/datavis3d/engine/abstract3drenderer.cpp b/src/datavis3d/engine/abstract3drenderer.cpp index 097b85ff..2e5d89d4 100644 --- a/src/datavis3d/engine/abstract3drenderer.cpp +++ b/src/datavis3d/engine/abstract3drenderer.cpp @@ -24,55 +24,26 @@ QT_DATAVIS3D_BEGIN_NAMESPACE Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) : QObject(controller), m_controller(controller), + m_isInitialized(false), m_hasNegativeValues(false), m_drawer(new Drawer(m_cachedTheme, m_cachedFont, m_cachedLabelTransparency)), m_autoScaleAdjustment(1.0f) { + QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures); } -void Abstract3DRenderer::initializePreOpenGL() +void Abstract3DRenderer::initializeOpenGL() { - QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures); - - QObject::connect(m_controller, &Abstract3DController::themeChanged, this, - &Abstract3DRenderer::updateTheme); - QObject::connect(m_controller, &Abstract3DController::fontChanged, this, - &Abstract3DRenderer::updateFont); - QObject::connect(m_controller, &Abstract3DController::labelTransparencyUpdated, this, - &Abstract3DRenderer::updateLabelTransparency); - QObject::connect(m_controller, &Abstract3DController::boundingRectChanged, this, - &Abstract3DRenderer::updateBoundingRect); - QObject::connect(m_controller, &Abstract3DController::sizeChanged, this, - &Abstract3DRenderer::updateBoundingRect); - QObject::connect(m_controller, &Abstract3DController::shadowQualityChanged, this, - &Abstract3DRenderer::updateShadowQuality); - QObject::connect(m_controller, &Abstract3DController::axisTypeChanged, this, - &Abstract3DRenderer::updateAxisType); - QObject::connect(m_controller, &Abstract3DController::axisTitleChanged, this, - &Abstract3DRenderer::updateAxisTitle); - QObject::connect(m_controller, &Abstract3DController::axisLabelsChanged, this, - &Abstract3DRenderer::updateAxisLabels); - QObject::connect(m_controller, &Abstract3DController::axisRangeChanged, this, - &Abstract3DRenderer::updateAxisRange); - QObject::connect(m_controller, &Abstract3DController::axisSegmentCountChanged, this, - &Abstract3DRenderer::updateAxisSegmentCount); - QObject::connect(m_controller, &Abstract3DController::axisSubSegmentCountChanged, this, - &Abstract3DRenderer::updateAxisSubSegmentCount); - - updateTheme(m_controller->theme()); - updateFont(m_controller->font()); - updateLabelTransparency(m_controller->labelTransparency()); } -void Abstract3DRenderer::initializeOpenGL() +void Abstract3DRenderer::updateDataModel(QAbstractDataProxy *dataProxy) { - // OpenGL is initialized, safe to call these. - updateBoundingRect(m_controller->boundingRect()); - updateShadowQuality(m_controller->shadowQuality()); + m_cachedItemLabelFormat = dataProxy->itemLabelFormat(); +} - initializeAxisCache(QAbstractAxis::AxisOrientationX, m_controller->axisX()); - initializeAxisCache(QAbstractAxis::AxisOrientationY, m_controller->axisY()); - initializeAxisCache(QAbstractAxis::AxisOrientationZ, m_controller->axisZ()); +QString Abstract3DRenderer::itemLabelFormat() const +{ + return m_cachedItemLabelFormat; } void Abstract3DRenderer::updateBoundingRect(const QRect boundingRect) diff --git a/src/datavis3d/engine/abstract3drenderer_p.h b/src/datavis3d/engine/abstract3drenderer_p.h index c7c90c90..b19ef101 100644 --- a/src/datavis3d/engine/abstract3drenderer_p.h +++ b/src/datavis3d/engine/abstract3drenderer_p.h @@ -35,6 +35,7 @@ #include "datavis3dglobal_p.h" #include "abstract3dcontroller_p.h" #include "axisrendercache_p.h" +#include "qabstractdataproxy.h" QT_DATAVIS3D_BEGIN_NAMESPACE @@ -42,7 +43,7 @@ class Abstract3DRenderer : public QObject, protected QOpenGLFunctions { protected: Abstract3DController *m_controller; - + bool m_isInitialized; bool m_hasNegativeValues; QRect m_cachedBoundingRect; QDataVis::ShadowQuality m_cachedShadowQuality; @@ -51,15 +52,18 @@ protected: QDataVis::LabelTransparency m_cachedLabelTransparency; Drawer *m_drawer; GLfloat m_autoScaleAdjustment; + QString m_cachedItemLabelFormat; AxisRenderCache m_axisCacheX; AxisRenderCache m_axisCacheY; AxisRenderCache m_axisCacheZ; Abstract3DRenderer(Abstract3DController *controller); - virtual void initializePreOpenGL(); virtual void initializeOpenGL(); +public: + inline bool isInitialized() { return m_isInitialized; } + virtual void updateBoundingRect(const QRect boundingRect); virtual void updatePosition(const QRect boundingRect); virtual void handleResize(); @@ -70,13 +74,15 @@ protected: virtual void handleShadowQualityChange(); - virtual void requestSelectionAtPoint(const QPoint &point)=0; - virtual void updateTextures()=0; - virtual void initSelectionBuffer()=0; - virtual void updateDepthBuffer()=0; - virtual void updateShadowQuality(QDataVis::ShadowQuality quality)=0; - virtual void initShaders(const QString &vertexShader, const QString &fragmentShader)=0; - virtual void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader)=0; + void updateDataModel(QAbstractDataProxy *dataProxy); + virtual QString itemLabelFormat() const; + virtual void requestSelectionAtPoint(const QPoint &point) = 0; + virtual void updateTextures() = 0; + virtual void initSelectionBuffer() = 0; + virtual void updateDepthBuffer() = 0; + virtual void updateShadowQuality(QDataVis::ShadowQuality quality) = 0; + virtual void initShaders(const QString &vertexShader, const QString &fragmentShader) = 0; + virtual void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader) = 0; virtual void updateAxisType(QAbstractAxis::AxisOrientation orientation, QAbstractAxis::AxisType type); virtual void updateAxisTitle(QAbstractAxis::AxisOrientation orientation, const QString &title); virtual void updateAxisLabels(QAbstractAxis::AxisOrientation orientation, const QStringList &labels); @@ -86,6 +92,13 @@ protected: void initializeAxisCache(QAbstractAxis::AxisOrientation orientation, const QAbstractAxis *axis); AxisRenderCache &axisCacheForOrientation(QAbstractAxis::AxisOrientation orientation); + +public: + /** + * @brief render Implements OpenGL rendering that occurs in the rendering thread. + * @param defaultFboHandle Defaults FBO handle (defaults to 0). + */ + virtual void render(CameraHelper *camera, const GLuint defaultFboHandle) = 0; }; QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/bars3dcontroller.cpp b/src/datavis3d/engine/bars3dcontroller.cpp index 4394c133..2a6a3a15 100644 --- a/src/datavis3d/engine/bars3dcontroller.cpp +++ b/src/datavis3d/engine/bars3dcontroller.cpp @@ -35,7 +35,6 @@ QT_DATAVIS3D_BEGIN_NAMESPACE Bars3dController::Bars3dController(QRect boundRect) : Abstract3DController(boundRect), - m_isInitialized(false), m_rowCount(0), m_columnCount(0), m_mouseState(MouseNone), @@ -49,8 +48,7 @@ Bars3dController::Bars3dController(QRect boundRect) m_isGridEnabled(true), m_isBackgroundEnabled(true), m_renderer(0), - m_data(0), - m_valuesDirty(false) + m_data(0) { // Default axes. Only Y axis can actually be changed by user. setAxisX(new QCategoryAxis()); @@ -68,23 +66,65 @@ Bars3dController::~Bars3dController() void Bars3dController::initializeOpenGL() { // Initialization is called multiple times when Qt Quick components are used - if (m_isInitialized) + if (isInitialized()) return; m_renderer = new Bars3dRenderer(this); - m_isInitialized = true; + setRenderer(m_renderer); } -void Bars3dController::render(const GLuint defaultFboHandle) +void Bars3dController::synchDataToRenderer() { - if (!m_isInitialized) + Abstract3DController::synchDataToRenderer(); + + if (!isInitialized()) return; - // TODO do not give the entire data array, just the data window - m_renderer->render(m_data, m_valuesDirty, m_cameraHelper, defaultFboHandle); + // Notify changes to renderer + if (m_changeTracker.selectionModeChanged) { + m_renderer->updateSelectionMode(m_selectionMode); + m_changeTracker.selectionModeChanged = false; + } + + if (m_changeTracker.slicingActiveChanged) { + m_renderer->updateSlicingActive(m_isSlicingActivated); + m_changeTracker.slicingActiveChanged = false; + } + + if (m_changeTracker.sampleSpaceChanged) { + m_renderer->updateSampleSpace(m_rowCount, m_columnCount); + m_changeTracker.sampleSpaceChanged = false; + } + + if (m_changeTracker.barSpecsChanged) { + m_renderer->updateBarSpecs(m_barThickness, m_barSpacing, m_isBarSpecRelative); + m_changeTracker.barSpecsChanged = false; + } + + if (m_changeTracker.objFileChanged) { + m_renderer->updateMeshFileName(m_objFile); + m_changeTracker.objFileChanged = false; + } + + if (m_changeTracker.gridEnabledChanged) { + m_renderer->updateGridEnabled(m_isGridEnabled); + m_changeTracker.gridEnabledChanged = false; + } + + if (m_changeTracker.backgroundEnabledChanged) { + m_renderer->updateBackgroundEnabled(m_isBackgroundEnabled); + m_changeTracker.backgroundEnabledChanged = false; + } - m_valuesDirty = false; + if (m_changeTracker.zoomLevelChanged) { + m_renderer->updateZoomLevel(m_zoomLevel); + m_changeTracker.zoomLevelChanged = false; + } + if (m_isDataDirty) { + m_renderer->updateDataModel(m_data); + m_isDataDirty = false; + } } QMatrix4x4 Bars3dController::calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight, bool showUnder) @@ -104,6 +144,8 @@ bool Bars3dController::isSlicingActive() void Bars3dController::setSlicingActive(bool isSlicing) { m_isSlicingActivated = isSlicing; + + m_changeTracker.slicingActiveChanged = true; emit slicingActiveChanged(m_isSlicingActivated); } @@ -245,7 +287,7 @@ void Bars3dController::setDataProxy(QBarDataProxy *proxy) QObject::connect(m_data, &QBarDataProxy::itemChanged, this, &Bars3dController::handleItemChanged); adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } QBarDataProxy *Bars3dController::dataProxy() @@ -257,7 +299,7 @@ void Bars3dController::handleArrayReset() { setSlicingActive(false); adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } void Bars3dController::handleRowsAdded(int startIndex, int count) @@ -268,7 +310,7 @@ void Bars3dController::handleRowsAdded(int startIndex, int count) // TODO should update slice instead of deactivating? setSlicingActive(false); adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } void Bars3dController::handleRowsChanged(int startIndex, int count) @@ -279,7 +321,7 @@ void Bars3dController::handleRowsChanged(int startIndex, int count) // TODO should update slice instead of deactivating? setSlicingActive(false); adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } void Bars3dController::handleRowsRemoved(int startIndex, int count) @@ -290,7 +332,7 @@ void Bars3dController::handleRowsRemoved(int startIndex, int count) // TODO should update slice instead of deactivating? setSlicingActive(false); adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } void Bars3dController::handleRowsInserted(int startIndex, int count) @@ -301,7 +343,7 @@ void Bars3dController::handleRowsInserted(int startIndex, int count) // TODO should update slice instead of deactivating? setSlicingActive(false); adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } void Bars3dController::handleItemChanged(int rowIndex, int columnIndex) @@ -312,11 +354,12 @@ void Bars3dController::handleItemChanged(int rowIndex, int columnIndex) // TODO should update slice instead of deactivating? setSlicingActive(false); adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } -void Bars3dController::handleAxisAutoAdjustRangeChanged(bool autoAdjust) +void Bars3dController::handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust) { + Q_UNUSED(orientation) Q_UNUSED(autoAdjust) adjustValueAxisRange(); } @@ -326,6 +369,8 @@ void Bars3dController::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relati m_barThickness = thickness; m_barSpacing = spacing; m_isBarSpecRelative = relative; + + m_changeTracker.barSpecsChanged = true; emit barSpecsChanged(thickness, spacing, relative); } @@ -378,6 +423,8 @@ void Bars3dController::setBarType(QDataVis::MeshStyle style, bool smooth) m_objFile = QStringLiteral(":/defaultMeshes/bevelbar"); } + + m_changeTracker.objFileChanged = true; emit objFileChanged(m_objFile); } @@ -385,6 +432,7 @@ void Bars3dController::setMeshFileName(const QString &objFileName) { m_objFile = objFileName; + m_changeTracker.objFileChanged = true; emit objFileChanged(m_objFile); } @@ -399,6 +447,7 @@ void Bars3dController::setupSampleSpace(int rowCount, int columnCount) adjustValueAxisRange(); + m_changeTracker.sampleSpaceChanged = true; emit sampleSpaceChanged(rowCount, columnCount); } @@ -408,6 +457,8 @@ void Bars3dController::setSelectionMode(QDataVis::SelectionMode mode) m_selectionMode = mode; // Disable zoom if selection mode changes setSlicingActive(false); + + m_changeTracker.selectionModeChanged = true; emit selectionModeChanged(m_selectionMode); } @@ -424,6 +475,8 @@ QDataVis::SelectionMode Bars3dController::selectionMode() void Bars3dController::setGridEnabled(bool enable) { m_isGridEnabled = enable; + + m_changeTracker.gridEnabledChanged = true; emit gridEnabledChanged(m_isGridEnabled); } @@ -435,6 +488,8 @@ bool Bars3dController::gridEnabled() void Bars3dController::setBackgroundEnabled(bool enable) { m_isBackgroundEnabled = enable; + + m_changeTracker.backgroundEnabledChanged = true; emit backgroundEnabledChanged(m_isBackgroundEnabled); } diff --git a/src/datavis3d/engine/bars3dcontroller_p.h b/src/datavis3d/engine/bars3dcontroller_p.h index f87ab866..4f6523f0 100644 --- a/src/datavis3d/engine/bars3dcontroller_p.h +++ b/src/datavis3d/engine/bars3dcontroller_p.h @@ -47,6 +47,29 @@ class Bars3dRenderer; class LabelItem; class QBarDataProxy; +struct Bars3DChangeBitField { + bool selectionModeChanged : 1; + bool slicingActiveChanged : 1; + bool sampleSpaceChanged : 1; + bool barSpecsChanged : 1; + bool objFileChanged : 1; + bool gridEnabledChanged : 1; + bool backgroundEnabledChanged : 1; + bool zoomLevelChanged : 1; + + Bars3DChangeBitField() : + selectionModeChanged(true), + slicingActiveChanged(true), + sampleSpaceChanged(true), + barSpecsChanged(true), + objFileChanged(true), + gridEnabledChanged(true), + backgroundEnabledChanged(true), + zoomLevelChanged(true) + { + } +}; + class QT_DATAVIS3D_EXPORT Bars3dController : public Abstract3DController { Q_OBJECT @@ -60,7 +83,9 @@ public: }; private: - bool m_isInitialized; + + + Bars3DChangeBitField m_changeTracker; // Data int m_rowCount; @@ -83,14 +108,13 @@ private: Bars3dRenderer *m_renderer; QBarDataProxy *m_data; - bool m_valuesDirty; public: explicit Bars3dController(QRect rect); ~Bars3dController(); void initializeOpenGL(); - void render(const GLuint defaultFboHandle = 0); + virtual void synchDataToRenderer(); int columnCount(); int rowCount(); @@ -150,6 +174,7 @@ public: // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy. void setDataProxy(QBarDataProxy *proxy); QBarDataProxy *dataProxy(); + virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust); public slots: void handleArrayReset(); @@ -159,7 +184,6 @@ public slots: void handleRowsInserted(int startIndex, int count); void handleItemChanged(int rowIndex, int columnIndex); - virtual void handleAxisAutoAdjustRangeChanged(bool autoAdjust); signals: void selectionModeChanged(QDataVis::SelectionMode mode); diff --git a/src/datavis3d/engine/bars3drenderer.cpp b/src/datavis3d/engine/bars3drenderer.cpp index 22409b23..0240d31a 100644 --- a/src/datavis3d/engine/bars3drenderer.cpp +++ b/src/datavis3d/engine/bars3drenderer.cpp @@ -90,16 +90,13 @@ Bars3dRenderer::Bars3dRenderer(Bars3dController *controller) m_scaleFactor(0), m_maxSceneSize(40.0), m_selection(selectionSkipColor), - m_hasHeightAdjustmentChanged(true), - m_dataProxy(0), - m_valueUpdateNeeded(false) + m_hasHeightAdjustmentChanged(true) #ifdef DISPLAY_RENDER_SPEED ,m_isFirstFrame(true), m_numFrames(0) #endif { m_dummyBarRenderItem.setRenderer(this); - initializePreOpenGL(); initializeOpenGLFunctions(); initializeOpenGL(); } @@ -126,41 +123,6 @@ Bars3dRenderer::~Bars3dRenderer() delete m_drawer; } -void Bars3dRenderer::initializePreOpenGL() -{ - Abstract3DRenderer::initializePreOpenGL(); - - // Listen to changes in the controller - QObject::connect(m_controller, &Bars3dController::selectionModeChanged, this, - &Bars3dRenderer::updateSelectionMode); - QObject::connect(m_controller, &Bars3dController::slicingActiveChanged, this, - &Bars3dRenderer::updateSlicingActive); - QObject::connect(m_controller, &Bars3dController::sampleSpaceChanged, this, - &Bars3dRenderer::updateSampleSpace); - QObject::connect(m_controller, &Bars3dController::barSpecsChanged, this, - &Bars3dRenderer::updateBarSpecs); - QObject::connect(m_controller, &Bars3dController::objFileChanged, this, - &Bars3dRenderer::updateMeshFileName); - QObject::connect(m_controller, &Bars3dController::positionChanged, this, - &Bars3dRenderer::updatePosition); - QObject::connect(m_controller, &Bars3dController::gridEnabledChanged, this, - &Bars3dRenderer::updateGridEnabled); - QObject::connect(m_controller, &Bars3dController::backgroundEnabledChanged, this, - &Bars3dRenderer::updateBackgroundEnabled); - QObject::connect(m_controller, &Bars3dController::zoomLevelChanged, this, - &Bars3dRenderer::updateZoomLevel); - - updateSampleSpace(m_controller->rowCount(), m_controller->columnCount()); - updateSelectionMode(m_controller->selectionMode()); - updateSlicingActive(m_controller->isSlicingActive()); - updateZoomLevel(m_controller->zoomLevel()); - updateBarSpecs(m_controller->barThickness(), m_controller->barSpacing(), - m_controller->isBarSpecRelative()); - updateMeshFileName(m_controller->objFile()); - updateGridEnabled(m_controller->gridEnabled()); - updateBackgroundEnabled(m_controller->backgroundEnabled()); -} - void Bars3dRenderer::initializeOpenGL() { m_textureHelper = new TextureHelper(); @@ -179,9 +141,6 @@ void Bars3dRenderer::initializeOpenGL() // Init selection shader initSelectionShader(); - // Load default mesh - loadBarMesh(); - // Load grid line mesh loadGridLineMesh(); @@ -204,20 +163,39 @@ void Bars3dRenderer::initializeOpenGL() glViewport(m_sliceViewPort.x(), m_sliceViewPort.y(), m_sliceViewPort.width(), m_sliceViewPort.height()); - // Resize in case we've missed resize events - // Resize calls initSelectionBuffer and initDepthBuffer, so they don't need to be called here - handleResize(); - // Load background mesh (we need to be initialized first) loadBackgroundMesh(); Abstract3DRenderer::initializeOpenGL(); } -void Bars3dRenderer::render(QBarDataProxy *dataProxy, - bool valuesDirty, - CameraHelper *camera, - const GLuint defaultFboHandle) +void Bars3dRenderer::updateDataModel(QBarDataProxy *dataProxy) +{ + // Update cached data window + int dataRowCount = dataProxy->rowCount(); + for (int i = 0; i < m_renderItemArray.size(); i++) { + int j = 0; + if (i < dataRowCount) { + const QBarDataRow *dataRow = dataProxy->rowAt(i); + int updateSize = qMin(dataRow->size(), m_renderItemArray[i].size()); + if (dataRow) { + for (; j < updateSize ; j++) { + qreal value = dataRow->at(j).value(); + m_renderItemArray[i][j].setValue(value); + m_renderItemArray[i][j].setHeight(value / m_heightNormalizer); + } + } + } + for (; j < m_renderItemArray[i].size(); j++) { + m_renderItemArray[i][j].setValue(0.0); + m_renderItemArray[i][j].setHeight(0.0f); + } + } + + Abstract3DRenderer::updateDataModel(dataProxy); +} + +void Bars3dRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle) { #ifdef DISPLAY_RENDER_SPEED // For speed computation @@ -235,34 +213,6 @@ void Bars3dRenderer::render(QBarDataProxy *dataProxy, } #endif - m_dataProxy = dataProxy; - - // Update cached data window - // TODO Should data changes be notified via signal instead of reading data in render? - // TODO this cache initialization assumes data window starts at 0,0 offset from array - if (valuesDirty || m_valueUpdateNeeded) { - m_valueUpdateNeeded = false; - int dataRowCount = dataProxy->rowCount(); - for (int i = 0; i < m_renderItemArray.size(); i++) { - int j = 0; - if (i < dataRowCount) { - const QBarDataRow *dataRow = dataProxy->rowAt(i); - int updateSize = qMin(dataRow->size(), m_renderItemArray[i].size()); - if (dataRow) { - for (; j < updateSize ; j++) { - qreal value = dataRow->at(j).value(); - m_renderItemArray[i][j].setValue(value); - m_renderItemArray[i][j].setHeight(value / m_heightNormalizer); - } - } - } - for (; j < m_renderItemArray[i].size(); j++) { - m_renderItemArray[i][j].setValue(0.0); - m_renderItemArray[i][j].setHeight(0.0f); - } - } - } - if (defaultFboHandle) { glDepthMask(true); glEnable(GL_DEPTH_TEST); @@ -464,7 +414,7 @@ void Bars3dRenderer::drawSlicedScene(CameraHelper *camera, // If draw order of bars is flipped, label draw order should be too if (m_xFlipped) { labelItem = m_sliceCache->labelItems().at( - m_sliceCache->labelItems().size() - col - 1); + m_sliceCache->labelItems().size() - col - 1); } else { labelItem = m_sliceCache->labelItems().at(col); } @@ -514,10 +464,10 @@ void Bars3dRenderer::drawScene(CameraHelper *camera, // Calculate view matrix QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix( - m_cachedZoomLevel * m_autoScaleAdjustment, - m_mainViewPort.width(), - m_mainViewPort.height(), - m_hasNegativeValues); + m_cachedZoomLevel * m_autoScaleAdjustment, + m_mainViewPort.width(), + m_mainViewPort.height(), + m_hasNegativeValues); // Calculate drawing order // Draw order is reversed to optimize amount of drawing (ie. draw front objects first, depth test handles not needing to draw objects behind them) @@ -841,14 +791,14 @@ void Bars3dRenderer::drawScene(CameraHelper *camera, QVector3D baseColor = Utils::vectorFromColor(m_cachedTheme.m_baseColor); QVector3D heightColor = Utils::vectorFromColor(m_cachedTheme.m_heightColor) * item.height(); QVector3D depthColor = Utils::vectorFromColor(m_cachedTheme.m_depthColor) - * (float(row) / GLfloat(m_cachedRowCount)); + * (float(row) / GLfloat(m_cachedRowCount)); QVector3D barColor = baseColor + heightColor + depthColor; GLfloat lightStrength = m_cachedTheme.m_lightStrength; if (m_cachedSelectionMode > QDataVis::ModeNone) { - Bars3dController::SelectionType selectionType = isSelected(row, bar); + Bars3dController::SelectionType selectionType = isSelected(row, bar); switch (selectionType) { case Bars3dController::SelectionBar: { @@ -1579,8 +1529,6 @@ void Bars3dRenderer::updateSampleSpace(int rowCount, int columnCount) m_renderItemArray[i][j].setRenderer(this); } - m_valueUpdateNeeded = true; - // Force update for selection related items m_sliceCache = 0; m_sliceTitleItem = 0; @@ -1757,9 +1705,6 @@ void Bars3dRenderer::calculateHeightAdjustment() m_yAdjustment = newAdjustment; } //qDebug() << m_yAdjustment; - - // If this function needs to be called, then value update is also needed - m_valueUpdateNeeded = true; } Bars3dController::SelectionType Bars3dRenderer::isSelected(GLint row, GLint bar) diff --git a/src/datavis3d/engine/bars3drenderer_p.h b/src/datavis3d/engine/bars3drenderer_p.h index 68c34598..221b3f74 100644 --- a/src/datavis3d/engine/bars3drenderer_p.h +++ b/src/datavis3d/engine/bars3drenderer_p.h @@ -128,10 +128,8 @@ private: bool m_hasHeightAdjustmentChanged; BarRenderItem m_dummyBarRenderItem; - QBarDataProxy *m_dataProxy; // Only valid during render BarRenderItemArray m_renderItemArray; - bool m_valueUpdateNeeded; #ifdef DISPLAY_RENDER_SPEED bool m_isFirstFrame; @@ -143,8 +141,8 @@ public: explicit Bars3dRenderer(Bars3dController *controller); ~Bars3dRenderer(); - void render(QBarDataProxy *dataProxy, bool valuesDirty, CameraHelper *camera, - const GLuint defaultFboHandle = 0); + void updateDataModel(QBarDataProxy *dataProxy); + void render(CameraHelper *camera, const GLuint defaultFboHandle = 0); QRect mainViewPort(); @@ -172,7 +170,6 @@ signals: void selectionUpdated(QVector3D selection); private: - virtual void initializePreOpenGL(); virtual void initializeOpenGL(); virtual void initShaders(const QString &vertexShader, const QString &fragmentShader); virtual void updateShadowQuality(QDataVis::ShadowQuality quality); diff --git a/src/datavis3d/engine/maps3dcontroller.cpp b/src/datavis3d/engine/maps3dcontroller.cpp index 9dc15bc4..7d558437 100644 --- a/src/datavis3d/engine/maps3dcontroller.cpp +++ b/src/datavis3d/engine/maps3dcontroller.cpp @@ -238,6 +238,12 @@ void Maps3DController::initializeOpenGL() #endif } +void Maps3DController::synchDataToRenderer() +{ + // TODO: Implement! +} + + /*! * \internal */ @@ -1622,9 +1628,9 @@ void Maps3DController::calculateTranslation(MapRenderItem &item) // We need to convert position (which is in coordinates), to translation (which has origin in the center and is scaled) // -> move pos(center, center) to trans(0, 0) and pos(0, 0) to trans(left, top) GLfloat xTrans = 2.0f * (item.mapPosition().x() - (m_areaSize.width() / 2.0f)) - / m_scaleFactor; + / m_scaleFactor; GLfloat zTrans = 2.0f * (item.mapPosition().y() - (m_areaSize.height() / 2.0f)) - / m_scaleFactor; + / m_scaleFactor; //qDebug() << "x, y" << item.mapPosition().x() << item.mapPosition().y(); item.setTranslation(QVector3D(xTrans, 0.0f, zTrans + zComp)); //qDebug() << item.translation(); diff --git a/src/datavis3d/engine/maps3dcontroller_p.h b/src/datavis3d/engine/maps3dcontroller_p.h index 5043bf97..d0c2e74e 100644 --- a/src/datavis3d/engine/maps3dcontroller_p.h +++ b/src/datavis3d/engine/maps3dcontroller_p.h @@ -76,6 +76,7 @@ public: ~Maps3DController(); void initializeOpenGL(); + virtual void synchDataToRenderer(); void render(const GLuint defaultFboHandle = 0); // bar specifications; base thickness in x, y and z, enum to indicate which direction is increased with value diff --git a/src/datavis3d/engine/maps3drenderer.cpp b/src/datavis3d/engine/maps3drenderer.cpp index 4c52441a..c1e9af2c 100644 --- a/src/datavis3d/engine/maps3drenderer.cpp +++ b/src/datavis3d/engine/maps3drenderer.cpp @@ -63,4 +63,10 @@ Maps3DRenderer::~Maps3DRenderer() { } +void Maps3DRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle) +{ + // TODO: Implement +} + + QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/maps3drenderer_p.h b/src/datavis3d/engine/maps3drenderer_p.h index d2c84425..89054e83 100644 --- a/src/datavis3d/engine/maps3drenderer_p.h +++ b/src/datavis3d/engine/maps3drenderer_p.h @@ -29,9 +29,11 @@ #ifndef MAPS3DRENDERER_P_H #define MAPS3DRENDERER_P_H -#include "datavis3dglobal_p.h" #include +#include "datavis3dglobal_p.h" +#include "camerahelper_p.h" + QT_DATAVIS3D_BEGIN_NAMESPACE class Maps3DController; @@ -42,6 +44,8 @@ class QT_DATAVIS3D_EXPORT Maps3DRenderer : public QObject, public QOpenGLFunctio public: explicit Maps3DRenderer(Maps3DController *controller); ~Maps3DRenderer(); + + void render(CameraHelper *camera, const GLuint defaultFboHandle); }; QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp index 9ee3da9b..e46d5d14 100644 --- a/src/datavis3d/engine/q3dbars.cpp +++ b/src/datavis3d/engine/q3dbars.cpp @@ -99,6 +99,7 @@ Q3DBars::~Q3DBars() */ void Q3DBars::render() { + d_ptr->m_shared->synchDataToRenderer(); d_ptr->m_shared->render(); } @@ -199,7 +200,7 @@ void Q3DBars::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relative) } /*! - * \a style One of the values in \c BarStyle. \c Bars by default. + * \a style One of the values in \c MeshStyle. \c Bars by default. * * \a smooth A flag to set shading to smooth. \c false by default. * diff --git a/src/datavis3d/engine/q3dscatter.cpp b/src/datavis3d/engine/q3dscatter.cpp index 0493e444..a9c4a1b0 100644 --- a/src/datavis3d/engine/q3dscatter.cpp +++ b/src/datavis3d/engine/q3dscatter.cpp @@ -99,6 +99,7 @@ Q3DScatter::~Q3DScatter() */ void Q3DScatter::render() { + d_ptr->m_shared->synchDataToRenderer(); d_ptr->m_shared->render(); } diff --git a/src/datavis3d/engine/scatter3dcontroller.cpp b/src/datavis3d/engine/scatter3dcontroller.cpp index 89646af7..21490971 100644 --- a/src/datavis3d/engine/scatter3dcontroller.cpp +++ b/src/datavis3d/engine/scatter3dcontroller.cpp @@ -34,18 +34,15 @@ QT_DATAVIS3D_BEGIN_NAMESPACE Scatter3DController::Scatter3DController(QRect boundRect) : Abstract3DController(boundRect), - m_isInitialized(false), m_mouseState(MouseNone), m_mousePos(QPoint(0, 0)), m_selectionMode(QDataVis::ModeItem), m_isSlicingActivated(false), m_objFile(QStringLiteral(":/defaultMeshes/sphere")), - m_font(QFont(QStringLiteral("Arial"))), m_isGridEnabled(true), m_isBackgroundEnabled(true), m_renderer(0), - m_data(0), - m_valuesDirty(false) + m_data(0) { // Default axes setAxisX(new QValueAxis()); @@ -63,23 +60,55 @@ Scatter3DController::~Scatter3DController() void Scatter3DController::initializeOpenGL() { // Initialization is called multiple times when Qt Quick components are used - if (m_isInitialized) + if (isInitialized()) return; m_renderer = new Scatter3DRenderer(this); - m_isInitialized = true; + setRenderer(m_renderer); } -void Scatter3DController::render(const GLuint defaultFboHandle) +void Scatter3DController::synchDataToRenderer() { - if (!m_isInitialized) + Abstract3DController::synchDataToRenderer(); + + if (!isInitialized()) return; - // TODO do not give the entire data array, just the data window - m_renderer->render(m_data, m_valuesDirty, m_cameraHelper, defaultFboHandle); + // Notify changes to renderer + if (m_changeTracker.selectionModeChanged) { + m_renderer->updateSelectionMode(m_selectionMode); + m_changeTracker.selectionModeChanged = false; + } + + if (m_changeTracker.slicingActiveChanged) { + // TODO: Add notification. + m_changeTracker.slicingActiveChanged = false; + } + + if (m_changeTracker.objFileChanged) { + m_renderer->updateMeshFileName(m_objFile); + m_changeTracker.objFileChanged = false; + } + + if (m_changeTracker.gridEnabledChanged) { + m_renderer->updateGridEnabled(m_isGridEnabled); + m_changeTracker.gridEnabledChanged = false; + } + + if (m_changeTracker.backgroundEnabledChanged) { + m_renderer->updateBackgroundEnabled(m_isBackgroundEnabled); + m_changeTracker.backgroundEnabledChanged = false; + } - m_valuesDirty = false; + if (m_changeTracker.zoomLevelChanged) { + m_renderer->updateZoomLevel(m_zoomLevel); + m_changeTracker.zoomLevelChanged = false; + } + if (m_isDataDirty) { + m_renderer->updateDataModel(m_data); + m_isDataDirty = false; + } } QMatrix4x4 Scatter3DController::calculateViewMatrix(int zoom, int viewPortWidth, @@ -100,6 +129,8 @@ bool Scatter3DController::isSlicingActive() void Scatter3DController::setSlicingActive(bool isSlicing) { m_isSlicingActivated = isSlicing; + + m_changeTracker.slicingActiveChanged = true; emit slicingActiveChanged(m_isSlicingActivated); } @@ -239,7 +270,7 @@ void Scatter3DController::setDataProxy(QScatterDataProxy *proxy) this, &Scatter3DController::handleItemsInserted); adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } QScatterDataProxy *Scatter3DController::dataProxy() @@ -251,7 +282,7 @@ void Scatter3DController::handleArrayReset() { setSlicingActive(false); adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } void Scatter3DController::handleItemsAdded(int startIndex, int count) @@ -260,7 +291,7 @@ void Scatter3DController::handleItemsAdded(int startIndex, int count) Q_UNUSED(count) // TODO should dirty only affected values? adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } void Scatter3DController::handleItemsChanged(int startIndex, int count) @@ -269,7 +300,7 @@ void Scatter3DController::handleItemsChanged(int startIndex, int count) Q_UNUSED(count) // TODO should dirty only affected values? adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } void Scatter3DController::handleItemsRemoved(int startIndex, int count) @@ -278,7 +309,7 @@ void Scatter3DController::handleItemsRemoved(int startIndex, int count) Q_UNUSED(count) // TODO should dirty only affected values? adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } void Scatter3DController::handleItemsInserted(int startIndex, int count) @@ -287,11 +318,12 @@ void Scatter3DController::handleItemsInserted(int startIndex, int count) Q_UNUSED(count) // TODO should dirty only affected values? adjustValueAxisRange(); - m_valuesDirty = true; + m_isDataDirty = true; } -void Scatter3DController::handleAxisAutoAdjustRangeChanged(bool autoAdjust) +void Scatter3DController::handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust) { + Q_UNUSED(orientation) Q_UNUSED(autoAdjust) adjustValueAxisRange(); } @@ -315,6 +347,7 @@ void Scatter3DController::setObjectType(QDataVis::MeshStyle style, bool smooth) m_objFile = QStringLiteral(":/defaultMeshes/dot"); } + m_changeTracker.objFileChanged = true; emit objFileChanged(m_objFile); } @@ -322,6 +355,7 @@ void Scatter3DController::setMeshFileName(const QString &objFileName) { m_objFile = objFileName; + m_changeTracker.objFileChanged = true; emit objFileChanged(m_objFile); } @@ -334,6 +368,8 @@ void Scatter3DController::setSelectionMode(QDataVis::SelectionMode mode) m_selectionMode = mode; // Disable zoom if selection mode changes setSlicingActive(false); + + m_changeTracker.selectionModeChanged = true; emit selectionModeChanged(m_selectionMode); } @@ -347,31 +383,11 @@ QDataVis::SelectionMode Scatter3DController::selectionMode() return m_selectionMode; } -void Scatter3DController::setFontSize(float fontsize) -{ - m_font.setPointSizeF(fontsize); - emit fontChanged(m_font); -} - -float Scatter3DController::fontSize() -{ - return m_font.pointSizeF(); -} - -void Scatter3DController::setFont(const QFont &font) -{ - m_font = font; - emit fontChanged(m_font); -} - -QFont Scatter3DController::font() -{ - return m_font; -} - void Scatter3DController::setGridEnabled(bool enable) { m_isGridEnabled = enable; + + m_changeTracker.gridEnabledChanged = true; emit gridEnabledChanged(m_isGridEnabled); } @@ -383,6 +399,8 @@ bool Scatter3DController::gridEnabled() void Scatter3DController::setBackgroundEnabled(bool enable) { m_isBackgroundEnabled = enable; + + m_changeTracker.backgroundEnabledChanged = true; emit backgroundEnabledChanged(m_isBackgroundEnabled); } diff --git a/src/datavis3d/engine/scatter3dcontroller_p.h b/src/datavis3d/engine/scatter3dcontroller_p.h index 96d3391f..f9d4c284 100644 --- a/src/datavis3d/engine/scatter3dcontroller_p.h +++ b/src/datavis3d/engine/scatter3dcontroller_p.h @@ -48,6 +48,25 @@ class Scatter3DRenderer; class LabelItem; class QScatterDataProxy; +struct Scatter3DChangeBitField { + bool selectionModeChanged : 1; + bool slicingActiveChanged : 1; + bool objFileChanged : 1; + bool gridEnabledChanged : 1; + bool backgroundEnabledChanged : 1; + bool zoomLevelChanged : 1; + + Scatter3DChangeBitField() : + selectionModeChanged(true), + slicingActiveChanged(true), + objFileChanged(true), + gridEnabledChanged(true), + backgroundEnabledChanged(true), + zoomLevelChanged(true) + { + } +}; + class QT_DATAVIS3D_EXPORT Scatter3DController : public Abstract3DController { Q_OBJECT @@ -61,7 +80,7 @@ public: }; private: - bool m_isInitialized; + Scatter3DChangeBitField m_changeTracker; // Interaction MouseState m_mouseState; @@ -71,20 +90,17 @@ private: // Look'n'Feel QString m_objFile; - QFont m_font; bool m_isGridEnabled; bool m_isBackgroundEnabled; Scatter3DRenderer *m_renderer; QScatterDataProxy *m_data; - bool m_valuesDirty; public: explicit Scatter3DController(QRect rect); ~Scatter3DController(); void initializeOpenGL(); - void render(const GLuint defaultFboHandle = 0); MouseState mouseState(); QPoint mousePosition(); @@ -106,14 +122,6 @@ public: void setSelectionMode(QDataVis::SelectionMode mode); QDataVis::SelectionMode selectionMode(); - // Font size adjustment - void setFontSize(float fontsize); - float fontSize(); - - // Set font - void setFont(const QFont &font); - QFont font(); - // Enable or disable background grid void setGridEnabled(bool enable); bool gridEnabled(); @@ -135,6 +143,10 @@ public: void setDataProxy(QScatterDataProxy *proxy); QScatterDataProxy *dataProxy(); + void synchDataToRenderer(); + + virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust); + public slots: void handleArrayReset(); void handleItemsAdded(int startIndex, int count); @@ -142,7 +154,6 @@ public slots: void handleItemsRemoved(int startIndex, int count); void handleItemsInserted(int startIndex, int count); - virtual void handleAxisAutoAdjustRangeChanged(bool autoAdjust); signals: void selectionModeChanged(QDataVis::SelectionMode mode); diff --git a/src/datavis3d/engine/scatter3drenderer.cpp b/src/datavis3d/engine/scatter3drenderer.cpp index e0c4bdf9..78639d06 100644 --- a/src/datavis3d/engine/scatter3drenderer.cpp +++ b/src/datavis3d/engine/scatter3drenderer.cpp @@ -84,8 +84,6 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) m_selection(selectionSkipColor), m_areaSize(QSizeF(0.0f, 0.0f)), m_hasHeightAdjustmentChanged(true), - m_dataProxy(0), - m_valueUpdateNeeded(false), m_dotSizeScale(1.0f) #ifdef DISPLAY_RENDER_SPEED , m_isFirstFrame(true), @@ -94,7 +92,6 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) { //qDebug() << __FUNCTION__; m_dummyRenderItem.setRenderer(this); - initializePreOpenGL(); initializeOpenGLFunctions(); initializeOpenGL(); } @@ -117,30 +114,6 @@ Scatter3DRenderer::~Scatter3DRenderer() delete m_textureHelper; } -void Scatter3DRenderer::initializePreOpenGL() -{ - Abstract3DRenderer::initializePreOpenGL(); - - QObject::connect(m_controller, &Scatter3DController::selectionModeChanged, this, - &Scatter3DRenderer::updateSelectionMode); - QObject::connect(m_controller, &Scatter3DController::objFileChanged, this, - &Scatter3DRenderer::updateMeshFileName); - QObject::connect(m_controller, &Scatter3DController::positionChanged, this, - &Scatter3DRenderer::updatePosition); - QObject::connect(m_controller, &Scatter3DController::gridEnabledChanged, this, - &Scatter3DRenderer::updateGridEnabled); - QObject::connect(m_controller, &Scatter3DController::backgroundEnabledChanged, this, - &Scatter3DRenderer::updateBackgroundEnabled); - QObject::connect(m_controller, &Scatter3DController::zoomLevelChanged, this, - &Scatter3DRenderer::updateZoomLevel); - - updateSelectionMode(m_controller->selectionMode()); - updateZoomLevel(m_controller->zoomLevel()); - updateMeshFileName(m_controller->objFile()); - updateGridEnabled(m_controller->gridEnabled()); - updateBackgroundEnabled(m_controller->backgroundEnabled()); -} - void Scatter3DRenderer::initializeOpenGL() { //qDebug() << __FUNCTION__; @@ -161,9 +134,6 @@ void Scatter3DRenderer::initializeOpenGL() // Init selection shader initSelectionShader(); - // Load default mesh - loadBarMesh(); - // Load grid line mesh loadGridLineMesh(); @@ -196,10 +166,27 @@ void Scatter3DRenderer::initializeOpenGL() Abstract3DRenderer::initializeOpenGL(); } -void Scatter3DRenderer::render(QScatterDataProxy *dataProxy, - bool valuesDirty, - CameraHelper *camera, - const GLuint defaultFboHandle) +void Scatter3DRenderer::updateDataModel(QScatterDataProxy *dataProxy) +{ + const QScatterDataArray &dataArray = *dataProxy->array(); + calculateSceneScalingFactors(); + int dataSize = dataArray.size(); + m_renderItemArray.resize(dataSize); + for (int i = 0; i < dataSize ; i++) { + qreal value = dataArray.at(i).position().y(); + m_renderItemArray[i].setValue(value); + m_renderItemArray[i].setPosition(dataArray.at(i).position()); + //m_renderItemArray[i].setHeight(value / m_heightNormalizer); + //m_renderItemArray[i].setItemLabel(dataArray.at(i).label()); + calculateTranslation(m_renderItemArray[i]); + m_renderItemArray[i].setRenderer(this); + } + m_dotSizeScale = (GLfloat)qBound(0.01, (qreal)(2.0f / qSqrt((qreal)dataSize)), 0.1); + + Abstract3DRenderer::updateDataModel(dataProxy); +} + +void Scatter3DRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle) { //qDebug() << __FUNCTION__; @@ -219,29 +206,6 @@ void Scatter3DRenderer::render(QScatterDataProxy *dataProxy, } #endif - m_dataProxy = dataProxy; - - // TODO Should data changes be notified via signal instead of reading data in render? - // TODO this cache initialization assumes data window starts at 0,0 offset from array - // Update cached values - if (valuesDirty|| m_valueUpdateNeeded) { - m_valueUpdateNeeded = false; - const QScatterDataArray &dataArray = *m_dataProxy->array(); - calculateSceneScalingFactors(); - int dataSize = dataArray.size(); - m_renderItemArray.resize(dataSize); - for (int i = 0; i < dataSize ; i++) { - qreal value = dataArray.at(i).position().y(); - m_renderItemArray[i].setValue(value); - m_renderItemArray[i].setPosition(dataArray.at(i).position()); - //m_renderItemArray[i].setHeight(value / m_heightNormalizer); - //m_renderItemArray[i].setItemLabel(dataArray.at(i).label()); - calculateTranslation(m_renderItemArray[i]); - m_renderItemArray[i].setRenderer(this); - } - m_dotSizeScale = (GLfloat)qBound(0.01, (qreal)(2.0f / qSqrt((qreal)dataSize)), 0.1); - } - if (defaultFboHandle) { glDepthMask(true); glEnable(GL_DEPTH_TEST); @@ -283,10 +247,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, // Calculate view matrix QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix( - m_cachedZoomLevel * m_autoScaleAdjustment, - m_mainViewPort.width(), - m_mainViewPort.height(), - true); + m_cachedZoomLevel * m_autoScaleAdjustment, + m_mainViewPort.width(), + m_mainViewPort.height(), + true); // Calculate label flipping if (viewMatrix.row(0).x() > 0) @@ -971,7 +935,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, for (int segment = 0; segment <= lastSegment; segment++) { #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z GLfloat lineZTrans = (aspectRatio * backgroundMargin * m_areaSize.height()) - / m_scaleFactor; + / m_scaleFactor; #else // ..and this if we want uniform scaling based on largest dimension GLfloat lineZTrans = aspectRatio * backgroundMargin; #endif @@ -1040,7 +1004,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, for (int segment = 0; segment <= lastSegment; segment++) { #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z GLfloat lineXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) - / m_scaleFactor; + / m_scaleFactor; #else // ..and this if we want uniform scaling based on largest dimension GLfloat lineXTrans = aspectRatio * backgroundMargin; #endif @@ -1191,7 +1155,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z if (m_axisCacheZ.labelItems().size() > labelNbr) { GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) - / m_scaleFactor; + / m_scaleFactor; #else // ..and this if we want uniform scaling based on largest dimension if (axisCacheMax->labelItems().size() > labelNbr) { GLfloat labelXTrans = aspectRatio * backgroundMargin; @@ -1252,7 +1216,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z if (m_axisCacheX.labelItems().size() > labelNbr) { GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height()) - / m_scaleFactor; + / m_scaleFactor; #else // ..and this if we want uniform scaling based on largest dimension if (axisCacheMax->labelItems().size() > labelNbr) { GLfloat labelZTrans = aspectRatio * backgroundMargin; @@ -1305,9 +1269,9 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, if (m_axisCacheY.labelItems().size() > labelNbr) { #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) - / m_scaleFactor; + / m_scaleFactor; GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height()) - / m_scaleFactor; + / m_scaleFactor; #else // ..and this if we want uniform scaling based on largest dimension GLfloat labelXTrans = aspectRatio * backgroundMargin; GLfloat labelZTrans = labelXTrans; @@ -1528,8 +1492,6 @@ void Scatter3DRenderer::updateAxisRange(QAbstractAxis::AxisOrientation orientati qreal min, qreal max) { Abstract3DRenderer::updateAxisRange(orientation, min, max); - // If this function is called, then value update is also needed - m_valueUpdateNeeded = true; } void Scatter3DRenderer::calculateTranslation(ScatterRenderItem &item) diff --git a/src/datavis3d/engine/scatter3drenderer_p.h b/src/datavis3d/engine/scatter3drenderer_p.h index bae41a14..048764da 100644 --- a/src/datavis3d/engine/scatter3drenderer_p.h +++ b/src/datavis3d/engine/scatter3drenderer_p.h @@ -116,10 +116,8 @@ private: bool m_hasHeightAdjustmentChanged; ScatterRenderItem m_dummyRenderItem; - QScatterDataProxy *m_dataProxy; // Only valid during render ScatterRenderItemArray m_renderItemArray; - bool m_valueUpdateNeeded; #ifdef DISPLAY_RENDER_SPEED bool m_isFirstFrame; @@ -131,8 +129,8 @@ public: explicit Scatter3DRenderer(Scatter3DController *controller); ~Scatter3DRenderer(); - void render(QScatterDataProxy *dataProxy, bool valuesDirty, CameraHelper *camera, - const GLuint defaultFboHandle = 0); + void updateDataModel(QScatterDataProxy *dataProxy); + void render(CameraHelper *camera, const GLuint defaultFboHandle); QRect mainViewPort(); @@ -155,7 +153,6 @@ signals: void selectionUpdated(QVector3D selection); private: - virtual void initializePreOpenGL(); virtual void initializeOpenGL(); virtual void initShaders(const QString &vertexShader, const QString &fragmentShader); virtual void updateShadowQuality(QDataVis::ShadowQuality quality); diff --git a/src/datavis3d/engine/surface3dcontroller.cpp b/src/datavis3d/engine/surface3dcontroller.cpp index 2b927898..2915c993 100644 --- a/src/datavis3d/engine/surface3dcontroller.cpp +++ b/src/datavis3d/engine/surface3dcontroller.cpp @@ -52,6 +52,11 @@ void Surface3dController::initializeOpenGL() m_isInitialized = true; } +void Surface3dController::synchDataToRenderer() +{ + // TODO: Implement +} + void Surface3dController::render(const GLuint defaultFboHandle) { if (!m_isInitialized) @@ -60,6 +65,14 @@ void Surface3dController::render(const GLuint defaultFboHandle) m_renderer->render(m_cameraHelper, defaultFboHandle); } +void Surface3dController::handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust) +{ + Q_UNUSED(orientation) + Q_UNUSED(autoAdjust) + + // TODO: Implement! +} + QMatrix4x4 Surface3dController::calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight, bool showUnder) { return m_cameraHelper->calculateViewMatrix(m_mousePos, diff --git a/src/datavis3d/engine/surface3dcontroller_p.h b/src/datavis3d/engine/surface3dcontroller_p.h index 74f825f9..d8c36d08 100644 --- a/src/datavis3d/engine/surface3dcontroller_p.h +++ b/src/datavis3d/engine/surface3dcontroller_p.h @@ -65,6 +65,7 @@ public: ~Surface3dController(); void initializeOpenGL(); + void synchDataToRenderer(); void render(const GLuint defaultFboHandle = 0); QPoint mousePosition(); @@ -103,6 +104,7 @@ public: // TODO: abstract renderer should have accessor for Drawer instead virtual Drawer *drawer(); + virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust); signals: void smoothStatusChanged(bool enable); diff --git a/src/datavis3d/engine/surface3drenderer.cpp b/src/datavis3d/engine/surface3drenderer.cpp index 781ff090..c66bd291 100644 --- a/src/datavis3d/engine/surface3drenderer.cpp +++ b/src/datavis3d/engine/surface3drenderer.cpp @@ -234,10 +234,10 @@ void Surface3dRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH // Calculate view matrix QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix( - 100.0f, //TODO: m_zoomLevel * m_autoScaleAdjustment - m_mainViewPort.width(), - m_mainViewPort.height(), - m_hasNegativeValues); + 100.0f, //TODO: m_zoomLevel * m_autoScaleAdjustment + m_mainViewPort.width(), + m_mainViewPort.height(), + m_hasNegativeValues); // calculate background rotation based on view matrix rotation if (viewMatrix.row(0).x() > 0 && viewMatrix.row(0).z() <= 0) @@ -278,7 +278,7 @@ void Surface3dRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH QMatrix4x4 MVPMatrix; modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp); - modelMatrix.scale(QVector3D( m_xLength / m_scaleFactor, + modelMatrix.scale(QVector3D(m_xLength / m_scaleFactor, 1.0f, m_zLength / m_scaleFactor)); @@ -346,10 +346,10 @@ void Surface3dRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH QMatrix4x4 itModelMatrix; modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp); - modelMatrix.scale(QVector3D( m_xLength / m_scaleFactor, + modelMatrix.scale(QVector3D(m_xLength / m_scaleFactor, 1.0f, m_zLength / m_scaleFactor)); - itModelMatrix.scale(QVector3D( m_xLength / m_scaleFactor, + itModelMatrix.scale(QVector3D(m_xLength / m_scaleFactor, 1.0f, m_zLength / m_scaleFactor)); @@ -375,7 +375,7 @@ void Surface3dRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH //m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(), m_shadowQualityToShader); //m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix); m_surfaceShader->setUniformValue(m_surfaceShader->lightS(), - m_cachedTheme.m_lightStrength * 2.0f); + m_cachedTheme.m_lightStrength * 2.0f); m_drawer->drawObject(m_surfaceShader, m_surfaceObj, m_gradientTexture, m_depthTexture); //m_drawer->drawObject(m_selectionShader, m_surfaceObj, m_selectionTexture, 0); // IFDEF print selection @@ -423,11 +423,11 @@ void Surface3dRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH QMatrix4x4 itModelMatrix; modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp); - modelMatrix.scale(QVector3D( m_xLength / m_scaleFactor, + modelMatrix.scale(QVector3D(m_xLength / m_scaleFactor, 1.0f, m_zLength / m_scaleFactor)); modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f); - itModelMatrix.scale(QVector3D( m_xLength / m_scaleFactor, + itModelMatrix.scale(QVector3D(m_xLength / m_scaleFactor, 1.0f, m_zLength / m_scaleFactor)); @@ -527,7 +527,7 @@ void Surface3dRenderer::updateSurfaceGradient() pmp.setPen(Qt::NoPen); pmp.drawRect(0, 0, 4, 100); -// QImage image(QStringLiteral("C:\\Users\\misalmel\\Work\\gerrit\\qtdatavis3d_2\\grid.png")); + // QImage image(QStringLiteral("C:\\Users\\misalmel\\Work\\gerrit\\qtdatavis3d_2\\grid.png")); if (m_gradientTexture) { m_textureHelper->deleteTexture(&m_gradientTexture); @@ -649,13 +649,13 @@ void Surface3dRenderer::setSeries(QList series) void Surface3dRenderer::calculateSceneScalingFactors() { // Calculate scene scaling and translation factors -// m_rowWidth = ((m_columnCount + 1) * m_barSpacing.width()) / 2.0f; -// m_columnDepth = ((m_rowCount + 1) * m_barSpacing.height()) / 2.0f; -// m_maxDimension = qMax(m_rowWidth, m_columnDepth); -// m_scaleFactor = qMin((m_columnCount * (m_maxDimension / m_maxSceneSize)), -// (m_rowCount * (m_maxDimension / m_maxSceneSize))); -// m_scaleX = m_barThickness.width() / m_scaleFactor; -// m_scaleZ = m_barThickness.height() / m_scaleFactor; + // m_rowWidth = ((m_columnCount + 1) * m_barSpacing.width()) / 2.0f; + // m_columnDepth = ((m_rowCount + 1) * m_barSpacing.height()) / 2.0f; + // m_maxDimension = qMax(m_rowWidth, m_columnDepth); + // m_scaleFactor = qMin((m_columnCount * (m_maxDimension / m_maxSceneSize)), + // (m_rowCount * (m_maxDimension / m_maxSceneSize))); + // m_scaleX = m_barThickness.width() / m_scaleFactor; + // m_scaleZ = m_barThickness.height() / m_scaleFactor; m_xLength = m_segmentXCount; m_zLength = m_segmentZCount; @@ -812,30 +812,30 @@ void Surface3dRenderer::updateDepthBuffer() m_shadowQuality); if (!m_depthTexture) { qDebug() << "Failed to create m_depthTexture"; -// switch (m_shadowQuality) { -// case ShadowHigh: -// qWarning("Creating high quality shadows failed. Changing to medium quality."); -// (void)setShadowQuality(ShadowMedium); -// break; -// case ShadowMedium: -// qWarning("Creating medium quality shadows failed. Changing to low quality."); -// (void)setShadowQuality(ShadowLow); -// break; -// case ShadowLow: -// qWarning("Creating low quality shadows failed. Switching shadows off."); -// (void)setShadowQuality(ShadowNone); -// break; -// default: -// // You'll never get here -// break; -// } + // switch (m_shadowQuality) { + // case ShadowHigh: + // qWarning("Creating high quality shadows failed. Changing to medium quality."); + // (void)setShadowQuality(ShadowMedium); + // break; + // case ShadowMedium: + // qWarning("Creating medium quality shadows failed. Changing to low quality."); + // (void)setShadowQuality(ShadowLow); + // break; + // case ShadowLow: + // qWarning("Creating low quality shadows failed. Switching shadows off."); + // (void)setShadowQuality(ShadowNone); + // break; + // default: + // // You'll never get here + // break; + // } } } } #endif void Surface3dRenderer::initBackgroundShaders(const QString &vertexShader, - const QString &fragmentShader) + const QString &fragmentShader) { if (m_backgroundShader) delete m_backgroundShader; diff --git a/src/datavis3dqml2/declarativebars.cpp b/src/datavis3dqml2/declarativebars.cpp index 0b4196cd..938575f5 100644 --- a/src/datavis3dqml2/declarativebars.cpp +++ b/src/datavis3dqml2/declarativebars.cpp @@ -69,9 +69,6 @@ void DeclarativeBars::componentComplete() QSGNode *DeclarativeBars::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { - // Call initialize on each update paint node and let the shared code worry about it. - m_shared->initializeOpenGL(); - // If old node exists and has right size, reuse it. if (oldNode && m_initialisedSize == boundingRect().size().toSize()) { // Update bounding rectangle (that has same size as before). diff --git a/src/datavis3dqml2/declarativebars_p.h b/src/datavis3dqml2/declarativebars_p.h index 169de795..bcb8bb83 100644 --- a/src/datavis3dqml2/declarativebars_p.h +++ b/src/datavis3dqml2/declarativebars_p.h @@ -37,6 +37,7 @@ #include #include #include +#include QT_DATAVIS3D_BEGIN_NAMESPACE @@ -76,7 +77,7 @@ public: void classBegin(); void componentComplete(); - // how many samples per row and column + // how many samples per row and column Q_INVOKABLE void setupSampleSpace(int rowCount, int columnCount); // Set color if you don't want to use themes. Set uniform to false if you want the (height) diff --git a/src/datavis3dqml2/declarativebarsrenderer.cpp b/src/datavis3dqml2/declarativebarsrenderer.cpp index 757824aa..1ecd4003 100644 --- a/src/datavis3dqml2/declarativebarsrenderer.cpp +++ b/src/datavis3dqml2/declarativebarsrenderer.cpp @@ -29,7 +29,8 @@ DeclarativeBarsRenderer::DeclarativeBarsRenderer(QQuickWindow *window, Bars3dCon m_window(window), m_barsRenderer(renderer) { - connect(m_window, SIGNAL(beforeRendering()), this, SLOT(render()), Qt::DirectConnection); + connect(m_window, SIGNAL(beforeSynchronizing()), this, SLOT(synchDataToRenderer()), Qt::DirectConnection); + connect(m_window, SIGNAL(beforeRendering()), this, SLOT(renderFBO()), Qt::DirectConnection); } DeclarativeBarsRenderer::~DeclarativeBarsRenderer() @@ -38,7 +39,13 @@ DeclarativeBarsRenderer::~DeclarativeBarsRenderer() delete m_fbo; } -void DeclarativeBarsRenderer::render() +void DeclarativeBarsRenderer::synchDataToRenderer() +{ + m_barsRenderer->initializeOpenGL(); + m_barsRenderer->synchDataToRenderer(); +} + +void DeclarativeBarsRenderer::renderFBO() { QSize size = rect().size().toSize(); diff --git a/src/datavis3dqml2/declarativebarsrenderer_p.h b/src/datavis3dqml2/declarativebarsrenderer_p.h index 39449245..1b40d3df 100644 --- a/src/datavis3dqml2/declarativebarsrenderer_p.h +++ b/src/datavis3dqml2/declarativebarsrenderer_p.h @@ -48,7 +48,10 @@ public: ~DeclarativeBarsRenderer(); public slots: - void render(); + // Used to synch up data model from controller to renderer while main thread is locked + void synchDataToRenderer(); + // Renders view to FBO before render cycle starts. + void renderFBO(); private: QOpenGLFramebufferObject *m_fbo; diff --git a/src/datavis3dqml2/declarativemaps_p.h b/src/datavis3dqml2/declarativemaps_p.h index e395f4b8..ba2da0b3 100644 --- a/src/datavis3dqml2/declarativemaps_p.h +++ b/src/datavis3dqml2/declarativemaps_p.h @@ -69,7 +69,7 @@ public: // For example, in AdjustAll mode setting thickness to (0.1f, 1.0f, 0.5f) would apply value to // x at 10%, y at 100% and z at 50%. If a dimension is not included, given thickness states its absolute value. Q_INVOKABLE void setBarSpecs(const QVector3D &thickness = QVector3D(1.0f, 1.0f, 1.0f), - Q3DMaps::AdjustmentDirection direction = Q3DMaps::AdjustHeight); + Q3DMaps::AdjustmentDirection direction = Q3DMaps::AdjustHeight); // bar type; bars (=cubes), pyramids, cones, cylinders, balls, etc. Q_INVOKABLE void setBarType(QDataVis::MeshStyle style, bool smooth = false); diff --git a/src/datavis3dqml2/declarativescatter.cpp b/src/datavis3dqml2/declarativescatter.cpp index b896d3d9..e880e553 100644 --- a/src/datavis3dqml2/declarativescatter.cpp +++ b/src/datavis3dqml2/declarativescatter.cpp @@ -68,9 +68,6 @@ void DeclarativeScatter::componentComplete() QSGNode *DeclarativeScatter::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { - // Call initialize on each update paint node and let the shared code worry about it. - m_shared->initializeOpenGL(); - // If old node exists and has right size, reuse it. if (oldNode && m_initialisedSize == boundingRect().size().toSize()) { // Update bounding rectangle (that has same size as before). @@ -191,6 +188,10 @@ void DeclarativeScatter::setTheme(QDataVis::ColorTheme theme) // We need to save this locally, as there are no getters for it in controller m_theme = theme; m_shared->setColorTheme(theme); + + // TODO: Investigate why the beforeSynchronizing() signal requires update and is not sent automatically when this value changes, + // but is sent wen e.g. enable/disable background changes. + update(); } QDataVis::ColorTheme DeclarativeScatter::theme() diff --git a/src/datavis3dqml2/declarativescatterrenderer.cpp b/src/datavis3dqml2/declarativescatterrenderer.cpp index 220386ae..23c59c26 100644 --- a/src/datavis3dqml2/declarativescatterrenderer.cpp +++ b/src/datavis3dqml2/declarativescatterrenderer.cpp @@ -30,7 +30,8 @@ DeclarativeScatterRenderer::DeclarativeScatterRenderer(QQuickWindow *window, m_window(window), m_scatterRenderer(renderer) { - connect(m_window, SIGNAL(beforeRendering()), this, SLOT(render()), Qt::DirectConnection); + connect(m_window, SIGNAL(beforeSynchronizing()), this, SLOT(synchDataToRenderer()), Qt::DirectConnection); + connect(m_window, SIGNAL(beforeRendering()), this, SLOT(renderFBO()), Qt::DirectConnection); } DeclarativeScatterRenderer::~DeclarativeScatterRenderer() @@ -39,7 +40,13 @@ DeclarativeScatterRenderer::~DeclarativeScatterRenderer() delete m_fbo; } -void DeclarativeScatterRenderer::render() +void DeclarativeScatterRenderer::synchDataToRenderer() +{ + m_scatterRenderer->initializeOpenGL(); + m_scatterRenderer->synchDataToRenderer(); +} + +void DeclarativeScatterRenderer::renderFBO() { QSize size = rect().size().toSize(); diff --git a/src/datavis3dqml2/declarativescatterrenderer_p.h b/src/datavis3dqml2/declarativescatterrenderer_p.h index 811fbf5b..498b1d83 100644 --- a/src/datavis3dqml2/declarativescatterrenderer_p.h +++ b/src/datavis3dqml2/declarativescatterrenderer_p.h @@ -48,7 +48,10 @@ public: ~DeclarativeScatterRenderer(); public slots: - void render(); + // Used to synch up data model from controller to renderer while main thread is locked + void synchDataToRenderer(); + // Renders view to FBO before render cycle starts. + void renderFBO(); private: QOpenGLFramebufferObject *m_fbo; -- cgit v1.2.3