From 6368dd9a1d9e51016dcef9c93137526c07adcbeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Korpip=C3=A4=C3=A4?= Date: Thu, 15 May 2014 12:01:47 +0300 Subject: Dirty bits to custom item Task-number: QTRD-3082 Change-Id: I1503b067edcc677904ca16c1501109187809f98b Change-Id: I1503b067edcc677904ca16c1501109187809f98b Reviewed-by: Miikka Heikkinen --- .../customitems/customitemgraph.cpp | 23 ++++++++++ .../customitems/customitemgraph.h | 5 +++ src/datavisualization/data/customrenderitem_p.h | 5 +++ src/datavisualization/data/qcustom3ditem.cpp | 36 +++++++++++----- src/datavisualization/data/qcustom3ditem.h | 1 + src/datavisualization/data/qcustom3ditem_p.h | 24 +++++++++++ .../engine/abstract3dcontroller.cpp | 17 ++++++++ .../engine/abstract3dcontroller_p.h | 3 ++ .../engine/abstract3drenderer.cpp | 49 +++++++++++++++++++++- .../engine/abstract3drenderer_p.h | 2 + 10 files changed, 154 insertions(+), 11 deletions(-) diff --git a/examples/datavisualization/customitems/customitemgraph.cpp b/examples/datavisualization/customitems/customitemgraph.cpp index 14117580..56187d14 100644 --- a/examples/datavisualization/customitems/customitemgraph.cpp +++ b/examples/datavisualization/customitems/customitemgraph.cpp @@ -91,6 +91,11 @@ CustomItemGraph::CustomItemGraph(Q3DSurface *surface, QLabel *label) connect(m_graph, &QAbstract3DGraph::elementSelected, this, &CustomItemGraph::handleElementSelected); + + m_selectionAnimation = new QPropertyAnimation(this); + m_selectionAnimation->setPropertyName("scaling"); + m_selectionAnimation->setDuration(500); + m_selectionAnimation->setLoopCount(-1); } CustomItemGraph::~CustomItemGraph() @@ -118,6 +123,7 @@ void CustomItemGraph::toggleItemOne(bool show) m_graph->addCustomItem(item); //! [3] } else { + resetSelection(); //! [4] m_graph->removeCustomItemAt(positionOne); //! [4] @@ -138,6 +144,7 @@ void CustomItemGraph::toggleItemTwo(bool show) item->setTextureImage(color); m_graph->addCustomItem(item); } else { + resetSelection(); m_graph->removeCustomItemAt(positionTwo); } } @@ -156,6 +163,7 @@ void CustomItemGraph::toggleItemThree(bool show) item->setTextureImage(color); m_graph->addCustomItem(item); } else { + resetSelection(); m_graph->removeCustomItemAt(positionThree); } } @@ -196,15 +204,22 @@ void CustomItemGraph::toggleShadows(bool shadows) void CustomItemGraph::handleElementSelected(QAbstract3DGraph::ElementType type) { + resetSelection(); if (type == QAbstract3DGraph::ElementCustomItem) { int index = m_graph->selectedCustomItemIndex(); QCustom3DItem *item = m_graph->selectedCustomItem(); + m_previouslyAnimatedItem = item; + m_previousScaling = item->scaling(); QString text; text.setNum(index); text.append(": "); QStringList split = item->meshFile().split("/"); text.append(split.last()); m_textField->setText(text); + m_selectionAnimation->setTargetObject(item); + m_selectionAnimation->setStartValue(item->scaling()); + m_selectionAnimation->setEndValue(item->scaling() * 1.5f); + m_selectionAnimation->start(); } else if (type == QAbstract3DGraph::ElementSeries) { QString text = "Surface ("; QSurface3DSeries *series = m_graph->selectedSeries(); @@ -226,3 +241,11 @@ void CustomItemGraph::handleElementSelected(QAbstract3DGraph::ElementType type) m_textField->setText("Nothing"); } } + +void CustomItemGraph::resetSelection() +{ + m_selectionAnimation->stop(); + if (m_previouslyAnimatedItem) + m_previouslyAnimatedItem->setScaling(m_previousScaling); + m_previouslyAnimatedItem = 0; +} diff --git a/examples/datavisualization/customitems/customitemgraph.h b/examples/datavisualization/customitems/customitemgraph.h index aee32c62..e86d3910 100644 --- a/examples/datavisualization/customitems/customitemgraph.h +++ b/examples/datavisualization/customitems/customitemgraph.h @@ -25,6 +25,7 @@ #include #include #include +#include using namespace QtDataVisualization; @@ -44,10 +45,14 @@ public: private: void handleElementSelected(QAbstract3DGraph::ElementType type); + void resetSelection(); private: Q3DSurface *m_graph; QLabel *m_textField; + QPropertyAnimation *m_selectionAnimation; + QCustom3DItem *m_previouslyAnimatedItem; + QVector3D m_previousScaling; }; #endif diff --git a/src/datavisualization/data/customrenderitem_p.h b/src/datavisualization/data/customrenderitem_p.h index 70c162b7..3bf8067e 100644 --- a/src/datavisualization/data/customrenderitem_p.h +++ b/src/datavisualization/data/customrenderitem_p.h @@ -34,6 +34,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION +class QCustom3DItem; + class CustomRenderItem : public AbstractRenderItem { public: @@ -51,6 +53,8 @@ public: inline bool isBlendNeeded() { return m_needBlend; } inline void setVisible(bool visible) { m_visible = visible; } inline bool isVisible() { return m_visible; } + inline void setItemPointer(QCustom3DItem *item) { m_item = item; } + inline QCustom3DItem *itemPointer() { return m_item; } private: GLuint m_texture; @@ -58,6 +62,7 @@ private: ObjectHelper *m_object; bool m_needBlend; bool m_visible; + QCustom3DItem *m_item; }; typedef QVector CustomRenderItemArray; diff --git a/src/datavisualization/data/qcustom3ditem.cpp b/src/datavisualization/data/qcustom3ditem.cpp index 285f5a39..ca4cef16 100644 --- a/src/datavisualization/data/qcustom3ditem.cpp +++ b/src/datavisualization/data/qcustom3ditem.cpp @@ -123,7 +123,9 @@ void QCustom3DItem::setMeshFile(const QString &meshFile) { if (d_ptr->m_meshFile != meshFile) { d_ptr->m_meshFile = meshFile; + d_ptr->m_dirtyBits.meshDirty = true; emit meshFileChanged(meshFile); + emit d_ptr->needUpdate(); } } @@ -144,7 +146,9 @@ void QCustom3DItem::setPosition(const QVector3D &position) { if (d_ptr->m_position != position) { d_ptr->m_position = position; + d_ptr->m_dirtyBits.positionDirty = true; emit positionChanged(position); + emit d_ptr->needUpdate(); } } @@ -161,7 +165,9 @@ void QCustom3DItem::setScaling(const QVector3D &scaling) { if (d_ptr->m_scaling != scaling) { d_ptr->m_scaling = scaling; + d_ptr->m_dirtyBits.scalingDirty = true; emit scalingChanged(scaling); + emit d_ptr->needUpdate(); } } @@ -178,7 +184,9 @@ void QCustom3DItem::setRotation(const QQuaternion &rotation) { if (d_ptr->m_rotation != rotation) { d_ptr->m_rotation = rotation; + d_ptr->m_dirtyBits.rotationDirty = true; emit rotationChanged(rotation); + emit d_ptr->needUpdate(); } } @@ -195,7 +203,9 @@ void QCustom3DItem::setVisible(bool visible) { if (d_ptr->m_visible != visible) { d_ptr->m_visible = visible; + d_ptr->m_dirtyBits.visibleDirty = true; emit visibleChanged(visible); + emit d_ptr->needUpdate(); } } @@ -219,17 +229,21 @@ void QCustom3DItem::setRotationAxisAndAngle(const QVector3D &axis, float angle) */ void QCustom3DItem::setTextureImage(const QImage &textureImage) { - if (textureImage.isNull()) { - // Make a solid gray texture - d_ptr->m_textureImage = QImage(2, 2, QImage::Format_RGB32); - d_ptr->m_textureImage.fill(Qt::gray); - } else { - d_ptr->m_textureImage = textureImage; - } + if (textureImage != d_ptr->m_textureImage) { + if (textureImage.isNull()) { + // Make a solid gray texture + d_ptr->m_textureImage = QImage(2, 2, QImage::Format_RGB32); + d_ptr->m_textureImage.fill(Qt::gray); + } else { + d_ptr->m_textureImage = textureImage; + } - if (!d_ptr->m_textureFile.isEmpty()) { - d_ptr->m_textureFile.clear(); - emit textureFileChanged(d_ptr->m_textureFile); + if (!d_ptr->m_textureFile.isEmpty()) { + d_ptr->m_textureFile.clear(); + emit textureFileChanged(d_ptr->m_textureFile); + } + d_ptr->m_dirtyBits.textureDirty = true; + emit d_ptr->needUpdate(); } } @@ -249,6 +263,8 @@ void QCustom3DItem::setTextureFile(const QString &textureFile) d_ptr->m_textureImage.fill(Qt::gray); } emit textureFileChanged(textureFile); + d_ptr->m_dirtyBits.textureDirty = true; + emit d_ptr->needUpdate(); } } diff --git a/src/datavisualization/data/qcustom3ditem.h b/src/datavisualization/data/qcustom3ditem.h index c9d0cd63..77e33404 100644 --- a/src/datavisualization/data/qcustom3ditem.h +++ b/src/datavisualization/data/qcustom3ditem.h @@ -82,6 +82,7 @@ private: Q_DISABLE_COPY(QCustom3DItem) friend class Abstract3DRenderer; + friend class Abstract3DController; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qcustom3ditem_p.h b/src/datavisualization/data/qcustom3ditem_p.h index f85ec5bf..89f47501 100644 --- a/src/datavisualization/data/qcustom3ditem_p.h +++ b/src/datavisualization/data/qcustom3ditem_p.h @@ -33,6 +33,25 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION +struct QCustomItemDirtyBitField { + bool textureDirty : 1; + bool meshDirty : 1; + bool positionDirty : 1; + bool scalingDirty : 1; + bool rotationDirty : 1; + bool visibleDirty : 1; + + QCustomItemDirtyBitField() + : textureDirty(false), + meshDirty(false), + positionDirty(false), + scalingDirty(false), + rotationDirty(false), + visibleDirty(false) + { + } +}; + class QCustom3DItemPrivate : public QObject { Q_OBJECT @@ -55,6 +74,11 @@ public: QQuaternion m_rotation; bool m_visible; + QCustomItemDirtyBitField m_dirtyBits; + +signals: + void needUpdate(); + private: friend class QCustom3DItem; }; diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 78ac135b..473ad34c 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -32,6 +32,7 @@ #include "q3dtheme_p.h" #include "q3dscene_p.h" #include "q3dscene.h" +#include "qcustom3ditem_p.h" #include #include @@ -52,6 +53,7 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen m_renderer(0), m_isDataDirty(true), m_isCustomDataDirty(true), + m_isCustomItemDirty(true), m_isSeriesVisualsDirty(true), m_renderPending(false), m_measureFps(false), @@ -411,6 +413,11 @@ void Abstract3DController::synchDataToRenderer() m_renderer->updateCustomData(m_customItems); m_isCustomDataDirty = false; } + + if (m_isCustomItemDirty) { + m_renderer->updateCustomItems(); + m_isCustomItemDirty = false; + } } void Abstract3DController::render(const GLuint defaultFboHandle) @@ -874,6 +881,8 @@ int Abstract3DController::addCustomItem(QCustom3DItem *item) return index; item->setParent(this); + connect(item->d_ptr.data(), &QCustom3DItemPrivate::needUpdate, + this, &Abstract3DController::updateCustomItem); m_customItems.append(item); m_isCustomDataDirty = true; emitNeedRender(); @@ -914,6 +923,8 @@ void Abstract3DController::deleteCustomItem(const QVector3D &position) void Abstract3DController::releaseCustomItem(QCustom3DItem *item) { if (item && m_customItems.contains(item)) { + disconnect(item->d_ptr.data(), &QCustom3DItemPrivate::needUpdate, + this, &Abstract3DController::updateCustomItem); m_customItems.removeOne(item); item->setParent(0); m_isCustomDataDirty = true; @@ -921,6 +932,12 @@ void Abstract3DController::releaseCustomItem(QCustom3DItem *item) } } +void Abstract3DController::updateCustomItem() +{ + m_isCustomItemDirty = true; + emitNeedRender(); +} + void Abstract3DController::handleAxisTitleChanged(const QString &title) { Q_UNUSED(title) diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index 79320c25..bd78b6fa 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -166,6 +166,7 @@ protected: Abstract3DRenderer *m_renderer; bool m_isDataDirty; bool m_isCustomDataDirty; + bool m_isCustomItemDirty; bool m_isSeriesVisualsDirty; bool m_renderPending; @@ -311,6 +312,8 @@ public slots: inline bool measureFps() const { return m_measureFps; } inline qreal currentFps() const { return m_currentFps; } + void updateCustomItem(); + signals: void shadowQualityChanged(QAbstract3DGraph::ShadowQuality quality); void activeInputHandlerChanged(QAbstract3DInputHandler *inputHandler); diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 6dcc46df..920b8cf0 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -427,6 +427,14 @@ void Abstract3DRenderer::updateCustomData(const QList &customIt addCustomItem(item); } +void Abstract3DRenderer::updateCustomItems() +{ + // Check all items + // TODO: Call updateCustomItem in a loop, as we can probably utilize the same function in updateCustomData when doing QTRD-3056 + foreach (CustomRenderItem *item, m_customRenderCache) + updateCustomItem(item); +} + SeriesRenderCache *Abstract3DRenderer::createNewCache(QAbstract3DSeries *series) { return new SeriesRenderCache(series, this); @@ -538,8 +546,10 @@ QVector4D Abstract3DRenderer::indexToSelectionColor(GLint index) return QVector4D(idxRed, idxGreen, idxBlue, 0); } -void Abstract3DRenderer::addCustomItem(QCustom3DItem *item) { +void Abstract3DRenderer::addCustomItem(QCustom3DItem *item) +{ CustomRenderItem *newItem = new CustomRenderItem(); + newItem->setItemPointer(item); // Store pointer for render item updates newItem->setMesh(item->meshFile()); newItem->setScaling(item->scaling()); newItem->setRotation(item->rotation()); @@ -555,6 +565,43 @@ void Abstract3DRenderer::addCustomItem(QCustom3DItem *item) { m_customRenderCache.append(newItem); } +void Abstract3DRenderer::updateCustomItem(CustomRenderItem *renderItem) +{ + QCustom3DItem *item = renderItem->itemPointer(); + if (item->d_ptr->m_dirtyBits.meshDirty) { + renderItem->setMesh(item->meshFile()); + item->d_ptr->m_dirtyBits.meshDirty = false; + } + if (item->d_ptr->m_dirtyBits.scalingDirty) { + renderItem->setScaling(item->scaling()); + item->d_ptr->m_dirtyBits.scalingDirty = false; + } + if (item->d_ptr->m_dirtyBits.rotationDirty) { + renderItem->setRotation(item->rotation()); + item->d_ptr->m_dirtyBits.rotationDirty = false; + } + if (item->d_ptr->m_dirtyBits.textureDirty) { + QImage textureImage = item->d_ptr->textureImage(); + renderItem->setBlendNeeded(textureImage.hasAlphaChannel()); + GLuint oldTexture = renderItem->texture(); + m_textureHelper->deleteTexture(&oldTexture); + GLuint texture = m_textureHelper->create2DTexture(textureImage, true, true, true); + renderItem->setTexture(texture); + // TODO: Uncomment this once custom item render cache handling has been optimized (QTRD-3056) + //item->d_ptr->clearTextureImage(); + item->d_ptr->m_dirtyBits.textureDirty = false; + } + if (item->d_ptr->m_dirtyBits.positionDirty) { + QVector3D translation = convertPositionToTranslation(item->position()); + renderItem->setTranslation(translation); + item->d_ptr->m_dirtyBits.positionDirty = false; + } + if (item->d_ptr->m_dirtyBits.visibleDirty) { + renderItem->setVisible(item->isVisible()); + item->d_ptr->m_dirtyBits.visibleDirty = false; + } +} + void Abstract3DRenderer::drawCustomItems(RenderingState state, ShaderHelper *shader, const QMatrix4x4 &viewMatrix, diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 5063f506..949ba104 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -68,6 +68,7 @@ public: virtual void updateData() = 0; virtual void updateSeries(const QList &seriesList); virtual void updateCustomData(const QList &customItems); + virtual void updateCustomItems(); virtual SeriesRenderCache *createNewCache(QAbstract3DSeries *series); virtual void cleanCache(SeriesRenderCache *cache); virtual void render(GLuint defaultFboHandle); @@ -112,6 +113,7 @@ public: virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); virtual void addCustomItem(QCustom3DItem *item); + virtual void updateCustomItem(CustomRenderItem *renderItem); virtual QVector3D convertPositionToTranslation(const QVector3D &position) = 0; -- cgit v1.2.3