summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/datavisualization/data/barrenderitem.cpp5
-rw-r--r--src/datavisualization/data/barrenderitem_p.h6
-rw-r--r--src/datavisualization/data/qabstract3dseries_p.h4
-rw-r--r--src/datavisualization/data/scatterrenderitem.cpp4
-rw-r--r--src/datavisualization/engine/abstract3dcontroller.cpp21
-rw-r--r--src/datavisualization/engine/abstract3dcontroller_p.h4
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp83
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h9
-rw-r--r--src/datavisualization/engine/bars3dcontroller.cpp17
-rw-r--r--src/datavisualization/engine/bars3dcontroller_p.h3
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp1090
-rw-r--r--src/datavisualization/engine/bars3drenderer_p.h16
-rw-r--r--src/datavisualization/engine/barseriesrendercache.cpp43
-rw-r--r--src/datavisualization/engine/barseriesrendercache_p.h61
-rw-r--r--src/datavisualization/engine/engine.pri8
-rw-r--r--src/datavisualization/engine/scatter3dcontroller.cpp36
-rw-r--r--src/datavisualization/engine/scatter3dcontroller_p.h3
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp733
-rw-r--r--src/datavisualization/engine/scatter3drenderer_p.h16
-rw-r--r--src/datavisualization/engine/scatterseriesrendercache.cpp43
-rw-r--r--src/datavisualization/engine/scatterseriesrendercache_p.h62
-rw-r--r--src/datavisualization/engine/seriesrendercache.cpp88
-rw-r--r--src/datavisualization/engine/seriesrendercache_p.h13
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp45
-rw-r--r--src/datavisualization/engine/surface3dcontroller_p.h4
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp215
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h13
-rw-r--r--src/datavisualization/engine/surfaceseriesrendercache.cpp28
-rw-r--r--src/datavisualization/engine/surfaceseriesrendercache_p.h17
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp2
-rw-r--r--tests/barstest/chart.cpp64
-rw-r--r--tests/barstest/chart.h2
-rw-r--r--tests/barstest/main.cpp6
-rw-r--r--tests/scattertest/main.cpp6
-rw-r--r--tests/scattertest/scatterchart.cpp6
-rw-r--r--tests/scattertest/scatterchart.h1
-rw-r--r--tests/surfacetest/graphmodifier.cpp38
-rw-r--r--tests/surfacetest/graphmodifier.h2
-rw-r--r--tests/surfacetest/main.cpp12
39 files changed, 1619 insertions, 1210 deletions
diff --git a/src/datavisualization/data/barrenderitem.cpp b/src/datavisualization/data/barrenderitem.cpp
index 50d2a4b4..2d9d3daa 100644
--- a/src/datavisualization/data/barrenderitem.cpp
+++ b/src/datavisualization/data/barrenderitem.cpp
@@ -24,8 +24,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
BarRenderItem::BarRenderItem()
: AbstractRenderItem(),
m_value(0),
- m_height(0.0f),
- m_seriesIndex(0)
+ m_height(0.0f)
{
}
@@ -35,7 +34,6 @@ BarRenderItem::BarRenderItem(const BarRenderItem &other)
m_value = other.m_value;
m_position = other.m_position;
m_height = other.m_height;
- m_seriesIndex = other.m_seriesIndex;
}
BarRenderItem::~BarRenderItem()
@@ -67,7 +65,6 @@ void BarRenderSliceItem::setItem(const BarRenderItem &renderItem)
m_value = renderItem.value();
m_position = renderItem.position();
m_height = renderItem.height();
- m_seriesIndex = renderItem.seriesIndex();
m_sliceLabel = QString();
m_sliceLabelItem = 0;
}
diff --git a/src/datavisualization/data/barrenderitem_p.h b/src/datavisualization/data/barrenderitem_p.h
index 1122053d..97c069e2 100644
--- a/src/datavisualization/data/barrenderitem_p.h
+++ b/src/datavisualization/data/barrenderitem_p.h
@@ -54,16 +54,10 @@ public:
inline void setHeight(GLfloat height) { m_height = height; }
inline GLfloat height() const { return m_height; }
- // Series index in visual series that this item belongs to.
- // This is only utilized by slicing, so it may not be up to date on all items.
- inline void setSeriesIndex(int seriesIndex) { m_seriesIndex = seriesIndex; }
- inline int seriesIndex() const { return m_seriesIndex; }
-
protected:
float m_value;
QPoint m_position; // x = row, y = column
GLfloat m_height;
- int m_seriesIndex;
friend class QBarDataItem;
};
diff --git a/src/datavisualization/data/qabstract3dseries_p.h b/src/datavisualization/data/qabstract3dseries_p.h
index 530afe5e..e62543af 100644
--- a/src/datavisualization/data/qabstract3dseries_p.h
+++ b/src/datavisualization/data/qabstract3dseries_p.h
@@ -52,6 +52,7 @@ struct QAbstract3DSeriesChangeBitField {
bool nameChanged : 1;
bool itemLabelChanged : 1;
bool itemLabelVisibilityChanged : 1;
+ bool visibilityChanged : 1;
QAbstract3DSeriesChangeBitField()
: meshChanged(true),
@@ -67,7 +68,8 @@ struct QAbstract3DSeriesChangeBitField {
multiHighlightGradientChanged(true),
nameChanged(true),
itemLabelChanged(true),
- itemLabelVisibilityChanged(true)
+ itemLabelVisibilityChanged(true),
+ visibilityChanged(true)
{
}
};
diff --git a/src/datavisualization/data/scatterrenderitem.cpp b/src/datavisualization/data/scatterrenderitem.cpp
index 3b2e64c5..33df4d28 100644
--- a/src/datavisualization/data/scatterrenderitem.cpp
+++ b/src/datavisualization/data/scatterrenderitem.cpp
@@ -29,10 +29,10 @@ ScatterRenderItem::ScatterRenderItem()
}
ScatterRenderItem::ScatterRenderItem(const ScatterRenderItem &other)
- : AbstractRenderItem(other),
- m_visible(false)
+ : AbstractRenderItem(other)
{
m_position = other.m_position;
+ m_visible = other.m_visible;
}
ScatterRenderItem::~ScatterRenderItem()
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp
index 9283ccb4..885904d4 100644
--- a/src/datavisualization/engine/abstract3dcontroller.cpp
+++ b/src/datavisualization/engine/abstract3dcontroller.cpp
@@ -50,7 +50,6 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen
m_axisZ(0),
m_renderer(0),
m_isDataDirty(true),
- m_isSeriesVisibilityDirty(true),
m_isSeriesVisualsDirty(true),
m_renderPending(false),
m_measureFps(false),
@@ -146,7 +145,7 @@ void Abstract3DController::removeSeries(QAbstract3DSeries *series)
this, &Abstract3DController::handleSeriesVisibilityChanged);
series->d_ptr->setController(0);
m_isDataDirty = true;
- m_isSeriesVisibilityDirty = true;
+ m_isSeriesVisualsDirty = true;
emitNeedRender();
}
}
@@ -354,9 +353,13 @@ void Abstract3DController::synchDataToRenderer()
}
}
- if (m_isSeriesVisibilityDirty || m_isSeriesVisualsDirty) {
- m_renderer->updateSeries(m_seriesList, m_isSeriesVisibilityDirty);
- m_isSeriesVisibilityDirty = false;
+ if (m_changedSeriesList.size()) {
+ m_renderer->modifiedSeriesList(m_changedSeriesList);
+ m_changedSeriesList.clear();
+ }
+
+ if (m_isSeriesVisualsDirty) {
+ m_renderer->updateSeries(m_seriesList);
m_isSeriesVisualsDirty = false;
}
@@ -1018,10 +1021,14 @@ void Abstract3DController::handleAxisFormatterDirtyBySender(QObject *sender)
void Abstract3DController::handleSeriesVisibilityChangedBySender(QObject *sender)
{
- Q_UNUSED(sender)
+ QAbstract3DSeries *series = static_cast<QAbstract3DSeries *>(sender);
+ series->d_ptr->m_changeTracker.visibilityChanged = true;
m_isDataDirty = true;
- m_isSeriesVisibilityDirty = true;
+ m_isSeriesVisualsDirty = true;
+
+ adjustAxisRanges();
+
emitNeedRender();
}
diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h
index f18ed452..4f597769 100644
--- a/src/datavisualization/engine/abstract3dcontroller_p.h
+++ b/src/datavisualization/engine/abstract3dcontroller_p.h
@@ -155,7 +155,6 @@ protected:
QList<QAbstract3DAxis *> m_axes; // List of all added axes
Abstract3DRenderer *m_renderer;
bool m_isDataDirty;
- bool m_isSeriesVisibilityDirty;
bool m_isSeriesVisualsDirty;
bool m_renderPending;
@@ -166,6 +165,8 @@ protected:
int m_numFrames;
qreal m_currentFps;
+ QVector<QAbstract3DSeries *> m_changedSeriesList;
+
explicit Abstract3DController(QRect initialViewport, Q3DScene *scene, QObject *parent = 0);
public:
@@ -247,6 +248,7 @@ public:
virtual void handleAxisFormatterDirtyBySender(QObject *sender);
virtual void handleSeriesVisibilityChangedBySender(QObject *sender);
virtual void handlePendingClick() = 0;
+ virtual void adjustAxisRanges() = 0;
void markSeriesItemLabelsDirty();
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
index 0b8ac8d1..f70d128b 100644
--- a/src/datavisualization/engine/abstract3drenderer.cpp
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -47,7 +47,8 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
m_clickPending(false),
m_clickedSeries(0),
m_clickedType(QAbstract3DGraph::ElementNone),
- m_selectionLabelItem(0)
+ m_selectionLabelItem(0),
+ m_visibleSeriesCount(0)
{
QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures);
@@ -59,14 +60,17 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
Abstract3DRenderer::~Abstract3DRenderer()
{
- for (int i = 0; i < m_visibleSeriesList.size(); i++)
- m_visibleSeriesList[i].cleanup(m_textureHelper);
-
delete m_drawer;
delete m_textureHelper;
delete m_cachedScene;
delete m_cachedTheme;
delete m_selectionLabelItem;
+
+ foreach (SeriesRenderCache *cache, m_renderCacheList) {
+ cache->cleanup(m_textureHelper);
+ delete cache;
+ }
+ m_renderCacheList.clear();
}
void Abstract3DRenderer::initializeOpenGL()
@@ -285,6 +289,9 @@ void Abstract3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orient
AxisRenderCache &cache = axisCacheForOrientation(orientation);
cache.setMin(min);
cache.setMax(max);
+
+ foreach (SeriesRenderCache *cache, m_renderCacheList)
+ cache->setDataDirty(true);
}
void Abstract3DRenderer::updateAxisSegmentCount(QAbstract3DAxis::AxisOrientation orientation,
@@ -318,6 +325,18 @@ void Abstract3DRenderer::updateAxisFormatter(QAbstract3DAxis::AxisOrientation or
}
formatter->d_ptr->populateCopy(*(cache.formatter()));
cache.markPositionsDirty();
+
+ foreach (SeriesRenderCache *cache, m_renderCacheList)
+ cache->setDataDirty(true);
+}
+
+void Abstract3DRenderer::modifiedSeriesList(const QVector<QAbstract3DSeries *> &seriesList)
+{
+ foreach (QAbstract3DSeries *series, seriesList) {
+ SeriesRenderCache *cache = m_renderCacheList.value(series, 0);
+ if (cache)
+ cache->setDataDirty(true);
+ }
}
void Abstract3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh)
@@ -327,33 +346,45 @@ void Abstract3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::M
Q_UNUSED(mesh)
}
-void Abstract3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList,
- bool updateVisibility)
+void Abstract3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList)
{
- int visibleCount = 0;
- if (updateVisibility) {
- int oldSize = m_visibleSeriesList.size();
- foreach (QAbstract3DSeries *current, seriesList) {
- if (current->isVisible())
- visibleCount++;
+ foreach (SeriesRenderCache *cache, m_renderCacheList)
+ cache->setValid(false);
+
+ m_visibleSeriesCount = 0;
+ int seriesCount = seriesList.size();
+ for (int i = 0; i < seriesCount; i++) {
+ QAbstract3DSeries *series = seriesList.at(i);
+ SeriesRenderCache *cache = m_renderCacheList.value(series);
+ bool newSeries = false;
+ if (!cache) {
+ cache = createNewCache(series);
+ m_renderCacheList[series] = cache;
+ newSeries = true;
}
+ cache->setValid(true);
+ cache->populate(newSeries);
+ if (cache->isVisible())
+ m_visibleSeriesCount++;
+ }
- // Clean up series caches that are about to be permanently deleted.
- // Can't just use cache destructor, as resize will call that to all items.
- if (visibleCount < oldSize) {
- for (int i = visibleCount; i < oldSize; i++)
- m_visibleSeriesList[i].cleanup(m_textureHelper);
- }
+ // Remove non-valid objects from the cache list
+ foreach (SeriesRenderCache *cache, m_renderCacheList) {
+ if (!cache->isValid())
+ cleanCache(cache);
+ }
+}
- if (visibleCount != oldSize)
- m_visibleSeriesList.resize(visibleCount);
+SeriesRenderCache *Abstract3DRenderer::createNewCache(QAbstract3DSeries *series)
+{
+ return new SeriesRenderCache(series, this);
+}
- visibleCount = 0;
- }
- foreach (QAbstract3DSeries *current, seriesList) {
- if (current->isVisible())
- m_visibleSeriesList[visibleCount++].populate(current, this);
- }
+void Abstract3DRenderer::cleanCache(SeriesRenderCache *cache)
+{
+ m_renderCacheList.remove(cache->series());
+ cache->cleanup(m_textureHelper);
+ delete cache;
}
AxisRenderCache &Abstract3DRenderer::axisCacheForOrientation(
diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h
index f5ca8d02..ce21deff 100644
--- a/src/datavisualization/engine/abstract3drenderer_p.h
+++ b/src/datavisualization/engine/abstract3drenderer_p.h
@@ -61,8 +61,9 @@ public:
virtual ~Abstract3DRenderer();
virtual void updateData() = 0;
- virtual void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility);
-
+ virtual void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
+ virtual SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
+ virtual void cleanCache(SeriesRenderCache *cache);
virtual void render(GLuint defaultFboHandle);
virtual void updateTheme(Q3DTheme *theme);
@@ -96,6 +97,7 @@ public:
const QString &format);
virtual void updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation,
QValue3DAxisFormatter *formatter);
+ virtual void modifiedSeriesList(const QVector<QAbstract3DSeries *> &seriesList);
virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh);
void generateBaseColorTexture(const QColor &color, GLuint *texture);
@@ -147,7 +149,7 @@ protected:
bool m_selectionDirty;
SelectionState m_selectionState;
QPoint m_inputPosition;
- QVector<SeriesRenderCache> m_visibleSeriesList;
+ QHash<QAbstract3DSeries *, SeriesRenderCache *> m_renderCacheList;
QRect m_primarySubViewport;
QRect m_secondarySubViewport;
float m_devicePixelRatio;
@@ -158,6 +160,7 @@ protected:
QString m_selectionLabel;
LabelItem *m_selectionLabelItem;
+ int m_visibleSeriesCount;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp
index 49b6f383..38870115 100644
--- a/src/datavisualization/engine/bars3dcontroller.cpp
+++ b/src/datavisualization/engine/bars3dcontroller.cpp
@@ -108,6 +108,8 @@ void Bars3DController::handleArrayReset()
m_isDataDirty = true;
series->d_ptr->markItemLabelDirty();
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
// Clear selection unless still valid
setSelectedBar(m_selectedBar, m_selectedBarSeries, false);
emitNeedRender();
@@ -122,6 +124,8 @@ void Bars3DController::handleRowsAdded(int startIndex, int count)
adjustAxisRanges();
m_isDataDirty = true;
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
@@ -135,6 +139,8 @@ void Bars3DController::handleRowsChanged(int startIndex, int count)
m_isDataDirty = true;
series->d_ptr->markItemLabelDirty();
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
@@ -161,6 +167,8 @@ void Bars3DController::handleRowsRemoved(int startIndex, int count)
adjustAxisRanges();
m_isDataDirty = true;
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
@@ -183,6 +191,8 @@ void Bars3DController::handleRowsInserted(int startIndex, int count)
adjustAxisRanges();
m_isDataDirty = true;
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
@@ -197,6 +207,8 @@ void Bars3DController::handleItemChanged(int rowIndex, int columnIndex)
m_isDataDirty = true;
series->d_ptr->markItemLabelDirty();
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
@@ -240,8 +252,6 @@ void Bars3DController::handleSeriesVisibilityChangedBySender(QObject *sender)
{
Abstract3DController::handleSeriesVisibilityChangedBySender(sender);
- adjustAxisRanges();
-
// Visibility changes may require disabling slicing,
// so just reset selection to ensure everything is still valid.
setSelectedBar(m_selectedBar, m_selectedBarSeries, false);
@@ -341,9 +351,6 @@ void Bars3DController::insertSeries(int index, QAbstract3DSeries *series)
Abstract3DController::insertSeries(index, series);
if (oldSize != m_seriesList.size()) {
- if (series->isVisible())
- adjustAxisRanges();
-
QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(series);
if (!oldSize) {
m_primarySeries = barSeries;
diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h
index 9ea59c89..33928306 100644
--- a/src/datavisualization/engine/bars3dcontroller_p.h
+++ b/src/datavisualization/engine/bars3dcontroller_p.h
@@ -118,6 +118,7 @@ public:
virtual QList<QBar3DSeries *> barSeriesList();
virtual void handleAxisRangeChangedBySender(QObject *sender);
+ virtual void adjustAxisRanges();
public slots:
void handleArrayReset();
@@ -137,11 +138,9 @@ protected:
virtual QAbstract3DAxis *createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation);
private:
- void adjustAxisRanges();
void adjustSelectionPosition(QPoint &pos, const QBar3DSeries *series);
Q_DISABLE_COPY(Bars3DController)
-
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index 46df6464..6102adde 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -27,6 +27,7 @@
#include "qbardataitem.h"
#include "q3dlight.h"
#include "qbar3dseries_p.h"
+#include "barseriesrendercache_p.h"
#include <QtGui/QMatrix4x4>
#include <QtGui/QMouseEvent>
@@ -83,17 +84,18 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
m_scaleFactor(0),
m_maxSceneSize(40.0f),
m_visualSelectedBarPos(Bars3DController::invalidSelectionPosition()),
- m_visualSelectedBarSeriesIndex(-1),
m_resetCameraBaseOrientation(true),
m_selectedBarPos(Bars3DController::invalidSelectionPosition()),
- m_selectedBarSeries(0),
+ m_selectedSeriesCache(0),
m_noZeroInRange(false),
m_seriesScaleX(0.0f),
m_seriesScaleZ(0.0f),
m_seriesStep(0.0f),
m_seriesStart(0.0f),
m_clickedPosition(Bars3DController::invalidSelectionPosition()),
- m_keepSeriesUniform(false)
+ m_keepSeriesUniform(false),
+ m_haveUniformColorSeries(false),
+ m_haveGradientSeries(false)
{
m_axisCacheY.setScale(2.0f);
m_axisCacheY.setTranslate(-1.0f);
@@ -151,7 +153,6 @@ void Bars3DRenderer::initializeOpenGL()
void Bars3DRenderer::updateData()
{
- int seriesCount = m_visibleSeriesList.size();
int minRow = m_axisCacheZ.min();
int maxRow = m_axisCacheZ.max();
int minCol = m_axisCacheX.min();
@@ -162,12 +163,9 @@ void Bars3DRenderer::updateData()
int dataRowCount = 0;
int maxDataRowCount = 0;
- if (m_renderingArrays.size() != seriesCount) {
- m_renderingArrays.resize(seriesCount);
- m_seriesScaleX = 1.0f / float(seriesCount);
- m_seriesStep = 1.0f / float(seriesCount);
- m_seriesStart = -((float(seriesCount) - 1.0f) / 2.0f) * m_seriesStep;
- }
+ m_seriesScaleX = 1.0f / float(m_visibleSeriesCount);
+ m_seriesStep = 1.0f / float(m_visibleSeriesCount);
+ m_seriesStart = -((float(m_visibleSeriesCount) - 1.0f) / 2.0f) * m_seriesStep;
if (m_keepSeriesUniform)
m_seriesScaleZ = m_seriesScaleX;
@@ -178,7 +176,6 @@ void Bars3DRenderer::updateData()
// Force update for selection related items
m_sliceCache = 0;
m_sliceTitleItem = 0;
- m_sliceSelection.clear();
m_cachedColumnCount = newColumns;
m_cachedRowCount = newRows;
@@ -192,95 +189,121 @@ void Bars3DRenderer::updateData()
const QValue3DAxisFormatter *axisFormatter = m_axisCacheY.formatter();
float zeroPosition = axisFormatter->positionAt(0.0f);
- for (int series = 0; series < seriesCount; series++) {
- BarRenderItemArray &renderArray = m_renderingArrays[series];
- if (newRows != renderArray.size()
- || newColumns != renderArray.at(0).size()) {
- // Destroy old render items and reallocate new array
- renderArray.resize(newRows);
- for (int i = 0; i < newRows; i++)
- renderArray[i].resize(newColumns);
- }
- // Update cached data window
- QBarDataProxy *dataProxy =
- static_cast<QBar3DSeries *>(m_visibleSeriesList.at(series).series())->dataProxy();
- dataRowCount = dataProxy->rowCount();
- if (maxDataRowCount < dataRowCount)
- maxDataRowCount = qMin(dataRowCount, newRows);
- int dataRowIndex = minRow;
- GLfloat heightValue = 0.0f;
- for (int i = 0; i < newRows; i++) {
- int j = 0;
- BarRenderItemRow &renderRow = renderArray[i];
- if (dataRowIndex < dataRowCount) {
- const QBarDataRow *dataRow = dataProxy->rowAt(dataRowIndex);
- updateSize = qMin((dataRow->size() - minCol), renderRow.size());
- if (dataRow) {
- int dataColIndex = minCol;
- for (; j < updateSize ; j++) {
- float value = dataRow->at(dataColIndex).value();
- heightValue = axisFormatter->positionAt(value);
- if (m_noZeroInRange) {
- if (m_hasNegativeValues) {
- heightValue = -1.0f + heightValue;
- if (heightValue > 0.0f)
- heightValue = 0.0f;
- } else {
- if (heightValue < 0.0f)
- heightValue = 0.0f;
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(baseCache);
+ if (cache->isVisible()) {
+ const QBar3DSeries *currentSeries = cache->series();
+ BarRenderItemArray &renderArray = cache->renderArray();
+ bool dimensionsChanged = false;
+ if (newRows != renderArray.size()
+ || newColumns != renderArray.at(0).size()) {
+ // Destroy old render items and reallocate new array
+ dimensionsChanged = true;
+ renderArray.resize(newRows);
+ for (int i = 0; i < newRows; i++)
+ renderArray[i].resize(newColumns);
+ cache->sliceArray().clear();
+ }
+
+ if (cache->dataDirty() || dimensionsChanged) {
+ QBarDataProxy *dataProxy = currentSeries->dataProxy();
+ dataRowCount = dataProxy->rowCount();
+ if (maxDataRowCount < dataRowCount)
+ maxDataRowCount = qMin(dataRowCount, newRows);
+ int dataRowIndex = minRow;
+ GLfloat heightValue = 0.0f;
+ for (int i = 0; i < newRows; i++) {
+ int j = 0;
+ BarRenderItemRow &renderRow = renderArray[i];
+ if (dataRowIndex < dataRowCount) {
+ const QBarDataRow *dataRow = dataProxy->rowAt(dataRowIndex);
+ updateSize = qMin((dataRow->size() - minCol), renderRow.size());
+ if (dataRow) {
+ int dataColIndex = minCol;
+ for (; j < updateSize ; j++) {
+ float value = dataRow->at(dataColIndex).value();
+ heightValue = axisFormatter->positionAt(value);
+ if (m_noZeroInRange) {
+ if (m_hasNegativeValues) {
+ heightValue = -1.0f + heightValue;
+ if (heightValue > 0.0f)
+ heightValue = 0.0f;
+ } else {
+ if (heightValue < 0.0f)
+ heightValue = 0.0f;
+ }
+ } else {
+ heightValue -= zeroPosition;
+ }
+ renderRow[j].setValue(value);
+ renderRow[j].setHeight(heightValue);
+
+ float angle = dataRow->at(dataColIndex).rotation();
+ if (angle) {
+ renderRow[j].setRotation(
+ QQuaternion::fromAxisAndAngle(
+ upVector, angle));
+ } else {
+ renderRow[j].setRotation(identityQuaternion);
+ }
+ dataColIndex++;
}
- } else {
- heightValue -= zeroPosition;
- }
- renderRow[j].setValue(value);
- renderRow[j].setHeight(heightValue);
-
- float angle = dataRow->at(dataColIndex).rotation();
- if (angle) {
- renderRow[j].setRotation(
- QQuaternion::fromAxisAndAngle(
- upVector, angle));
- } else {
- renderRow[j].setRotation(identityQuaternion);
}
- dataColIndex++;
}
+ for (; j < newColumns; j++) {
+ renderRow[j].setValue(0.0f);
+ renderRow[j].setHeight(0.0f);
+ renderRow[j].setRotation(identityQuaternion);
+ }
+ dataRowIndex++;
}
+ cache->setDataDirty(false);
}
- for (; j < m_renderingArrays.at(series).at(i).size(); j++) {
- renderRow[j].setValue(0.0f);
- renderRow[j].setHeight(0.0f);
- renderRow[j].setRotation(identityQuaternion);
- }
- dataRowIndex++;
}
}
// Reset selected bar to update selection
- updateSelectedBar(m_selectedBarPos, m_selectedBarSeries);
+ updateSelectedBar(m_selectedBarPos,
+ m_selectedSeriesCache ? m_selectedSeriesCache->series() : 0);
}
-void Bars3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList,
- bool updateVisibility)
+void Bars3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList)
{
- Abstract3DRenderer::updateSeries(seriesList, updateVisibility);
+ Abstract3DRenderer::updateSeries(seriesList);
bool noSelection = true;
- int seriesCount = m_visibleSeriesList.size();
- for (int i = 0; i < seriesCount; i++) {
- QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(m_visibleSeriesList.at(i).series());
- if (noSelection
- && barSeries->selectedBar() != QBar3DSeries::invalidSelectionPosition()
- && selectionLabel() != m_visibleSeriesList.at(i).itemLabel()) {
- m_selectionLabelDirty = true;
- noSelection = false;
+ int seriesCount = seriesList.size();
+ int visualIndex = 0;
+ m_haveUniformColorSeries = false;
+ m_haveGradientSeries = false;
+ for (int i = 0 ; i < seriesCount; i++) {
+ QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(seriesList[i]);
+ if (barSeries->isVisible()) {
+ BarSeriesRenderCache *cache =
+ static_cast<BarSeriesRenderCache *>(m_renderCacheList.value(barSeries));
+ if (noSelection
+ && barSeries->selectedBar() != QBar3DSeries::invalidSelectionPosition()
+ && selectionLabel() != cache->itemLabel()) {
+ m_selectionLabelDirty = true;
+ noSelection = false;
+ }
+ cache->setVisualIndex(visualIndex++);
+ if (cache->colorStyle() == Q3DTheme::ColorStyleUniform)
+ m_haveUniformColorSeries = true;
+ else
+ m_haveGradientSeries = true;
}
}
if (noSelection && !selectionLabel().isEmpty())
m_selectionLabelDirty = true;
}
+SeriesRenderCache *Bars3DRenderer::createNewCache(QAbstract3DSeries *series)
+{
+ return new BarSeriesRenderCache(series, this);
+}
+
void Bars3DRenderer::updateScene(Q3DScene *scene)
{
if (m_hasNegativeValues)
@@ -506,7 +529,6 @@ void Bars3DRenderer::drawSlicedScene()
ShaderHelper *barShader = m_barShader;
barShader->bind();
- int currentSeriesIndex = -1;
Q3DTheme::ColorStyle previousColorStyle = Q3DTheme::ColorStyleUniform;
Q3DTheme::ColorStyle colorStyle = Q3DTheme::ColorStyleUniform;
ObjectHelper *barObj = 0;
@@ -514,29 +536,31 @@ void Bars3DRenderer::drawSlicedScene()
QVector3D baseColor;
GLuint highlightGradientTexture = 0;
GLuint baseGradientTexture = 0;
- const SeriesRenderCache *currentSeries = 0;
bool colorStyleIsUniform = true;
+ int firstVisualIndex = m_renderCacheList.size();
+ QVector<BarRenderSliceItem> *firstVisualSliceArray = 0;
+ BarRenderSliceItem *selectedItem = 0;
+
+ QQuaternion seriesRotation;
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ if (baseCache->isVisible()) {
+ BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(baseCache);
+ QVector<BarRenderSliceItem> &sliceArray = cache->sliceArray();
+ int sliceCount = sliceArray.size();
+ if (firstVisualIndex > cache->visualIndex()) {
+ firstVisualIndex = cache->visualIndex();
+ firstVisualSliceArray = &sliceArray;
+ }
- int sliceItemCount = m_sliceSelection.size();
- for (int bar = 0; bar < sliceItemCount; bar++) {
- const BarRenderSliceItem &item = m_sliceSelection.at(bar);
- if (!item.value())
- continue;
-
- QQuaternion seriesRotation;
-
- if (item.seriesIndex() != currentSeriesIndex) {
- currentSeriesIndex = item.seriesIndex();
- currentSeries = &(m_visibleSeriesList.at(currentSeriesIndex));
- barObj = currentSeries->object();
- colorStyle = currentSeries->colorStyle();
+ barObj = cache->object();
+ colorStyle = cache->colorStyle();
colorStyleIsUniform = (colorStyle == Q3DTheme::ColorStyleUniform);
if (colorStyleIsUniform) {
- highlightColor = currentSeries->singleHighlightColor();
- baseColor = currentSeries->baseColor();
+ highlightColor = cache->singleHighlightColor();
+ baseColor = cache->baseColor();
} else {
- highlightGradientTexture = currentSeries->singleHighlightGradientTexture();
- baseGradientTexture = currentSeries->baseGradientTexture();
+ highlightGradientTexture = cache->singleHighlightGradientTexture();
+ baseGradientTexture = cache->baseGradientTexture();
}
// Rebind shader if it has changed
@@ -555,76 +579,88 @@ void Bars3DRenderer::drawSlicedScene()
}
previousColorStyle = colorStyle;
- seriesRotation = currentSeries->meshRotation();
- }
+ seriesRotation = cache->meshRotation();
+ bool selectedSeries = (cache == m_selectedSeriesCache);
+
+ for (int bar = 0; bar < sliceCount; bar++) {
+ BarRenderSliceItem &item = cache->sliceArray()[bar];
+ if (selectedSeries && itemMode && sliceGridLabels
+ && m_visualSelectedBarPos.x() == item.position().x()
+ && m_visualSelectedBarPos.y() == item.position().y()) {
+ selectedItem = &item;
+ }
+ if (!item.value())
+ continue;
- if (item.height() < 0)
- glCullFace(GL_FRONT);
- else
- glCullFace(GL_BACK);
+ if (item.height() < 0)
+ glCullFace(GL_FRONT);
+ else
+ glCullFace(GL_BACK);
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 modelMatrix;
- QMatrix4x4 itModelMatrix;
- QQuaternion barRotation = item.rotation();
- GLfloat barPosY = item.translation().y() + barPosYAdjustment - zeroPosAdjustment;
-
- if (rowMode) {
- barPosX = item.translation().x();
- } else {
- barPosX = -(item.translation().z()); // flip z; frontmost bar to the left
- barRotation *= ninetyDegreeRotation;
- }
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 itModelMatrix;
+ QQuaternion barRotation = item.rotation();
+ GLfloat barPosY = item.translation().y() + barPosYAdjustment - zeroPosAdjustment;
- modelMatrix.translate(barPosX, barPosY, 0.0f);
- modelMatrixScaler.setY(item.height());
+ if (rowMode) {
+ barPosX = item.translation().x();
+ } else {
+ barPosX = -(item.translation().z()); // flip z; frontmost bar to the left
+ barRotation *= ninetyDegreeRotation;
+ }
- if (!seriesRotation.isIdentity())
- barRotation *= seriesRotation;
+ modelMatrix.translate(barPosX, barPosY, 0.0f);
+ modelMatrixScaler.setY(item.height());
- if (!barRotation.isIdentity()) {
- modelMatrix.rotate(barRotation);
- itModelMatrix.rotate(barRotation);
- }
+ if (!seriesRotation.isIdentity())
+ barRotation *= seriesRotation;
- modelMatrix.scale(modelMatrixScaler);
- itModelMatrix.scale(modelMatrixScaler);
+ if (!barRotation.isIdentity()) {
+ modelMatrix.rotate(barRotation);
+ itModelMatrix.rotate(barRotation);
+ }
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ modelMatrix.scale(modelMatrixScaler);
+ itModelMatrix.scale(modelMatrixScaler);
- QVector3D barColor;
- GLuint gradientTexture = 0;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
- if (itemMode && m_visualSelectedBarPos.x() == item.position().x()
- && m_visualSelectedBarPos.y() == item.position().y()) {
- if (colorStyleIsUniform)
- barColor = highlightColor;
- else
- gradientTexture = highlightGradientTexture;
- } else {
- if (colorStyleIsUniform)
- barColor = baseColor;
- else
- gradientTexture = baseGradientTexture;
- }
+ QVector3D barColor;
+ GLuint gradientTexture = 0;
- if (item.height() != 0) {
- // Set shader bindings
- barShader->setUniformValue(barShader->model(), modelMatrix);
- barShader->setUniformValue(barShader->nModel(),
- itModelMatrix.inverted().transposed());
- barShader->setUniformValue(barShader->MVP(), MVPMatrix);
- if (colorStyleIsUniform) {
- barShader->setUniformValue(barShader->color(), barColor);
- } else if (colorStyle == Q3DTheme::ColorStyleRangeGradient) {
- barShader->setUniformValue(barShader->gradientHeight(),
- (qAbs(item.height()) / m_gradientFraction));
- }
+ if (itemMode && m_visualSelectedBarPos.x() == item.position().x()
+ && m_visualSelectedBarPos.y() == item.position().y()) {
+ if (colorStyleIsUniform)
+ barColor = highlightColor;
+ else
+ gradientTexture = highlightGradientTexture;
+ } else {
+ if (colorStyleIsUniform)
+ barColor = baseColor;
+ else
+ gradientTexture = baseGradientTexture;
+ }
- // Draw the object
- m_drawer->drawObject(barShader,
- barObj,
- gradientTexture);
+ if (item.height() != 0) {
+ // Set shader bindings
+ barShader->setUniformValue(barShader->model(), modelMatrix);
+ barShader->setUniformValue(barShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ barShader->setUniformValue(barShader->MVP(), MVPMatrix);
+ if (colorStyleIsUniform) {
+ barShader->setUniformValue(barShader->color(), barColor);
+ } else if (colorStyle == Q3DTheme::ColorStyleRangeGradient) {
+ barShader->setUniformValue(barShader->gradientHeight(),
+ (qAbs(item.height()) / m_gradientFraction));
+ }
+
+ // Draw the object
+ m_drawer->drawObject(barShader,
+ barObj,
+ gradientTexture);
+ }
+ }
}
}
@@ -644,11 +680,11 @@ void Bars3DRenderer::drawSlicedScene()
QVector3D sliceValueRotation(0.0f, 0.0f, 90.0f);
QVector3D sliceLabelRotation(0.0f, 0.0f, -45.0f);
- int lastLabel = m_sliceCache->labelItems().size() - 1;
+ int labelCount = m_sliceCache->labelItems().size();
- for (int labelNo = 0; labelNo <= lastLabel; labelNo++) {
+ for (int labelNo = 0; labelNo < labelCount; labelNo++) {
// Get labels from first series only
- const BarRenderSliceItem &item = m_sliceSelection.at(labelNo);
+ const BarRenderSliceItem &item = firstVisualSliceArray->at(labelNo);
m_dummyBarRenderItem.setTranslation(QVector3D(item.translation().x(),
barLabelYPos,
item.translation().z()));
@@ -660,60 +696,63 @@ void Bars3DRenderer::drawSlicedScene()
Qt::AlignRight, true);
}
- for (int col = 0; col < sliceItemCount; col++) {
- BarRenderSliceItem &item = m_sliceSelection[col];
-
- if (!sliceGridLabels) {
- // Draw values
- if (item.height() != 0.0f || (!m_noZeroInRange && item.value() == 0.0f)) {
- // Create label texture if we need it
- if (item.sliceLabel().isNull() || m_updateLabels) {
- QString valueLabelText = m_axisCacheY.formatter()->stringForValue(
- qreal(item.value()), m_axisCacheY.labelFormat());
- item.setSliceLabel(valueLabelText);
- m_drawer->generateLabelItem(item.sliceLabelItem(), item.sliceLabel());
- m_updateLabels = false;
- }
- Qt::AlignmentFlag alignment = (item.height() < 0) ? Qt::AlignBottom : Qt::AlignTop;
- Drawer::LabelPosition labelPos = (item.height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver;
- m_dummyBarRenderItem.setTranslation(QVector3D(item.translation().x(),
- barPosYAdjustment - zeroPosAdjustment
- + item.height(),
- item.translation().z()));
-
- m_drawer->drawLabel(m_dummyBarRenderItem, item.sliceLabelItem(), viewMatrix,
- projectionMatrix, zeroVector, sliceValueRotation,
- item.height(), m_cachedSelectionMode, m_labelShader,
- m_labelObj, activeCamera, false, false, labelPos,
- alignment, true);
- }
- } else {
- // Only draw value for selected item when grid labels are on
- if (itemMode && m_visualSelectedBarPos.x() == item.position().x()
- && m_visualSelectedBarPos.y() == item.position().y()
- && item.seriesIndex() == m_visualSelectedBarSeriesIndex) {
- // Create label texture if we need it
- if (item.sliceLabel().isNull() || m_updateLabels) {
- QString valueLabelText = m_axisCacheY.formatter()->stringForValue(
- qreal(item.value()), m_axisCacheY.labelFormat());
- item.setSliceLabel(valueLabelText);
- m_drawer->generateLabelItem(item.sliceLabelItem(), item.sliceLabel());
- m_updateLabels = false;
+ if (!sliceGridLabels) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ if (baseCache->isVisible()) {
+ BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(baseCache);
+ QVector<BarRenderSliceItem> &sliceArray = cache->sliceArray();
+ int sliceCount = sliceArray.size();
+ for (int col = 0; col < sliceCount; col++) {
+ BarRenderSliceItem &item = sliceArray[col];
+
+ // Draw values
+ if (item.height() != 0.0f || (!m_noZeroInRange && item.value() == 0.0f)) {
+ // Create label texture if we need it
+ if (item.sliceLabel().isNull() || m_updateLabels) {
+ QString valueLabelText = m_axisCacheY.formatter()->stringForValue(
+ qreal(item.value()), m_axisCacheY.labelFormat());
+ item.setSliceLabel(valueLabelText);
+ m_drawer->generateLabelItem(item.sliceLabelItem(), item.sliceLabel());
+ m_updateLabels = false;
+ }
+ Qt::AlignmentFlag alignment = (item.height() < 0) ? Qt::AlignBottom : Qt::AlignTop;
+ Drawer::LabelPosition labelPos = (item.height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver;
+ m_dummyBarRenderItem.setTranslation(QVector3D(item.translation().x(),
+ barPosYAdjustment - zeroPosAdjustment
+ + item.height(),
+ item.translation().z()));
+
+ m_drawer->drawLabel(m_dummyBarRenderItem, item.sliceLabelItem(), viewMatrix,
+ projectionMatrix, zeroVector, sliceValueRotation,
+ item.height(), m_cachedSelectionMode, m_labelShader,
+ m_labelObj, activeCamera, false, false, labelPos,
+ alignment, true);
+ }
}
- Qt::AlignmentFlag alignment = (item.height() < 0) ? Qt::AlignBottom : Qt::AlignTop;
- Drawer::LabelPosition labelPos = (item.height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver;
- m_dummyBarRenderItem.setTranslation(QVector3D(item.translation().x(),
- barPosYAdjustment - zeroPosAdjustment
- + item.height(),
- item.translation().z()));
-
- m_drawer->drawLabel(m_dummyBarRenderItem, item.sliceLabelItem(), viewMatrix,
- projectionMatrix, zeroVector, sliceValueRotation,
- item.height(), m_cachedSelectionMode, m_labelShader,
- m_labelObj, activeCamera, false, false, labelPos,
- alignment, true);
}
}
+ } else {
+ // Only draw value for selected item when grid labels are on
+ // Create label texture if we need it
+ if (selectedItem->sliceLabel().isNull() || m_updateLabels) {
+ QString valueLabelText = m_axisCacheY.formatter()->stringForValue(
+ qreal(selectedItem->value()), m_axisCacheY.labelFormat());
+ selectedItem->setSliceLabel(valueLabelText);
+ m_drawer->generateLabelItem(selectedItem->sliceLabelItem(), selectedItem->sliceLabel());
+ m_updateLabels = false;
+ }
+ Qt::AlignmentFlag alignment = (selectedItem->height() < 0) ? Qt::AlignBottom : Qt::AlignTop;
+ Drawer::LabelPosition labelPos = (selectedItem->height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver;
+ m_dummyBarRenderItem.setTranslation(QVector3D(selectedItem->translation().x(),
+ barPosYAdjustment - zeroPosAdjustment
+ + selectedItem->height(),
+ selectedItem->translation().z()));
+
+ m_drawer->drawLabel(m_dummyBarRenderItem, selectedItem->sliceLabelItem(), viewMatrix,
+ projectionMatrix, zeroVector, sliceValueRotation,
+ selectedItem->height(), m_cachedSelectionMode, m_labelShader,
+ m_labelObj, activeCamera, false, false, labelPos,
+ alignment, true);
}
// Draw labels for axes
@@ -773,8 +812,6 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
QVector3D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor());
- int seriesCount = m_visibleSeriesList.size();
-
const Q3DCamera *activeCamera = m_cachedScene->activeCamera();
glViewport(m_primarySubViewport.x(),
@@ -880,70 +917,74 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
// Draw bars to depth buffer
QVector3D shadowScaler(m_scaleX * m_seriesScaleX * 0.9f, 0.0f,
m_scaleZ * m_seriesScaleZ * 0.9f);
- float seriesPos = m_seriesStart;
- for (int series = 0; series < seriesCount; series++) {
- ObjectHelper *barObj = m_visibleSeriesList.at(series).object();
- QQuaternion seriesRotation(m_visibleSeriesList.at(series).meshRotation());
- for (int row = startRow; row != stopRow; row += stepRow) {
- for (int bar = startBar; bar != stopBar; bar += stepBar) {
- GLfloat shadowOffset = 0.0f;
- const BarRenderItem &item = m_renderingArrays.at(series).at(row).at(bar);
- if (!item.value())
- continue;
- // Set front face culling for negative valued bars and back face culling for
- // positive valued bars to remove peter-panning issues
- if (item.height() > 0) {
- glCullFace(GL_BACK);
- if (m_yFlipped)
- shadowOffset = 0.015f;
- } else {
- glCullFace(GL_FRONT);
- if (!m_yFlipped)
- shadowOffset = -0.015f;
- }
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ if (baseCache->isVisible()) {
+ BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(baseCache);
+ float seriesPos = m_seriesStart + m_seriesStep * cache->visualIndex() + 0.5f;
+ ObjectHelper *barObj = cache->object();
+ QQuaternion seriesRotation(cache->meshRotation());
+ const BarRenderItemArray &renderArray = cache->renderArray();
+ for (int row = startRow; row != stopRow; row += stepRow) {
+ const BarRenderItemRow &renderRow = renderArray.at(row);
+ for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ const BarRenderItem &item = renderRow.at(bar);
+ if (!item.value())
+ continue;
+ GLfloat shadowOffset = 0.0f;
+ // Set front face culling for negative valued bars and back face culling
+ // for positive valued bars to remove peter-panning issues
+ if (item.height() > 0) {
+ glCullFace(GL_BACK);
+ if (m_yFlipped)
+ shadowOffset = 0.015f;
+ } else {
+ glCullFace(GL_FRONT);
+ if (!m_yFlipped)
+ shadowOffset = -0.015f;
+ }
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
- colPos = (bar + 0.5f + seriesPos) * (m_cachedBarSpacing.width());
- rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
+ colPos = (bar + seriesPos) * (m_cachedBarSpacing.width());
+ rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
- // Draw shadows for bars "on the other side" a bit off ground to avoid seeing
- // shadows through the ground
- modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
- item.height() + shadowOffset,
- (m_columnDepth - rowPos) / m_scaleFactor);
- // Scale the bars down in X and Z to reduce self-shadowing issues
- shadowScaler.setY(item.height());
- if (!seriesRotation.isIdentity() || !item.rotation().isIdentity())
- modelMatrix.rotate(seriesRotation * item.rotation());
- modelMatrix.scale(shadowScaler);
+ // Draw shadows for bars "on the other side" a bit off ground to avoid
+ // seeing shadows through the ground
+ modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
+ item.height() + shadowOffset,
+ (m_columnDepth - rowPos) / m_scaleFactor);
+ // Scale the bars down in X and Z to reduce self-shadowing issues
+ shadowScaler.setY(item.height());
+ if (!seriesRotation.isIdentity() || !item.rotation().isIdentity())
+ modelMatrix.rotate(seriesRotation * item.rotation());
+ modelMatrix.scale(shadowScaler);
- MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
- m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
+ m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(m_depthShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, barObj->vertexBuf());
- glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
- (void *)0);
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, barObj->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, barObj->elementBuf());
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, barObj->elementBuf());
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, barObj->indexCount(), GL_UNSIGNED_SHORT,
- (void *)0);
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, barObj->indexCount(), GL_UNSIGNED_SHORT,
+ (void *)0);
- // Free buffers
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
- glDisableVertexAttribArray(m_depthShader->posAtt());
+ glDisableVertexAttribArray(m_depthShader->posAtt());
+ }
}
}
- seriesPos += m_seriesStep;
}
// Disable drawing to depth framebuffer (= enable drawing to screen)
@@ -962,7 +1003,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
// Skip selection mode drawing if we're slicing or have no selection mode
if (!m_cachedIsSlicingActivated && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone
- && m_selectionState == SelectOnScene && seriesCount > 0) {
+ && m_selectionState == SelectOnScene && m_visibleSeriesCount > 0) {
// Bind selection shader
m_selectionShader->bind();
@@ -976,50 +1017,54 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Set clear color to white (= selectionSkipColor)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
- float seriesPos = m_seriesStart;
- for (int series = 0; series < seriesCount; series++) {
- ObjectHelper *barObj = m_visibleSeriesList.at(series).object();
- QQuaternion seriesRotation(m_visibleSeriesList.at(series).meshRotation());
- for (int row = startRow; row != stopRow; row += stepRow) {
- for (int bar = startBar; bar != stopBar; bar += stepBar) {
- const BarRenderItem &item = m_renderingArrays.at(series).at(row).at(bar);
- if (!item.value())
- continue;
-
- if (item.height() < 0)
- glCullFace(GL_FRONT);
- else
- glCullFace(GL_BACK);
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ if (baseCache->isVisible()) {
+ BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(baseCache);
+ float seriesPos = m_seriesStart + m_seriesStep * cache->visualIndex() + 0.5f;
+ ObjectHelper *barObj = cache->object();
+ QQuaternion seriesRotation(cache->meshRotation());
+ const BarRenderItemArray &renderArray = cache->renderArray();
+ for (int row = startRow; row != stopRow; row += stepRow) {
+ const BarRenderItemRow &renderRow = renderArray.at(row);
+ for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ const BarRenderItem &item = renderRow.at(bar);
+ if (!item.value())
+ continue;
+
+ if (item.height() < 0)
+ glCullFace(GL_FRONT);
+ else
+ glCullFace(GL_BACK);
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
- colPos = (bar + 0.5f + seriesPos) * (m_cachedBarSpacing.width());
- rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
+ colPos = (bar + seriesPos) * (m_cachedBarSpacing.width());
+ rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
- modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
- item.height(),
- (m_columnDepth - rowPos) / m_scaleFactor);
- if (!seriesRotation.isIdentity() || !item.rotation().isIdentity())
- modelMatrix.rotate(seriesRotation * item.rotation());
- modelMatrix.scale(QVector3D(m_scaleX * m_seriesScaleX,
- item.height(),
- m_scaleZ * m_seriesScaleZ));
+ modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
+ item.height(),
+ (m_columnDepth - rowPos) / m_scaleFactor);
+ if (!seriesRotation.isIdentity() || !item.rotation().isIdentity())
+ modelMatrix.rotate(seriesRotation * item.rotation());
+ modelMatrix.scale(QVector3D(m_scaleX * m_seriesScaleX,
+ item.height(),
+ m_scaleZ * m_seriesScaleZ));
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
- QVector4D barColor = QVector4D(GLfloat(row) / 255.0f,
- GLfloat(bar) / 255.0f,
- GLfloat(series) / 255.0f,
- itemAlpha);
+ QVector4D barColor = QVector4D(GLfloat(row) / 255.0f,
+ GLfloat(bar) / 255.0f,
+ GLfloat(cache->visualIndex()) / 255.0f,
+ itemAlpha);
- m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
- m_selectionShader->setUniformValue(m_selectionShader->color(), barColor);
+ m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
+ m_selectionShader->setUniformValue(m_selectionShader->color(), barColor);
- m_drawer->drawSelectionObject(m_selectionShader, barObj);
+ m_drawer->drawSelectionObject(m_selectionShader, barObj);
+ }
}
}
- seriesPos += m_seriesStep;
}
glCullFace(GL_BACK);
drawLabels(true, activeCamera, viewMatrix, projectionMatrix, rowScaleFactor,
@@ -1048,18 +1093,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
ShaderHelper *barShader = 0;
GLuint gradientTexture = 0;
Q3DTheme::ColorStyle previousColorStyle = Q3DTheme::ColorStyleUniform;
- bool haveUniformColorSeries = false;
- bool haveGradientSeries = false;
-
- for (int i = 0; i < seriesCount; i++) {
- if (m_visibleSeriesList.at(i).colorStyle() == Q3DTheme::ColorStyleUniform)
- haveUniformColorSeries = true;
- else
- haveGradientSeries = true;
- }
// Set unchanging shader bindings
- if (haveGradientSeries) {
+ if (m_haveGradientSeries) {
m_barGradientShader->bind();
m_barGradientShader->setUniformValue(m_barGradientShader->lightP(), lightPos);
m_barGradientShader->setUniformValue(m_barGradientShader->view(), viewMatrix);
@@ -1069,7 +1105,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
m_barGradientShader->setUniformValue(m_barGradientShader->lightColor(), lightColor);
}
- if (haveUniformColorSeries) {
+ if (m_haveUniformColorSeries) {
m_barShader->bind();
m_barShader->setUniformValue(m_barShader->lightP(), lightPos);
m_barShader->setUniformValue(m_barShader->view(), viewMatrix);
@@ -1082,17 +1118,13 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
previousColorStyle = Q3DTheme::ColorStyleRangeGradient;
}
+ int sliceReserveAmount = 0;
if (m_selectionDirty && m_cachedIsSlicingActivated) {
// Slice doesn't own its items, no need to delete them - just clear
- m_sliceSelection.clear();
- int reserveAmount;
if (rowMode)
- reserveAmount = m_cachedColumnCount;
+ sliceReserveAmount = m_cachedColumnCount;
else
- reserveAmount = m_cachedRowCount;
- if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries))
- reserveAmount *= m_visibleSeriesList.size();
- m_sliceSelection.resize(reserveAmount);
+ sliceReserveAmount = m_cachedRowCount;
// Set slice cache, i.e. axis cache from where slice labels are taken
if (rowMode)
@@ -1115,225 +1147,220 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
QVector3D barColor;
QVector3D modelScaler(m_scaleX * m_seriesScaleX, 0.0f, m_scaleZ * m_seriesScaleZ);
bool somethingSelected = (m_visualSelectedBarPos != Bars3DController::invalidSelectionPosition());
- float seriesPos = m_seriesStart;
- for (int series = 0; series < seriesCount; series++) {
- const SeriesRenderCache &currentSeries = m_visibleSeriesList.at(series);
- QQuaternion seriesRotation(currentSeries.meshRotation());
- ObjectHelper *barObj = currentSeries.object();
- Q3DTheme::ColorStyle colorStyle = currentSeries.colorStyle();
- bool colorStyleIsUniform = (colorStyle == Q3DTheme::ColorStyleUniform);
-
- // Rebind shader if it has changed
- if (colorStyleIsUniform != (previousColorStyle == Q3DTheme::ColorStyleUniform)) {
- if (colorStyleIsUniform)
- barShader = m_barShader;
- else
- barShader = m_barGradientShader;
- barShader->bind();
- }
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ if (baseCache->isVisible()) {
+ BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(baseCache);
+ float seriesPos = m_seriesStart + m_seriesStep * cache->visualIndex() + 0.5f;
+ ObjectHelper *barObj = cache->object();
+ QQuaternion seriesRotation(cache->meshRotation());
+ Q3DTheme::ColorStyle colorStyle = cache->colorStyle();
+ BarRenderItemArray &renderArray = cache->renderArray();
+ bool colorStyleIsUniform = (colorStyle == Q3DTheme::ColorStyleUniform);
+ if (sliceReserveAmount)
+ cache->sliceArray().resize(sliceReserveAmount);
- if (colorStyleIsUniform) {
- baseColor = currentSeries.baseColor();
- } else if ((previousColorStyle != colorStyle)
- && (colorStyle == Q3DTheme::ColorStyleObjectGradient)) {
- m_barGradientShader->setUniformValue(m_barGradientShader->gradientHeight(), 0.5f);
- }
+ // Rebind shader if it has changed
+ if (colorStyleIsUniform != (previousColorStyle == Q3DTheme::ColorStyleUniform)) {
+ if (colorStyleIsUniform)
+ barShader = m_barShader;
+ else
+ barShader = m_barGradientShader;
+ barShader->bind();
+ }
- // Always use base color when no selection mode
- if (m_cachedSelectionMode == QAbstract3DGraph::SelectionNone) {
- if (colorStyleIsUniform)
- barColor = baseColor;
- else
- gradientTexture = currentSeries.baseGradientTexture();
- }
+ if (colorStyleIsUniform) {
+ baseColor = cache->baseColor();
+ } else if ((previousColorStyle != colorStyle)
+ && (colorStyle == Q3DTheme::ColorStyleObjectGradient)) {
+ m_barGradientShader->setUniformValue(m_barGradientShader->gradientHeight(), 0.5f);
+ }
- previousColorStyle = colorStyle;
- int sliceSeriesAdjust = 0;
- if (m_selectionDirty && m_cachedIsSlicingActivated) {
- int seriesMultiplier = 0;
- if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries))
- seriesMultiplier = series;
- if (rowMode)
- sliceSeriesAdjust = seriesMultiplier * m_cachedColumnCount;
- else
- sliceSeriesAdjust = seriesMultiplier * m_cachedRowCount;
- }
+ // Always use base color when no selection mode
+ if (m_cachedSelectionMode == QAbstract3DGraph::SelectionNone) {
+ if (colorStyleIsUniform)
+ barColor = baseColor;
+ else
+ gradientTexture = cache->baseGradientTexture();
+ }
- for (int row = startRow; row != stopRow; row += stepRow) {
- for (int bar = startBar; bar != stopBar; bar += stepBar) {
- BarRenderItem &item = m_renderingArrays[series][row][bar];
+ previousColorStyle = colorStyle;
- if (item.height() < 0)
- glCullFace(GL_FRONT);
- else
- glCullFace(GL_BACK);
+ for (int row = startRow; row != stopRow; row += stepRow) {
+ BarRenderItemRow &renderRow = renderArray[row];
+ for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ BarRenderItem &item = renderRow[bar];
+ if (item.height() < 0)
+ glCullFace(GL_FRONT);
+ else
+ glCullFace(GL_BACK);
- QMatrix4x4 modelMatrix;
- QMatrix4x4 itModelMatrix;
- QMatrix4x4 MVPMatrix;
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 itModelMatrix;
+ QMatrix4x4 MVPMatrix;
- colPos = (bar + 0.5f + seriesPos) * (m_cachedBarSpacing.width());
- rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
-
- modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
- item.height(),
- (m_columnDepth - rowPos) / m_scaleFactor);
- modelScaler.setY(item.height());
- if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) {
- QQuaternion totalRotation = seriesRotation * item.rotation();
- modelMatrix.rotate(totalRotation);
- itModelMatrix.rotate(totalRotation);
- }
- modelMatrix.scale(modelScaler);
- itModelMatrix.scale(modelScaler);
+ colPos = (bar + seriesPos) * (m_cachedBarSpacing.width());
+ rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
+
+ modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
+ item.height(),
+ (m_columnDepth - rowPos) / m_scaleFactor);
+ modelScaler.setY(item.height());
+ if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) {
+ QQuaternion totalRotation = seriesRotation * item.rotation();
+ modelMatrix.rotate(totalRotation);
+ itModelMatrix.rotate(totalRotation);
+ }
+ modelMatrix.scale(modelScaler);
+ itModelMatrix.scale(modelScaler);
#ifdef SHOW_DEPTH_TEXTURE_SCENE
- MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
#else
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
#endif
- GLfloat lightStrength = m_cachedTheme->lightStrength();
- GLfloat shadowLightStrength = adjustedLightStrength;
-
- if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone) {
- Bars3DController::SelectionType selectionType = Bars3DController::SelectionNone;
- if (somethingSelected)
- selectionType = isSelected(row, bar, series);
-
- switch (selectionType) {
- case Bars3DController::SelectionItem: {
- if (colorStyleIsUniform)
- barColor = currentSeries.singleHighlightColor();
- else
- gradientTexture = currentSeries.singleHighlightGradientTexture();
-
- lightStrength = m_cachedTheme->highlightLightStrength();
- shadowLightStrength = adjustedHighlightStrength;
- // Insert position data into render item. We have no ownership, don't delete the previous one
- if (!m_cachedIsSlicingActivated
- && m_visualSelectedBarSeriesIndex == series) {
- selectedBar = &item;
- selectedBar->setPosition(QPoint(row, bar));
- item.setTranslation(modelMatrix.column(3).toVector3D());
- barSelectionFound = true;
- }
- if (m_selectionDirty && m_cachedIsSlicingActivated) {
- QVector3D translation = modelMatrix.column(3).toVector3D();
- if (m_cachedSelectionMode & QAbstract3DGraph::SelectionColumn
- && seriesCount > 1) {
- translation.setZ((m_columnDepth - ((row + 0.5f + seriesPos)
- * (m_cachedBarSpacing.height())))
- / m_scaleFactor);
- }
- item.setTranslation(translation);
- item.setPosition(QPoint(row, bar));
- item.setSeriesIndex(series);
- if (rowMode)
- m_sliceSelection[sliceSeriesAdjust + bar].setItem(item);
+ GLfloat lightStrength = m_cachedTheme->lightStrength();
+ GLfloat shadowLightStrength = adjustedLightStrength;
+
+ if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone) {
+ Bars3DController::SelectionType selectionType =
+ Bars3DController::SelectionNone;
+ if (somethingSelected)
+ selectionType = isSelected(row, bar, cache);
+
+ switch (selectionType) {
+ case Bars3DController::SelectionItem: {
+ if (colorStyleIsUniform)
+ barColor = cache->singleHighlightColor();
else
- m_sliceSelection[sliceSeriesAdjust + row].setItem(item);
- }
- break;
- }
- case Bars3DController::SelectionRow: {
- // Current bar is on the same row as the selected bar
- if (colorStyleIsUniform)
- barColor = currentSeries.multiHighlightColor();
- else
- gradientTexture = currentSeries.multiHighlightGradientTexture();
-
- lightStrength = m_cachedTheme->highlightLightStrength();
- shadowLightStrength = adjustedHighlightStrength;
- if (m_cachedIsSlicingActivated) {
- item.setTranslation(modelMatrix.column(3).toVector3D());
- item.setPosition(QPoint(row, bar));
- if (m_selectionDirty) {
- item.setSeriesIndex(series);
- if (!m_sliceTitleItem && m_axisCacheZ.labelItems().size() > row)
- m_sliceTitleItem = m_axisCacheZ.labelItems().at(row);
- m_sliceSelection[sliceSeriesAdjust + bar].setItem(item);
+ gradientTexture = cache->singleHighlightGradientTexture();
+
+ lightStrength = m_cachedTheme->highlightLightStrength();
+ shadowLightStrength = adjustedHighlightStrength;
+ // Insert position data into render item
+ // We have no ownership, don't delete the previous one
+ if (!m_cachedIsSlicingActivated
+ && m_selectedSeriesCache == cache) {
+ selectedBar = &item;
+ selectedBar->setPosition(QPoint(row, bar));
+ item.setTranslation(modelMatrix.column(3).toVector3D());
+ barSelectionFound = true;
+ }
+ if (m_selectionDirty && m_cachedIsSlicingActivated) {
+ QVector3D translation = modelMatrix.column(3).toVector3D();
+ if (m_cachedSelectionMode & QAbstract3DGraph::SelectionColumn
+ && m_visibleSeriesCount > 1) {
+ translation.setZ((m_columnDepth
+ - ((row + seriesPos)
+ * (m_cachedBarSpacing.height())))
+ / m_scaleFactor);
+ }
+ item.setTranslation(translation);
+ item.setPosition(QPoint(row, bar));
+ if (rowMode)
+ cache->sliceArray()[bar].setItem(item);
+ else
+ cache->sliceArray()[row].setItem(item);
}
+ break;
}
- break;
- }
- case Bars3DController::SelectionColumn: {
- // Current bar is on the same column as the selected bar
- if (colorStyleIsUniform)
- barColor = currentSeries.multiHighlightColor();
- else
- gradientTexture = currentSeries.multiHighlightGradientTexture();
-
- lightStrength = m_cachedTheme->highlightLightStrength();
- shadowLightStrength = adjustedHighlightStrength;
- if (m_cachedIsSlicingActivated) {
- QVector3D translation = modelMatrix.column(3).toVector3D();
- if (seriesCount > 1) {
- translation.setZ((m_columnDepth - ((row + 0.5f + seriesPos)
- * (m_cachedBarSpacing.height())))
- / m_scaleFactor);
+ case Bars3DController::SelectionRow: {
+ // Current bar is on the same row as the selected bar
+ if (colorStyleIsUniform)
+ barColor = cache->multiHighlightColor();
+ else
+ gradientTexture = cache->multiHighlightGradientTexture();
+
+ lightStrength = m_cachedTheme->highlightLightStrength();
+ shadowLightStrength = adjustedHighlightStrength;
+ if (m_cachedIsSlicingActivated) {
+ item.setTranslation(modelMatrix.column(3).toVector3D());
+ item.setPosition(QPoint(row, bar));
+ if (m_selectionDirty) {
+ if (!m_sliceTitleItem && m_axisCacheZ.labelItems().size() > row)
+ m_sliceTitleItem = m_axisCacheZ.labelItems().at(row);
+ cache->sliceArray()[bar].setItem(item);
+ }
}
- item.setTranslation(translation);
- item.setPosition(QPoint(row, bar));
- if (m_selectionDirty) {
- item.setSeriesIndex(series);
- if (!m_sliceTitleItem && m_axisCacheX.labelItems().size() > bar)
- m_sliceTitleItem = m_axisCacheX.labelItems().at(bar);
- m_sliceSelection[sliceSeriesAdjust + row].setItem(item);
+ break;
+ }
+ case Bars3DController::SelectionColumn: {
+ // Current bar is on the same column as the selected bar
+ if (colorStyleIsUniform)
+ barColor = cache->multiHighlightColor();
+ else
+ gradientTexture = cache->multiHighlightGradientTexture();
+
+ lightStrength = m_cachedTheme->highlightLightStrength();
+ shadowLightStrength = adjustedHighlightStrength;
+ if (m_cachedIsSlicingActivated) {
+ QVector3D translation = modelMatrix.column(3).toVector3D();
+ if (m_visibleSeriesCount > 1) {
+ translation.setZ((m_columnDepth - ((row + seriesPos)
+ * (m_cachedBarSpacing.height())))
+ / m_scaleFactor);
+ }
+ item.setTranslation(translation);
+ item.setPosition(QPoint(row, bar));
+ if (m_selectionDirty) {
+ if (!m_sliceTitleItem && m_axisCacheX.labelItems().size() > bar)
+ m_sliceTitleItem = m_axisCacheX.labelItems().at(bar);
+ cache->sliceArray()[row].setItem(item);
+ }
}
+ break;
+ }
+ case Bars3DController::SelectionNone: {
+ // Current bar is not selected, nor on a row or column
+ if (colorStyleIsUniform)
+ barColor = baseColor;
+ else
+ gradientTexture = cache->baseGradientTexture();
+ break;
+ }
}
- break;
- }
- case Bars3DController::SelectionNone: {
- // Current bar is not selected, nor on a row or column
- if (colorStyleIsUniform)
- barColor = baseColor;
- else
- gradientTexture = currentSeries.baseGradientTexture();
- break;
- }
}
- }
- // Skip drawing of 0-height bars
- if (item.height() != 0) {
- // Set shader bindings
- barShader->setUniformValue(barShader->model(), modelMatrix);
- barShader->setUniformValue(barShader->nModel(),
- itModelMatrix.transposed().inverted());
- barShader->setUniformValue(barShader->MVP(), MVPMatrix);
- if (colorStyleIsUniform) {
- barShader->setUniformValue(barShader->color(), barColor);
- } else if (colorStyle == Q3DTheme::ColorStyleRangeGradient) {
- barShader->setUniformValue(barShader->gradientHeight(),
- qAbs(item.height()) / m_gradientFraction);
- }
+ // Skip drawing of 0-height bars
+ if (item.height() != 0) {
+ // Set shader bindings
+ barShader->setUniformValue(barShader->model(), modelMatrix);
+ barShader->setUniformValue(barShader->nModel(),
+ itModelMatrix.transposed().inverted());
+ barShader->setUniformValue(barShader->MVP(), MVPMatrix);
+ if (colorStyleIsUniform) {
+ barShader->setUniformValue(barShader->color(), barColor);
+ } else if (colorStyle == Q3DTheme::ColorStyleRangeGradient) {
+ barShader->setUniformValue(barShader->gradientHeight(),
+ qAbs(item.height()) / m_gradientFraction);
+ }
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- // Set shadow shader bindings
- QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
- barShader->setUniformValue(barShader->shadowQ(), m_shadowQualityToShader);
- barShader->setUniformValue(barShader->depth(), depthMVPMatrix);
- barShader->setUniformValue(barShader->lightS(), shadowLightStrength);
- barShader->setUniformValue(barShader->lightColor(), lightColor);
-
- // Draw the object
- m_drawer->drawObject(barShader, barObj, gradientTexture, m_depthTexture);
- } else
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ barShader->setUniformValue(barShader->shadowQ(), m_shadowQualityToShader);
+ barShader->setUniformValue(barShader->depth(), depthMVPMatrix);
+ barShader->setUniformValue(barShader->lightS(), shadowLightStrength);
+ barShader->setUniformValue(barShader->lightColor(), lightColor);
+
+ // Draw the object
+ m_drawer->drawObject(barShader, barObj, gradientTexture, m_depthTexture);
+ } else
#else
- Q_UNUSED(shadowLightStrength);
+ Q_UNUSED(shadowLightStrength);
#endif
- {
- // Set shadowless shader bindings
- barShader->setUniformValue(barShader->lightS(), lightStrength);
+ {
+ // Set shadowless shader bindings
+ barShader->setUniformValue(barShader->lightS(), lightStrength);
- // Draw the object
- m_drawer->drawObject(barShader, barObj, gradientTexture);
+ // Draw the object
+ m_drawer->drawObject(barShader, barObj, gradientTexture);
+ }
}
}
}
}
- seriesPos += m_seriesStep;
}
+
glDisable(GL_POLYGON_OFFSET_FILL);
// Bind background shader
@@ -1676,7 +1703,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
|| m_selectionLabelDirty) {
QString labelText = selectionLabel();
if (labelText.isNull() || m_selectionLabelDirty) {
- labelText = m_visibleSeriesList[m_visualSelectedBarSeriesIndex].itemLabel();
+ labelText = m_selectedSeriesCache->itemLabel();
setSelectionLabel(labelText);
m_selectionLabelDirty = false;
}
@@ -1891,7 +1918,7 @@ void Bars3DRenderer::updateMultiSeriesScaling(bool uniform)
m_keepSeriesUniform = uniform;
// Recalculate scale factors
- m_seriesScaleX = 1.0f / float(m_visibleSeriesList.size());
+ m_seriesScaleX = 1.0f / float(m_visibleSeriesCount);
if (m_keepSeriesUniform)
m_seriesScaleZ = m_seriesScaleX;
else
@@ -1943,30 +1970,24 @@ void Bars3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientatio
}
}
-void Bars3DRenderer::updateSelectedBar(const QPoint &position, const QBar3DSeries *series)
+void Bars3DRenderer::updateSelectedBar(const QPoint &position, QBar3DSeries *series)
{
m_selectedBarPos = position;
- m_selectedBarSeries = series;
+ m_selectedSeriesCache = static_cast<BarSeriesRenderCache *>(m_renderCacheList.value(series, 0));
m_selectionDirty = true;
m_selectionLabelDirty = true;
- m_visualSelectedBarSeriesIndex = -1;
- if (m_renderingArrays.isEmpty()) {
+ if (!m_selectedSeriesCache
+ || !m_selectedSeriesCache->isVisible()
+ || m_selectedSeriesCache->renderArray().isEmpty()) {
m_visualSelectedBarPos = Bars3DController::invalidSelectionPosition();
return;
}
int adjustedZ = m_selectedBarPos.x() - int(m_axisCacheZ.min());
int adjustedX = m_selectedBarPos.y() - int(m_axisCacheX.min());
- int maxZ = m_renderingArrays.at(0).size() - 1;
- int maxX = maxZ >= 0 ? m_renderingArrays.at(0).at(0).size() - 1 : -1;
-
- for (int i = 0; i < m_visibleSeriesList.size(); i++) {
- if (m_visibleSeriesList.at(i).series() == series) {
- m_visualSelectedBarSeriesIndex = i;
- break;
- }
- }
+ int maxZ = m_selectedSeriesCache->renderArray().size() - 1;
+ int maxX = maxZ >= 0 ? m_selectedSeriesCache->renderArray().at(0).size() - 1 : -1;
if (m_selectedBarPos == Bars3DController::invalidSelectionPosition()
|| adjustedZ < 0 || adjustedZ > maxZ
@@ -2113,13 +2134,13 @@ void Bars3DRenderer::calculateHeightAdjustment()
}
}
-Bars3DController::SelectionType Bars3DRenderer::isSelected(int row, int bar, int seriesIndex)
+Bars3DController::SelectionType Bars3DRenderer::isSelected(int row, int bar,
+ const BarSeriesRenderCache *cache)
{
Bars3DController::SelectionType isSelectedType = Bars3DController::SelectionNone;
if ((m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries)
- && m_visualSelectedBarSeriesIndex >= 0)
- || seriesIndex == m_visualSelectedBarSeriesIndex) {
+ && m_selectedSeriesCache) || cache == m_selectedSeriesCache) {
if (row == m_visualSelectedBarPos.x() && bar == m_visualSelectedBarPos.y()
&& (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem))) {
isSelectedType = Bars3DController::SelectionItem;
@@ -2174,10 +2195,17 @@ QPoint Bars3DRenderer::selectionColorToArrayPosition(const QVector4D &selectionC
QBar3DSeries *Bars3DRenderer::selectionColorToSeries(const QVector4D &selectionColor)
{
- if (selectionColor == selectionSkipColor)
+ if (selectionColor == selectionSkipColor) {
return 0;
- else
- return static_cast<QBar3DSeries *>(m_visibleSeriesList.at(int(selectionColor.z())).series());
+ } else {
+ int seriesIndexFromColor(selectionColor.z());
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(baseCache);
+ if (cache->visualIndex() == seriesIndexFromColor)
+ return cache->series();
+ }
+ }
+ return 0;
}
void Bars3DRenderer::updateSlicingActive(bool isSlicing)
diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h
index fba5d830..549a63f6 100644
--- a/src/datavisualization/engine/bars3drenderer_p.h
+++ b/src/datavisualization/engine/bars3drenderer_p.h
@@ -45,6 +45,7 @@ class ShaderHelper;
class ObjectHelper;
class LabelItem;
class Q3DScene;
+class BarSeriesRenderCache;
class QT_DATAVISUALIZATION_EXPORT Bars3DRenderer : public Abstract3DRenderer
{
@@ -60,7 +61,6 @@ private:
// Internal state
BarRenderItem *m_selectedBar; // points to renderitem array
- QVector<BarRenderSliceItem> m_sliceSelection;
AxisRenderCache *m_sliceCache; // not owned
const LabelItem *m_sliceTitleItem; // not owned
bool m_xFlipped;
@@ -95,12 +95,10 @@ private:
GLfloat m_scaleFactor;
GLfloat m_maxSceneSize;
QPoint m_visualSelectedBarPos;
- int m_visualSelectedBarSeriesIndex;
bool m_resetCameraBaseOrientation;
QPoint m_selectedBarPos;
- const QBar3DSeries *m_selectedBarSeries;
+ BarSeriesRenderCache *m_selectedSeriesCache;
BarRenderItem m_dummyBarRenderItem;
- QVector<BarRenderItemArray> m_renderingArrays;
bool m_noZeroInRange;
float m_seriesScaleX;
float m_seriesScaleZ;
@@ -108,13 +106,16 @@ private:
float m_seriesStart;
QPoint m_clickedPosition;
bool m_keepSeriesUniform;
+ bool m_haveUniformColorSeries;
+ bool m_haveGradientSeries;
public:
explicit Bars3DRenderer(Bars3DController *controller);
~Bars3DRenderer();
void updateData();
- void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility);
+ void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
+ SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
void updateScene(Q3DScene *scene);
void render(GLuint defaultFboHandle = 0);
@@ -127,7 +128,7 @@ public slots:
const QSizeF &spacing = QSizeF(1.0, 1.0),
bool relative = true);
void updateSlicingActive(bool isSlicing);
- void updateSelectedBar(const QPoint &position, const QBar3DSeries *series);
+ void updateSelectedBar(const QPoint &position, QBar3DSeries *series);
inline QPoint clickedPosition() const { return m_clickedPosition; }
void resetClickedStatus();
@@ -161,7 +162,8 @@ private:
#endif
void calculateSceneScalingFactors();
void calculateHeightAdjustment();
- Abstract3DController::SelectionType isSelected(int row, int bar, int seriesIndex);
+ Abstract3DController::SelectionType isSelected(int row, int bar,
+ const BarSeriesRenderCache *cache);
QPoint selectionColorToArrayPosition(const QVector4D &selectionColor);
QBar3DSeries *selectionColorToSeries(const QVector4D &selectionColor);
diff --git a/src/datavisualization/engine/barseriesrendercache.cpp b/src/datavisualization/engine/barseriesrendercache.cpp
new file mode 100644
index 00000000..83d3e366
--- /dev/null
+++ b/src/datavisualization/engine/barseriesrendercache.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "barseriesrendercache_p.h"
+#include "bars3drenderer_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+BarSeriesRenderCache::BarSeriesRenderCache(QAbstract3DSeries *series,
+ Abstract3DRenderer *renderer)
+ : SeriesRenderCache(series, renderer),
+ m_visualIndex(-1)
+{
+}
+
+BarSeriesRenderCache::~BarSeriesRenderCache()
+{
+}
+
+void BarSeriesRenderCache::cleanup(TextureHelper *texHelper)
+{
+ m_renderArray.clear();
+ m_sliceArray.clear();
+
+ SeriesRenderCache::cleanup(texHelper);
+}
+
+QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/barseriesrendercache_p.h b/src/datavisualization/engine/barseriesrendercache_p.h
new file mode 100644
index 00000000..4e169300
--- /dev/null
+++ b/src/datavisualization/engine/barseriesrendercache_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef BARSERIESRENDERCACHE_P_H
+#define BARSERIESRENDERCACHE_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "seriesrendercache_p.h"
+#include "qbar3dseries_p.h"
+#include "barrenderitem_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class BarSeriesRenderCache : public SeriesRenderCache
+{
+public:
+ BarSeriesRenderCache(QAbstract3DSeries *series, Abstract3DRenderer *renderer);
+ virtual ~BarSeriesRenderCache();
+
+ void cleanup(TextureHelper *texHelper);
+
+ inline BarRenderItemArray &renderArray() { return m_renderArray; }
+ inline QBar3DSeries *series() const { return static_cast<QBar3DSeries *>(m_series); }
+ inline QVector<BarRenderSliceItem> &sliceArray() { return m_sliceArray; }
+ inline void setVisualIndex(int index) { m_visualIndex = index; }
+ inline int visualIndex() {return m_visualIndex; }
+
+protected:
+ BarRenderItemArray m_renderArray;
+ QVector<BarRenderSliceItem> m_sliceArray;
+ int m_visualIndex; // order of the series is relevant
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif
diff --git a/src/datavisualization/engine/engine.pri b/src/datavisualization/engine/engine.pri
index 9c2e71e4..96fa7fa9 100644
--- a/src/datavisualization/engine/engine.pri
+++ b/src/datavisualization/engine/engine.pri
@@ -26,7 +26,9 @@ HEADERS += $$PWD/qabstract3dgraph_p.h \
$$PWD/q3dobject.h \
$$PWD/q3dobject_p.h \
$$PWD/q3dscene_p.h \
- $$PWD/surfaceseriesrendercache_p.h
+ $$PWD/surfaceseriesrendercache_p.h \
+ $$PWD/barseriesrendercache_p.h \
+ $$PWD/scatterseriesrendercache_p.h
SOURCES += $$PWD/qabstract3dgraph.cpp \
$$PWD/q3dbars.cpp \
@@ -48,7 +50,9 @@ SOURCES += $$PWD/qabstract3dgraph.cpp \
$$PWD/q3dlight.cpp \
$$PWD/q3dobject.cpp \
$$PWD/q3dscene.cpp \
- $$PWD/surfaceseriesrendercache.cpp
+ $$PWD/surfaceseriesrendercache.cpp \
+ $$PWD/barseriesrendercache.cpp \
+ $$PWD/scatterseriesrendercache.cpp
RESOURCES += engine/engine.qrc
diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp
index b45a956d..05c0efe7 100644
--- a/src/datavisualization/engine/scatter3dcontroller.cpp
+++ b/src/datavisualization/engine/scatter3dcontroller.cpp
@@ -83,9 +83,6 @@ void Scatter3DController::addSeries(QAbstract3DSeries *series)
Abstract3DController::addSeries(series);
- if (series->isVisible())
- adjustValueAxisRange();
-
QScatter3DSeries *scatterSeries = static_cast<QScatter3DSeries *>(series);
if (scatterSeries->selectedItem() != invalidSelectionIndex())
setSelectedItem(scatterSeries->selectedItem(), scatterSeries);
@@ -101,7 +98,7 @@ void Scatter3DController::removeSeries(QAbstract3DSeries *series)
setSelectedItem(invalidSelectionIndex(), 0);
if (wasVisible)
- adjustValueAxisRange();
+ adjustAxisRanges();
}
QList<QScatter3DSeries *> Scatter3DController::scatterSeriesList()
@@ -121,9 +118,11 @@ void Scatter3DController::handleArrayReset()
{
QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series();
if (series->isVisible()) {
- adjustValueAxisRange();
+ adjustAxisRanges();
m_isDataDirty = true;
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
setSelectedItem(m_selectedItem, m_selectedItemSeries);
series->d_ptr->markItemLabelDirty();
emitNeedRender();
@@ -135,9 +134,11 @@ void Scatter3DController::handleItemsAdded(int startIndex, int count)
Q_UNUSED(count)
QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series();
if (series->isVisible()) {
- adjustValueAxisRange();
+ adjustAxisRanges();
m_isDataDirty = true;
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
@@ -147,10 +148,12 @@ void Scatter3DController::handleItemsChanged(int startIndex, int count)
Q_UNUSED(count)
QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series();
if (series->isVisible()) {
- adjustValueAxisRange();
+ adjustAxisRanges();
m_isDataDirty = true;
series->d_ptr->markItemLabelDirty();
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
@@ -173,9 +176,11 @@ void Scatter3DController::handleItemsRemoved(int startIndex, int count)
}
if (series->isVisible()) {
- adjustValueAxisRange();
+ adjustAxisRanges();
m_isDataDirty = true;
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
if (m_recordInsertsAndRemoves) {
InsertRemoveRecord record(false, startIndex, count, series);
@@ -200,9 +205,11 @@ void Scatter3DController::handleItemsInserted(int startIndex, int count)
}
if (series->isVisible()) {
- adjustValueAxisRange();
+ adjustAxisRanges();
m_isDataDirty = true;
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
if (m_recordInsertsAndRemoves) {
InsertRemoveRecord record(true, startIndex, count, series);
@@ -231,7 +238,7 @@ void Scatter3DController::handleAxisAutoAdjustRangeChangedInOrientation(
{
Q_UNUSED(orientation)
Q_UNUSED(autoAdjust)
- adjustValueAxisRange();
+ adjustAxisRanges();
}
void Scatter3DController::handleAxisRangeChangedBySender(QObject *sender)
@@ -242,13 +249,6 @@ void Scatter3DController::handleAxisRangeChangedBySender(QObject *sender)
setSelectedItem(m_selectedItem, m_selectedItemSeries);
}
-void Scatter3DController::handleSeriesVisibilityChangedBySender(QObject *sender)
-{
- Abstract3DController::handleSeriesVisibilityChangedBySender(sender);
-
- adjustValueAxisRange();
-}
-
void Scatter3DController::handlePendingClick()
{
int index = m_renderer->clickedIndex();
@@ -333,7 +333,7 @@ void Scatter3DController::clearSelection()
setSelectedItem(invalidSelectionIndex(), 0);
}
-void Scatter3DController::adjustValueAxisRange()
+void Scatter3DController::adjustAxisRanges()
{
QValue3DAxis *valueAxisX = static_cast<QValue3DAxis *>(m_axisX);
QValue3DAxis *valueAxisY = static_cast<QValue3DAxis *>(m_axisY);
diff --git a/src/datavisualization/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h
index 53d24549..1194bc3a 100644
--- a/src/datavisualization/engine/scatter3dcontroller_p.h
+++ b/src/datavisualization/engine/scatter3dcontroller_p.h
@@ -108,8 +108,8 @@ public:
virtual void handleAxisAutoAdjustRangeChangedInOrientation(
QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust);
virtual void handleAxisRangeChangedBySender(QObject *sender);
- virtual void handleSeriesVisibilityChangedBySender(QObject *sender);
virtual void handlePendingClick();
+ virtual void adjustAxisRanges();
public slots:
void handleArrayReset();
@@ -125,7 +125,6 @@ protected:
virtual void startRecordingRemovesAndInserts();
private:
- void adjustValueAxisRange();
Q_DISABLE_COPY(Scatter3DController)
};
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index f5336832..c6e243a1 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -26,6 +26,7 @@
#include "utils_p.h"
#include "q3dlight.h"
#include "qscatter3dseries_p.h"
+#include "scatterseriesrendercache_p.h"
#include <QtGui/QMatrix4x4>
#include <QtGui/QMouseEvent>
@@ -83,15 +84,17 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_heightNormalizer(1.0f),
m_scaleFactor(0),
m_selectedItemIndex(Scatter3DController::invalidSelectionIndex()),
- m_selectedItemTotalIndex(Scatter3DController::invalidSelectionIndex()),
- m_selectedItemSeriesIndex(Scatter3DController::invalidSelectionIndex()),
- m_selectedSeries(0),
+ m_selectedSeriesCache(0),
m_areaSize(QSizeF(0.0, 0.0)),
m_dotSizeScale(1.0f),
m_hasHeightAdjustmentChanged(true),
m_backgroundMargin(defaultMaxSize),
m_maxItemSize(0.0f),
- m_clickedIndex(Scatter3DController::invalidSelectionIndex())
+ m_clickedIndex(Scatter3DController::invalidSelectionIndex()),
+ m_havePointSeries(false),
+ m_haveMeshSeries(false),
+ m_haveUniformColorMeshSeries(false),
+ m_haveGradientMeshSeries(false)
{
m_axisCacheY.setScale(2.0f);
m_axisCacheY.setTranslate(-1.0f);
@@ -159,32 +162,99 @@ void Scatter3DRenderer::initializeOpenGL()
loadBackgroundMesh();
}
-void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList,
- bool updateVisibility)
+void Scatter3DRenderer::updateData()
+{
+ calculateSceneScalingFactors();
+ float minX = float(m_axisCacheX.min());
+ float maxX = float(m_axisCacheX.max());
+ float minY = float(m_axisCacheY.min());
+ float maxY = float(m_axisCacheY.max());
+ float minZ = float(m_axisCacheZ.min());
+ float maxZ = float(m_axisCacheZ.max());
+ int totalDataSize = 0;
+
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ ScatterSeriesRenderCache *cache = static_cast<ScatterSeriesRenderCache *>(baseCache);
+ if (cache->isVisible() && cache->dataDirty()) {
+ const QScatter3DSeries *currentSeries = cache->series();
+ ScatterRenderItemArray &renderArray = cache->renderArray();
+ QScatterDataProxy *dataProxy = currentSeries->dataProxy();
+ const QScatterDataArray &dataArray = *dataProxy->array();
+ int dataSize = dataArray.size();
+ totalDataSize += dataSize;
+ if (dataSize != renderArray.size())
+ renderArray.resize(dataSize);
+
+ for (int i = 0; i < dataSize; i++) {
+ QVector3D dotPos = dataArray.at(i).position();
+ ScatterRenderItem &renderItem = renderArray[i];
+ if ((dotPos.x() >= minX && dotPos.x() <= maxX )
+ && (dotPos.y() >= minY && dotPos.y() <= maxY)
+ && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) {
+ renderItem.setPosition(dotPos);
+ renderItem.setVisible(true);
+ if (!dataArray.at(i).rotation().isIdentity())
+ renderItem.setRotation(dataArray.at(i).rotation().normalized());
+ else
+ renderItem.setRotation(identityQuaternion);
+ calculateTranslation(renderItem);
+ } else {
+ renderItem.setVisible(false);
+ }
+ }
+ cache->setDataDirty(false);
+ }
+ }
+
+ if (totalDataSize) {
+ m_dotSizeScale = GLfloat(qBound(defaultMinSize, 2.0f / float(qSqrt(qreal(totalDataSize))),
+ defaultMaxSize));
+ }
+
+ updateSelectedItem(m_selectedItemIndex,
+ m_selectedSeriesCache ? m_selectedSeriesCache->series() : 0);
+}
+
+void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList)
{
- Abstract3DRenderer::updateSeries(seriesList, updateVisibility);
+ Abstract3DRenderer::updateSeries(seriesList);
- int seriesCount = m_visibleSeriesList.size();
+ int seriesCount = seriesList.size();
float maxItemSize = 0.0f;
float itemSize = 0.0f;
+ bool noSelection = true;
- if (m_cachedItemSize.size() != seriesCount)
- m_cachedItemSize.resize(seriesCount);
+ m_havePointSeries = false;
+ m_haveMeshSeries = false;
+ m_haveUniformColorMeshSeries = false;
+ m_haveGradientMeshSeries = false;
- bool noSelection = true;
- for (int series = 0; series < seriesCount; series++) {
- QScatter3DSeries *scatterSeries =
- static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(series).series());
- itemSize = scatterSeries->itemSize();
- if (maxItemSize < itemSize)
- maxItemSize = itemSize;
- if (m_cachedItemSize.at(series) != itemSize)
- m_cachedItemSize[series] = itemSize;
- if (noSelection
- && scatterSeries->selectedItem() != QScatter3DSeries::invalidSelectionIndex()
- && m_selectionLabel != m_visibleSeriesList.at(series).itemLabel()) {
- m_selectionLabelDirty = true;
- noSelection = false;
+ for (int i = 0; i < seriesCount; i++) {
+ QScatter3DSeries *scatterSeries = static_cast<QScatter3DSeries *>(seriesList[i]);
+ if (scatterSeries->isVisible()) {
+ ScatterSeriesRenderCache *cache =
+ static_cast<ScatterSeriesRenderCache *>(m_renderCacheList.value(scatterSeries));
+ itemSize = scatterSeries->itemSize();
+ if (maxItemSize < itemSize)
+ maxItemSize = itemSize;
+ if (cache->itemSize() != itemSize)
+ cache->setItemSize(itemSize);
+ if (noSelection
+ && scatterSeries->selectedItem() != QScatter3DSeries::invalidSelectionIndex()
+ && m_selectionLabel != cache->itemLabel()) {
+ m_selectionLabelDirty = true;
+ noSelection = false;
+ }
+
+ if (cache->mesh() == QAbstract3DSeries::MeshPoint) {
+ m_havePointSeries = true;
+ } else {
+ m_haveMeshSeries = true;
+ if (cache->colorStyle() == Q3DTheme::ColorStyleUniform)
+ m_haveUniformColorMeshSeries = true;
+ else
+ m_haveGradientMeshSeries = true;
+ }
}
}
m_maxItemSize = maxItemSize;
@@ -197,53 +267,9 @@ void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
m_selectionLabelDirty = true;
}
-void Scatter3DRenderer::updateData()
+SeriesRenderCache *Scatter3DRenderer::createNewCache(QAbstract3DSeries *series)
{
- int seriesCount = m_visibleSeriesList.size();
- calculateSceneScalingFactors();
- float minX = float(m_axisCacheX.min());
- float maxX = float(m_axisCacheX.max());
- float minY = float(m_axisCacheY.min());
- float maxY = float(m_axisCacheY.max());
- float minZ = float(m_axisCacheZ.min());
- float maxZ = float(m_axisCacheZ.max());
- int totalDataSize = 0;
-
- if (m_renderingArrays.size() != seriesCount)
- m_renderingArrays.resize(seriesCount);
-
- for (int series = 0; series < seriesCount; series++) {
- QScatterDataProxy *dataProxy =
- static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(series).series())->dataProxy();
- const QScatterDataArray &dataArray = *dataProxy->array();
- int dataSize = dataArray.size();
- totalDataSize += dataSize;
-
- if (dataSize != m_renderingArrays.at(series).size())
- m_renderingArrays[series].resize(dataSize);
-
- for (int i = 0; i < dataSize; i++) {
- QVector3D dotPos = dataArray.at(i).position();
- ScatterRenderItem &renderItem = m_renderingArrays[series][i];
- if ((dotPos.x() >= minX && dotPos.x() <= maxX )
- && (dotPos.y() >= minY && dotPos.y() <= maxY)
- && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) {
- renderItem.setPosition(dotPos);
- renderItem.setVisible(true);
- if (!dataArray.at(i).rotation().isIdentity())
- renderItem.setRotation(dataArray.at(i).rotation().normalized());
- else
- renderItem.setRotation(identityQuaternion);
- calculateTranslation(renderItem);
- } else {
- renderItem.setVisible(false);
- }
- }
- }
- m_dotSizeScale = GLfloat(qBound(defaultMinSize, 2.0f / float(qSqrt(qreal(totalDataSize))),
- defaultMaxSize));
-
- updateSelectedItem(m_selectedItemIndex, m_selectedSeries);
+ return new ScatterSeriesRenderCache(series, this);
}
void Scatter3DRenderer::updateScene(Q3DScene *scene)
@@ -306,8 +332,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QMatrix4x4 viewMatrix = activeCamera->d_ptr->viewMatrix();
QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
- int seriesCount = m_visibleSeriesList.size();
-
// Calculate label flipping
if (viewMatrix.row(0).x() > 0)
m_zFlipped = false;
@@ -342,25 +366,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QMatrix4x4 depthProjectionMatrix;
QMatrix4x4 depthProjectionViewMatrix;
- // Check if we have any series with points
- bool havePointSeries = false;
- bool haveMeshSeries = false;
- bool haveUniformColorMeshSeries = false;
- bool haveGradientMeshSeries = false;
- for (int i = 0; i < seriesCount; i++) {
- if (m_visibleSeriesList.at(i).mesh() == QAbstract3DSeries::MeshPoint) {
- havePointSeries = true;
- } else {
- haveMeshSeries = true;
- if (m_visibleSeriesList.at(i).colorStyle() == Q3DTheme::ColorStyleUniform)
- haveUniformColorMeshSeries = true;
- else
- haveGradientMeshSeries = true;
- }
- }
-
#if !defined(QT_OPENGL_ES_2)
- if (havePointSeries) {
+ if (m_havePointSeries) {
glEnable(GL_POINT_SMOOTH);
glEnable(GL_PROGRAM_POINT_SIZE);
}
@@ -401,60 +408,63 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
depthProjectionViewMatrix = depthProjectionMatrix * depthViewMatrix;
// Draw dots to depth buffer
- for (int series = 0; series < seriesCount; series++) {
- ObjectHelper *dotObj = m_visibleSeriesList.at(series).object();
- QQuaternion seriesRotation = m_visibleSeriesList.at(series).meshRotation();
- bool drawingPoints = (m_visibleSeriesList.at(series).mesh() == QAbstract3DSeries::MeshPoint);
-
- float itemSize = m_cachedItemSize.at(series) / itemScaler;
- if (itemSize == 0.0f)
- itemSize = m_dotSizeScale;
- if (drawingPoints) {
- // Scale points based on shadow quality for shadows, not by zoom level
- glPointSize(itemSize * 100.0f * m_shadowQualityMultiplier);
- }
- QVector3D modelScaler(itemSize, itemSize, itemSize);
-
- for (int dot = 0; dot < m_renderingArrays.at(series).size(); dot++) {
- const ScatterRenderItem &item = m_renderingArrays.at(series).at(dot);
- if (!item.isVisible())
- continue;
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
-
- modelMatrix.translate(item.translation());
- if (!drawingPoints) {
- if (!seriesRotation.isIdentity() || !item.rotation().isIdentity())
- modelMatrix.rotate(seriesRotation * item.rotation());
- modelMatrix.scale(modelScaler);
- }
-
- MVPMatrix = depthProjectionViewMatrix * modelMatrix;
-
- m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
-
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ if (baseCache->isVisible()) {
+ ScatterSeriesRenderCache *cache = static_cast<ScatterSeriesRenderCache *>(baseCache);
+ ObjectHelper *dotObj = cache->object();
+ QQuaternion seriesRotation(cache->meshRotation());
+ const ScatterRenderItemArray &renderArray = cache->renderArray();
+ const int renderArraySize = renderArray.size();
+ bool drawingPoints = (cache->mesh() == QAbstract3DSeries::MeshPoint);
+ float itemSize = cache->itemSize() / itemScaler;
+ if (itemSize == 0.0f)
+ itemSize = m_dotSizeScale;
if (drawingPoints) {
- m_drawer->drawPoint(m_depthShader);
- } else {
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(m_depthShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, dotObj->vertexBuf());
- glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
- (void *)0);
-
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dotObj->elementBuf());
-
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, dotObj->indexCount(), GL_UNSIGNED_SHORT,
- (void *)0);
-
- // Free buffers
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glDisableVertexAttribArray(m_depthShader->posAtt());
+ // Scale points based on shadow quality for shadows, not by zoom level
+ glPointSize(itemSize * 100.0f * m_shadowQualityMultiplier);
+ }
+ QVector3D modelScaler(itemSize, itemSize, itemSize);
+ for (int dot = 0; dot < renderArraySize; dot++) {
+ const ScatterRenderItem &item = renderArray.at(dot);
+ if (!item.isVisible())
+ continue;
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(item.translation());
+ if (!drawingPoints) {
+ if (!seriesRotation.isIdentity() || !item.rotation().isIdentity())
+ modelMatrix.rotate(seriesRotation * item.rotation());
+ modelMatrix.scale(modelScaler);
+ }
+
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+
+ m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
+
+ if (drawingPoints) {
+ m_drawer->drawPoint(m_depthShader);
+ } else {
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, dotObj->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dotObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, dotObj->indexCount(), GL_UNSIGNED_SHORT,
+ (void *)0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_depthShader->posAtt());
+ }
}
}
}
@@ -481,7 +491,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Skip selection mode drawing if we have no selection mode
if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone
- && SelectOnScene == m_selectionState && seriesCount > 0) {
+ && SelectOnScene == m_selectionState && m_visibleSeriesCount > 0) {
// Draw dots to selection buffer
glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
glViewport(0, 0,
@@ -493,70 +503,67 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
- int arraySize = 0;
- int totalArraySize = 0;
- int dotNo = 0;
-
- // Init previous to opposite of first to ensure we change binding for first series
- bool previousDrawingPoints = (m_visibleSeriesList.at(0).mesh() != QAbstract3DSeries::MeshPoint);
- for (int series = 0; series < seriesCount; series++) {
- ObjectHelper *dotObj = m_visibleSeriesList.at(series).object();
- QQuaternion seriesRotation = m_visibleSeriesList.at(series).meshRotation();
- bool drawingPoints = (m_visibleSeriesList.at(series).mesh() == QAbstract3DSeries::MeshPoint);
-
- float itemSize = m_cachedItemSize.at(series) / itemScaler;
- if (itemSize == 0.0f)
- itemSize = m_dotSizeScale;
+ bool previousDrawingPoints = false;
+ int totalIndex = 0;
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ if (baseCache->isVisible()) {
+ ScatterSeriesRenderCache *cache =
+ static_cast<ScatterSeriesRenderCache *>(baseCache);
+ ObjectHelper *dotObj = cache->object();
+ QQuaternion seriesRotation(cache->meshRotation());
+ const ScatterRenderItemArray &renderArray = cache->renderArray();
+ const int renderArraySize = renderArray.size();
+ bool drawingPoints = (cache->mesh() == QAbstract3DSeries::MeshPoint);
+ float itemSize = cache->itemSize() / itemScaler;
+ if (itemSize == 0.0f)
+ itemSize = m_dotSizeScale;
#if !defined(QT_OPENGL_ES_2)
- if (drawingPoints)
- glPointSize(itemSize * activeCamera->zoomLevel()); // Scale points based on zoom
-#endif
- QVector3D modelScaler(itemSize, itemSize, itemSize);
-
- // Rebind selection shader if it has changed
- if (drawingPoints != previousDrawingPoints) {
- previousDrawingPoints = drawingPoints;
if (drawingPoints)
- selectionShader = pointSelectionShader;
- else
- selectionShader = m_selectionShader;
-
- selectionShader->bind();
- }
- arraySize = m_renderingArrays.at(series).size();
- totalArraySize += arraySize;
+ glPointSize(itemSize * activeCamera->zoomLevel()); // Scale points based on zoom
+#endif
+ QVector3D modelScaler(itemSize, itemSize, itemSize);
- if (totalArraySize > 0xfffffe) // Max possible different selection colors, 0xffffff being skipColor
- qFatal("Too many objects");
+ // Rebind selection shader if it has changed
+ if (!totalIndex || drawingPoints != previousDrawingPoints) {
+ previousDrawingPoints = drawingPoints;
+ if (drawingPoints)
+ selectionShader = pointSelectionShader;
+ else
+ selectionShader = m_selectionShader;
- for (int dot = 0; dot < arraySize; dot++) {
- const ScatterRenderItem &item = m_renderingArrays.at(series).at(dot);
- if (!item.isVisible())
- continue;
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
-
- modelMatrix.translate(item.translation());
- if (!drawingPoints) {
- if (!seriesRotation.isIdentity() || !item.rotation().isIdentity())
- modelMatrix.rotate(seriesRotation * item.rotation());
- modelMatrix.scale(modelScaler);
+ selectionShader->bind();
+ }
+ cache->setSelectionIndexOffset(totalIndex);
+ for (int dot = 0; dot < renderArraySize; dot++) {
+ const ScatterRenderItem &item = renderArray.at(dot);
+ if (!item.isVisible()) {
+ totalIndex++;
+ continue;
+ }
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(item.translation());
+ if (!drawingPoints) {
+ if (!seriesRotation.isIdentity() || !item.rotation().isIdentity())
+ modelMatrix.rotate(seriesRotation * item.rotation());
+ modelMatrix.scale(modelScaler);
+ }
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+
+ QVector4D dotColor = indexToSelectionColor(totalIndex++);
+ dotColor /= 255.0f;
+
+ selectionShader->setUniformValue(selectionShader->MVP(), MVPMatrix);
+ selectionShader->setUniformValue(selectionShader->color(), dotColor);
+
+ if (drawingPoints)
+ m_drawer->drawPoint(selectionShader);
+ else
+ m_drawer->drawSelectionObject(selectionShader, dotObj);
}
-
- MVPMatrix = projectionViewMatrix * modelMatrix;
-
- QVector4D dotColor = indexToSelectionColor(dotNo);
- dotColor /= 255.0f;
-
- selectionShader->setUniformValue(selectionShader->MVP(), MVPMatrix);
- selectionShader->setUniformValue(selectionShader->color(), dotColor);
-
- if (drawingPoints)
- m_drawer->drawPoint(selectionShader);
- else
- m_drawer->drawSelectionObject(selectionShader, dotObj);
- dotNo++;
}
}
@@ -584,15 +591,14 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
GLuint gradientTexture = 0;
bool dotSelectionFound = false;
ScatterRenderItem *selectedItem(0);
- int dotNo = 0;
QVector3D baseColor;
QVector3D dotColor;
bool previousDrawingPoints = false;
Q3DTheme::ColorStyle previousMeshColorStyle = Q3DTheme::ColorStyleUniform;
- if (haveMeshSeries) {
+ if (m_haveMeshSeries) {
// Set unchanging shader bindings
- if (haveGradientMeshSeries) {
+ if (m_haveGradientMeshSeries) {
m_dotGradientShader->bind();
m_dotGradientShader->setUniformValue(m_dotGradientShader->lightP(), lightPos);
m_dotGradientShader->setUniformValue(m_dotGradientShader->view(), viewMatrix);
@@ -600,7 +606,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
m_cachedTheme->ambientLightStrength());
m_dotGradientShader->setUniformValue(m_dotGradientShader->lightColor(), lightColor);
}
- if (haveUniformColorMeshSeries) {
+ if (m_haveUniformColorMeshSeries) {
m_dotShader->bind();
m_dotShader->setUniformValue(m_dotShader->lightP(), lightPos);
m_dotShader->setUniformValue(m_dotShader->view(), viewMatrix);
@@ -620,160 +626,170 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
dotShader->bind();
}
- for (int series = 0; series < seriesCount; series++) {
- const SeriesRenderCache &currentSeries = m_visibleSeriesList.at(series);
- QQuaternion seriesRotation = currentSeries.meshRotation();
- ObjectHelper *dotObj = currentSeries.object();
- bool drawingPoints = (currentSeries.mesh() == QAbstract3DSeries::MeshPoint);
- Q3DTheme::ColorStyle colorStyle = currentSeries.colorStyle();
- bool colorStyleIsUniform = (colorStyle == Q3DTheme::ColorStyleUniform);
- bool useColor = colorStyleIsUniform || drawingPoints;
-
- float itemSize = m_cachedItemSize.at(series) / itemScaler;
- if (itemSize == 0.0f)
- itemSize = m_dotSizeScale;
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ if (baseCache->isVisible()) {
+ ScatterSeriesRenderCache *cache =
+ static_cast<ScatterSeriesRenderCache *>(baseCache);
+ ObjectHelper *dotObj = cache->object();
+ QQuaternion seriesRotation(cache->meshRotation());
+ ScatterRenderItemArray &renderArray = cache->renderArray();
+ const int renderArraySize = renderArray.size();
+ bool selectedSeries = m_cachedSelectionMode > QAbstract3DGraph::SelectionNone
+ && (m_selectedSeriesCache == cache);
+ bool drawingPoints = (cache->mesh() == QAbstract3DSeries::MeshPoint);
+ Q3DTheme::ColorStyle colorStyle = cache->colorStyle();
+ bool colorStyleIsUniform = (colorStyle == Q3DTheme::ColorStyleUniform);
+ bool useColor = colorStyleIsUniform || drawingPoints;
+ bool rangeGradientPoints = drawingPoints
+ && (colorStyle == Q3DTheme::ColorStyleRangeGradient);
+ float itemSize = cache->itemSize() / itemScaler;
+ if (itemSize == 0.0f)
+ itemSize = m_dotSizeScale;
#if !defined(QT_OPENGL_ES_2)
- if (drawingPoints)
- glPointSize(itemSize * activeCamera->zoomLevel()); // Scale points based on zoom
+ if (drawingPoints)
+ glPointSize(itemSize * activeCamera->zoomLevel()); // Scale points based on zoom
#endif
- QVector3D modelScaler(itemSize, itemSize, itemSize);
-
- // Rebind shader if it has changed
- if (drawingPoints != previousDrawingPoints
- || (!drawingPoints &&
- (colorStyleIsUniform != (previousMeshColorStyle == Q3DTheme::ColorStyleUniform)))) {
- previousDrawingPoints = drawingPoints;
- if (drawingPoints) {
- dotShader = pointSelectionShader;
- } else {
- if (colorStyleIsUniform)
- dotShader = m_dotShader;
- else
- dotShader = m_dotGradientShader;
+ QVector3D modelScaler(itemSize, itemSize, itemSize);
+
+ // Rebind shader if it has changed
+ if (drawingPoints != previousDrawingPoints
+ || (!drawingPoints &&
+ (colorStyleIsUniform != (previousMeshColorStyle
+ == Q3DTheme::ColorStyleUniform)))) {
+ previousDrawingPoints = drawingPoints;
+ if (drawingPoints) {
+ dotShader = pointSelectionShader;
+ } else {
+ if (colorStyleIsUniform)
+ dotShader = m_dotShader;
+ else
+ dotShader = m_dotGradientShader;
+ }
+ dotShader->bind();
}
- dotShader->bind();
- }
- if (!drawingPoints && !colorStyleIsUniform && previousMeshColorStyle != colorStyle) {
- if (colorStyle == Q3DTheme::ColorStyleObjectGradient) {
- m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientMin(), 0.0f);
- m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientHeight(), 0.5f);
- } else {
- // Each ball is of uniform color according to its Y-coordinate
- m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientHeight(), 0.0f);
+ if (!drawingPoints && !colorStyleIsUniform && previousMeshColorStyle != colorStyle) {
+ if (colorStyle == Q3DTheme::ColorStyleObjectGradient) {
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientMin(), 0.0f);
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientHeight(),
+ 0.5f);
+ } else {
+ // Each dot is of uniform color according to its Y-coordinate
+ m_dotGradientShader->setUniformValue(m_dotGradientShader->gradientHeight(),
+ 0.0f);
+ }
}
- }
- if (!drawingPoints)
- previousMeshColorStyle = colorStyle;
+ if (!drawingPoints)
+ previousMeshColorStyle = colorStyle;
- if (useColor) {
- baseColor = currentSeries.baseColor();
- dotColor = baseColor;
- }
+ if (useColor) {
+ baseColor = cache->baseColor();
+ dotColor = baseColor;
+ }
+ for (int i = 0; i < renderArraySize; i++) {
+ ScatterRenderItem &item = renderArray[i];
+ if (!item.isVisible())
+ continue;
- int seriesSize = m_renderingArrays.at(series).size();
- for (int dot = 0; dot < seriesSize; dot++) {
- ScatterRenderItem &item = m_renderingArrays[series][dot];
- if (!item.isVisible())
- continue;
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- modelMatrix.translate(item.translation());
- if (!drawingPoints) {
- if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) {
- QQuaternion totalRotation = seriesRotation * item.rotation();
- modelMatrix.rotate(totalRotation);
- itModelMatrix.rotate(totalRotation);
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(item.translation());
+ if (!drawingPoints) {
+ if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) {
+ QQuaternion totalRotation = seriesRotation * item.rotation();
+ modelMatrix.rotate(totalRotation);
+ itModelMatrix.rotate(totalRotation);
+ }
+ modelMatrix.scale(modelScaler);
+ itModelMatrix.scale(modelScaler);
}
- modelMatrix.scale(modelScaler);
- itModelMatrix.scale(modelScaler);
- }
#ifdef SHOW_DEPTH_TEXTURE_SCENE
- MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
#else
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
#endif
- if (useColor)
- dotColor = baseColor;
- else
- gradientTexture = currentSeries.baseGradientTexture();
-
- GLfloat lightStrength = m_cachedTheme->lightStrength();
- if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone
- && (m_selectedItemTotalIndex == dotNo)) {
- if (useColor)
- dotColor = currentSeries.singleHighlightColor();
- else
- gradientTexture = currentSeries.singleHighlightGradientTexture();
- lightStrength = m_cachedTheme->highlightLightStrength();
- // Insert data to ScatterRenderItem. We have no ownership, don't delete the previous one
- selectedItem = &item;
- dotSelectionFound = true;
- // Save selected item size (adjusted with font size) for selection label positioning
- selectedItemSize = itemSize + (m_cachedTheme->font().pointSizeF() / 500.0f);
- }
-
- if (!drawingPoints) {
- // Set shader bindings
- dotShader->setUniformValue(dotShader->model(), modelMatrix);
- dotShader->setUniformValue(dotShader->nModel(),
- itModelMatrix.inverted().transposed());
- }
+ if (useColor) {
+ if (rangeGradientPoints) {
+ // Drawing points with range gradient
+ // Get color from gradient based on items y position converted to percent
+ int position = int(item.translation().y() * 50.0f) + 50;
+ dotColor = Utils::vectorFromColor(
+ cache->gradientImage().pixel(0, position));
+ } else {
+ dotColor = baseColor;
+ }
+ } else {
+ gradientTexture = cache->baseGradientTexture();
+ }
- dotShader->setUniformValue(dotShader->MVP(), MVPMatrix);
- if (useColor) {
- if (colorStyle == Q3DTheme::ColorStyleRangeGradient &&
- (m_selectedItemTotalIndex != dotNo)) {
- // Drawing points with range gradient
- // Get color from gradient based on items y position converted to percents
- int position = int(item.translation().y() * 50.0f) + 50;
- dotColor = Utils::vectorFromColor(
- currentSeries.gradientImage().pixel(0, position));
+ GLfloat lightStrength = m_cachedTheme->lightStrength();
+ if (selectedSeries && (m_selectedItemIndex == i)) {
+ if (useColor)
+ dotColor = cache->singleHighlightColor();
+ else
+ gradientTexture = cache->singleHighlightGradientTexture();
+ lightStrength = m_cachedTheme->highlightLightStrength();
+ // Insert data to ScatterRenderItem
+ // We don't have ownership, so don't delete the previous one
+ selectedItem = &item;
+ dotSelectionFound = true;
+ // Save selected item size (adjusted with font size) for selection label
+ // positioning
+ selectedItemSize = itemSize + (m_cachedTheme->font().pointSizeF() / 500.0f);
}
- dotShader->setUniformValue(dotShader->color(), dotColor);
- } else if (colorStyle == Q3DTheme::ColorStyleRangeGradient) {
- dotShader->setUniformValue(dotShader->gradientMin(),
- (item.translation().y() + 1.0f) / 2.0f);
- }
-#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+
if (!drawingPoints) {
- // Set shadow shader bindings
- QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
- dotShader->setUniformValue(dotShader->shadowQ(), m_shadowQualityToShader);
- dotShader->setUniformValue(dotShader->depth(), depthMVPMatrix);
- dotShader->setUniformValue(dotShader->lightS(), lightStrength / 10.0f);
+ // Set shader bindings
+ dotShader->setUniformValue(dotShader->model(), modelMatrix);
+ dotShader->setUniformValue(dotShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ }
- // Draw the object
- m_drawer->drawObject(dotShader, dotObj, gradientTexture, m_depthTexture);
- } else {
- // Draw the object
- m_drawer->drawPoint(dotShader);
+ dotShader->setUniformValue(dotShader->MVP(), MVPMatrix);
+ if (useColor) {
+ dotShader->setUniformValue(dotShader->color(), dotColor);
+ } else if (colorStyle == Q3DTheme::ColorStyleRangeGradient) {
+ dotShader->setUniformValue(dotShader->gradientMin(),
+ (item.translation().y() + 1.0f) / 2.0f);
}
- } else
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ if (!drawingPoints) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ dotShader->setUniformValue(dotShader->shadowQ(), m_shadowQualityToShader);
+ dotShader->setUniformValue(dotShader->depth(), depthMVPMatrix);
+ dotShader->setUniformValue(dotShader->lightS(), lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(dotShader, dotObj, gradientTexture, m_depthTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawPoint(dotShader);
+ }
+ } else
#endif
- {
- if (!drawingPoints) {
- // Set shadowless shader bindings
- dotShader->setUniformValue(dotShader->lightS(), lightStrength);
- // Draw the object
- m_drawer->drawObject(dotShader, dotObj, gradientTexture);
- } else {
- // Draw the object
- m_drawer->drawPoint(dotShader);
+ {
+ if (!drawingPoints) {
+ // Set shadowless shader bindings
+ dotShader->setUniformValue(dotShader->lightS(), lightStrength);
+ // Draw the object
+ m_drawer->drawObject(dotShader, dotObj, gradientTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawPoint(dotShader);
+ }
}
}
- dotNo++;
}
}
#if !defined(QT_OPENGL_ES_2)
- if (havePointSeries) {
+ if (m_havePointSeries) {
glDisable(GL_POINT_SMOOTH);
glDisable(GL_PROGRAM_POINT_SIZE);
}
@@ -1263,7 +1279,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
|| !labelItem.textureId() || m_selectionLabelDirty) {
QString labelText = selectionLabel();
if (labelText.isNull() || m_selectionLabelDirty) {
- labelText = m_visibleSeriesList[m_selectedItemSeriesIndex].itemLabel();
+ labelText = m_selectedSeriesCache->itemLabel();
setSelectionLabel(labelText);
m_selectionLabelDirty = false;
}
@@ -1505,26 +1521,18 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
glDisable(GL_POLYGON_OFFSET_FILL);
}
-void Scatter3DRenderer::updateSelectedItem(int index, const QScatter3DSeries *series)
+void Scatter3DRenderer::updateSelectedItem(int index, QScatter3DSeries *series)
{
m_selectionDirty = true;
m_selectionLabelDirty = true;
- m_selectedSeries = series;
+ m_selectedSeriesCache =
+ static_cast<ScatterSeriesRenderCache *>(m_renderCacheList.value(series, 0));
m_selectedItemIndex = Scatter3DController::invalidSelectionIndex();
- m_selectedItemTotalIndex = Scatter3DController::invalidSelectionIndex();
- m_selectedItemSeriesIndex = Scatter3DController::invalidSelectionIndex();
- if (!m_renderingArrays.isEmpty() && index != Scatter3DController::invalidSelectionIndex()) {
- int totalIndex = 0;
- for (int i = 0; i < m_visibleSeriesList.size(); i++) {
- if (m_visibleSeriesList.at(i).series() == series) {
- m_selectedItemSeriesIndex = i;
- m_selectedItemIndex = index;
- m_selectedItemTotalIndex = index + totalIndex;
- break;
- }
- totalIndex += m_renderingArrays.at(i).size();
- }
+ if (m_selectedSeriesCache) {
+ const ScatterRenderItemArray &renderArray = m_selectedSeriesCache->renderArray();
+ if (index < renderArray.size() && index >= 0)
+ m_selectedItemIndex = index;
}
}
@@ -1767,17 +1775,22 @@ void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector4D &color,
index = Scatter3DController::invalidSelectionIndex();
m_clickedType = QAbstract3DGraph::ElementAxisYLabel;
} else {
- index = int(color.x())
+ int totalIndex = int(color.x())
+ (int(color.y()) << 8)
+ (int(color.z()) << 16);
// Find the series and adjust the index accordingly
- for (int i = 0; i < m_renderingArrays.size(); i++) {
- if (index < m_renderingArrays.at(i).size()) {
- series = m_visibleSeriesList.at(i).series();
- m_clickedType = QAbstract3DGraph::ElementSeries;
- return; // Valid found and already set to return parameters, so we can return
- } else {
- index -= m_renderingArrays.at(i).size();
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ if (baseCache->isVisible()) {
+ ScatterSeriesRenderCache *cache =
+ static_cast<ScatterSeriesRenderCache *>(baseCache);
+ int offset = cache->selectionIndexOffset();
+ if (totalIndex >= offset
+ && totalIndex < (offset + cache->renderArray().size())) {
+ index = totalIndex - offset;
+ series = cache->series();
+ m_clickedType = QAbstract3DGraph::ElementSeries;
+ return;
+ }
}
}
}
diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h
index 8b4d0759..ab45381e 100644
--- a/src/datavisualization/engine/scatter3drenderer_p.h
+++ b/src/datavisualization/engine/scatter3drenderer_p.h
@@ -46,6 +46,7 @@ class ObjectHelper;
class LabelItem;
class Q3DScene;
class QAbstractAxisPrivate;
+class ScatterSeriesRenderCache;
class QT_DATAVISUALIZATION_EXPORT Scatter3DRenderer : public Abstract3DRenderer
{
@@ -83,26 +84,27 @@ private:
GLfloat m_heightNormalizer;
GLfloat m_scaleFactor;
int m_selectedItemIndex;
- int m_selectedItemTotalIndex;
- int m_selectedItemSeriesIndex;
- const QScatter3DSeries *m_selectedSeries;
+ ScatterSeriesRenderCache *m_selectedSeriesCache;
QSizeF m_areaSize;
GLfloat m_dotSizeScale;
QVector3D m_translationOffset;
bool m_hasHeightAdjustmentChanged;
ScatterRenderItem m_dummyRenderItem;
- QVector<ScatterRenderItemArray> m_renderingArrays;
GLfloat m_backgroundMargin;
GLfloat m_maxItemSize;
- QVector<float> m_cachedItemSize;
int m_clickedIndex;
+ bool m_havePointSeries;
+ bool m_haveMeshSeries;
+ bool m_haveUniformColorMeshSeries;
+ bool m_haveGradientMeshSeries;
public:
explicit Scatter3DRenderer(Scatter3DController *controller);
~Scatter3DRenderer();
- void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility);
void updateData();
+ void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
+ SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
void updateScene(Q3DScene *scene);
inline int clickedIndex() const { return m_clickedIndex; }
@@ -145,7 +147,7 @@ private:
friend class ScatterRenderItem;
public slots:
- void updateSelectedItem(int index, const QScatter3DSeries *series);
+ void updateSelectedItem(int index, QScatter3DSeries *series);
private:
QVector4D indexToSelectionColor(GLint index);
diff --git a/src/datavisualization/engine/scatterseriesrendercache.cpp b/src/datavisualization/engine/scatterseriesrendercache.cpp
new file mode 100644
index 00000000..2a2c5393
--- /dev/null
+++ b/src/datavisualization/engine/scatterseriesrendercache.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "scatterseriesrendercache_p.h"
+#include "scatter3drenderer_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+ScatterSeriesRenderCache::ScatterSeriesRenderCache(QAbstract3DSeries *series,
+ Abstract3DRenderer *renderer)
+ : SeriesRenderCache(series, renderer),
+ m_itemSize(0.0f),
+ m_selectionIndexOffset(0)
+{
+}
+
+ScatterSeriesRenderCache::~ScatterSeriesRenderCache()
+{
+}
+
+void ScatterSeriesRenderCache::cleanup(TextureHelper *texHelper)
+{
+ m_renderArray.clear();
+
+ SeriesRenderCache::cleanup(texHelper);
+}
+
+QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/scatterseriesrendercache_p.h b/src/datavisualization/engine/scatterseriesrendercache_p.h
new file mode 100644
index 00000000..b2e2d55f
--- /dev/null
+++ b/src/datavisualization/engine/scatterseriesrendercache_p.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef SCATTERSERIESRENDERCACHE_P_H
+#define SCATTERSERIESRENDERCACHE_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "seriesrendercache_p.h"
+#include "qscatter3dseries_p.h"
+#include "scatterrenderitem_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class ScatterSeriesRenderCache : public SeriesRenderCache
+{
+public:
+ ScatterSeriesRenderCache(QAbstract3DSeries *series, Abstract3DRenderer *renderer);
+ virtual ~ScatterSeriesRenderCache();
+
+ void cleanup(TextureHelper *texHelper);
+
+ inline ScatterRenderItemArray &renderArray() { return m_renderArray; }
+ inline QScatter3DSeries *series() const { return static_cast<QScatter3DSeries *>(m_series); }
+ inline void setItemSize(float size) { m_itemSize = size; }
+ inline float itemSize() const { return m_itemSize; }
+ inline void setSelectionIndexOffset(int offset) { m_selectionIndexOffset = offset; }
+ inline int selectionIndexOffset() const { return m_selectionIndexOffset; }
+
+protected:
+ ScatterRenderItemArray m_renderArray;
+ float m_itemSize;
+ int m_selectionIndexOffset; // Temporarily cached value for selection color calculations
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif
diff --git a/src/datavisualization/engine/seriesrendercache.cpp b/src/datavisualization/engine/seriesrendercache.cpp
index 7e51df1e..e674ae43 100644
--- a/src/datavisualization/engine/seriesrendercache.cpp
+++ b/src/datavisualization/engine/seriesrendercache.cpp
@@ -26,15 +26,19 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
const QString smoothString(QStringLiteral("Smooth"));
-SeriesRenderCache::SeriesRenderCache()
- : m_series(0),
+SeriesRenderCache::SeriesRenderCache(QAbstract3DSeries *series, Abstract3DRenderer *renderer)
+ : m_series(series),
m_object(0),
m_mesh(QAbstract3DSeries::MeshCube),
m_baseUniformTexture(0),
m_baseGradientTexture(0),
m_gradientImage(0),
m_singleHighlightGradientTexture(0),
- m_multiHighlightGradientTexture(0)
+ m_multiHighlightGradientTexture(0),
+ m_valid(false),
+ m_visible(false),
+ m_renderer(renderer),
+ m_objectDirty(true)
{
}
@@ -42,22 +46,13 @@ SeriesRenderCache::~SeriesRenderCache()
{
}
-void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *renderer)
+void SeriesRenderCache::populate(bool newSeries)
{
- Q_ASSERT(series);
+ QAbstract3DSeriesChangeBitField &changeTracker = m_series->d_ptr->m_changeTracker;
- bool seriesChanged = false;
-
- if (m_series != series) {
- m_series = series;
- seriesChanged = true;
- }
-
- QAbstract3DSeriesChangeBitField &changeTracker = series->d_ptr->m_changeTracker;
-
- if (seriesChanged || changeTracker.meshChanged || changeTracker.meshSmoothChanged
+ if (newSeries || changeTracker.meshChanged || changeTracker.meshSmoothChanged
|| changeTracker.userDefinedMeshChanged) {
- m_mesh = series->mesh();
+ m_mesh = m_series->mesh();
changeTracker.meshChanged = false;
changeTracker.meshSmoothChanged = false;
changeTracker.userDefinedMeshChanged = false;
@@ -67,7 +62,7 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *
// Compose mesh filename
if (m_mesh == QAbstract3DSeries::MeshUserDefined) {
// Always use the supplied mesh directly
- meshFileName = series->userDefinedMesh();
+ meshFileName = m_series->userDefinedMesh();
} else {
switch (m_mesh) {
case QAbstract3DSeries::MeshBar:
@@ -107,11 +102,11 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *
break;
}
- if (series->isMeshSmooth() && m_mesh != QAbstract3DSeries::MeshPoint)
+ if (m_series->isMeshSmooth() && m_mesh != QAbstract3DSeries::MeshPoint)
meshFileName += smoothString;
// Give renderer an opportunity to customize the mesh
- renderer->fixMeshFileName(meshFileName, m_mesh);
+ m_renderer->fixMeshFileName(meshFileName, m_mesh);
}
delete m_object;
@@ -123,8 +118,8 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *
}
}
- if (seriesChanged || changeTracker.meshRotationChanged) {
- m_meshRotation = series->meshRotation().normalized();
+ if (newSeries || changeTracker.meshRotationChanged) {
+ m_meshRotation = m_series->meshRotation().normalized();
if (m_series->type() == QAbstract3DSeries::SeriesTypeBar
&& (m_meshRotation.x() || m_meshRotation.z())) {
m_meshRotation = identityQuaternion;
@@ -132,63 +127,68 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *
changeTracker.meshRotationChanged = false;
}
- if (seriesChanged || changeTracker.colorStyleChanged) {
- m_colorStyle = series->colorStyle();
+ if (newSeries || changeTracker.colorStyleChanged) {
+ m_colorStyle = m_series->colorStyle();
changeTracker.colorStyleChanged = false;
}
- if (seriesChanged || changeTracker.baseColorChanged) {
- m_baseColor = Utils::vectorFromColor(series->baseColor());
+ if (newSeries || changeTracker.baseColorChanged) {
+ m_baseColor = Utils::vectorFromColor(m_series->baseColor());
if (m_series->type() == QAbstract3DSeries::SeriesTypeSurface)
- renderer->generateBaseColorTexture(series->baseColor(), &m_baseUniformTexture);
+ m_renderer->generateBaseColorTexture(m_series->baseColor(), &m_baseUniformTexture);
changeTracker.baseColorChanged = false;
}
- if (seriesChanged || changeTracker.baseGradientChanged) {
- QLinearGradient gradient = series->baseGradient();
+ if (newSeries || changeTracker.baseGradientChanged) {
+ QLinearGradient gradient = m_series->baseGradient();
m_gradientImage = Utils::getGradientImage(gradient);
- renderer->fixGradientAndGenerateTexture(&gradient, &m_baseGradientTexture);
+ m_renderer->fixGradientAndGenerateTexture(&gradient, &m_baseGradientTexture);
changeTracker.baseGradientChanged = false;
}
- if (seriesChanged || changeTracker.singleHighlightColorChanged) {
- m_singleHighlightColor = Utils::vectorFromColor(series->singleHighlightColor());
+ if (newSeries || changeTracker.singleHighlightColorChanged) {
+ m_singleHighlightColor = Utils::vectorFromColor(m_series->singleHighlightColor());
changeTracker.singleHighlightColorChanged = false;
}
- if (seriesChanged || changeTracker.singleHighlightGradientChanged) {
- QLinearGradient gradient = series->singleHighlightGradient();
- renderer->fixGradientAndGenerateTexture(&gradient, &m_singleHighlightGradientTexture);
+ if (newSeries || changeTracker.singleHighlightGradientChanged) {
+ QLinearGradient gradient = m_series->singleHighlightGradient();
+ m_renderer->fixGradientAndGenerateTexture(&gradient, &m_singleHighlightGradientTexture);
changeTracker.singleHighlightGradientChanged = false;
}
- if (seriesChanged || changeTracker.multiHighlightColorChanged) {
- m_multiHighlightColor = Utils::vectorFromColor(series->multiHighlightColor());
+ if (newSeries || changeTracker.multiHighlightColorChanged) {
+ m_multiHighlightColor = Utils::vectorFromColor(m_series->multiHighlightColor());
changeTracker.multiHighlightColorChanged = false;
}
- if (seriesChanged || changeTracker.multiHighlightGradientChanged) {
- QLinearGradient gradient = series->multiHighlightGradient();
- renderer->fixGradientAndGenerateTexture(&gradient, &m_multiHighlightGradientTexture);
+ if (newSeries || changeTracker.multiHighlightGradientChanged) {
+ QLinearGradient gradient = m_series->multiHighlightGradient();
+ m_renderer->fixGradientAndGenerateTexture(&gradient, &m_multiHighlightGradientTexture);
changeTracker.multiHighlightGradientChanged = false;
}
- if (seriesChanged || changeTracker.nameChanged) {
- m_name = series->name();
+ if (newSeries || changeTracker.nameChanged) {
+ m_name = m_series->name();
changeTracker.nameChanged = false;
}
- if (seriesChanged || changeTracker.itemLabelChanged
+ if (newSeries || changeTracker.itemLabelChanged
|| changeTracker.itemLabelVisibilityChanged) {
changeTracker.itemLabelChanged = false;
changeTracker.itemLabelVisibilityChanged = false;
// series->itemLabel() call resolves the item label and emits the changed signal
// if it is dirty, so we need to call it even if m_itemLabel is eventually set
// to an empty string.
- m_itemLabel = series->itemLabel();
- if (!series->isItemLabelVisible())
+ m_itemLabel = m_series->itemLabel();
+ if (!m_series->isItemLabelVisible())
m_itemLabel = QString();
}
+
+ if (newSeries || changeTracker.visibilityChanged) {
+ m_visible = m_series->isVisible();
+ changeTracker.visibilityChanged = false;
+ }
}
void SeriesRenderCache::cleanup(TextureHelper *texHelper)
diff --git a/src/datavisualization/engine/seriesrendercache_p.h b/src/datavisualization/engine/seriesrendercache_p.h
index a6ae03cf..8536d501 100644
--- a/src/datavisualization/engine/seriesrendercache_p.h
+++ b/src/datavisualization/engine/seriesrendercache_p.h
@@ -41,10 +41,10 @@ class TextureHelper;
class SeriesRenderCache
{
public:
- SeriesRenderCache();
+ SeriesRenderCache(QAbstract3DSeries *series, Abstract3DRenderer *renderer);
virtual ~SeriesRenderCache();
- void populate(QAbstract3DSeries *series, Abstract3DRenderer *renderer);
+ virtual void populate(bool newSeries);
virtual void cleanup(TextureHelper *texHelper);
// NOTE: Series pointer can only be used to access the series when syncing with controller.
@@ -66,6 +66,11 @@ public:
inline const GLuint &multiHighlightGradientTexture() const { return m_multiHighlightGradientTexture; }
inline const QString &name() const { return m_name; }
inline const QString &itemLabel() const { return m_itemLabel; }
+ inline void setValid(bool valid) { m_valid = valid; }
+ inline bool isValid() const { return m_valid; }
+ inline bool isVisible() const { return m_visible; }
+ inline void setDataDirty(bool state) { m_objectDirty = state; }
+ inline bool dataDirty() const { return m_objectDirty; }
protected:
QAbstract3DSeries *m_series;
@@ -85,6 +90,10 @@ protected:
QString m_name;
QString m_itemLabel;
+ bool m_valid;
+ bool m_visible;
+ Abstract3DRenderer *m_renderer;
+ bool m_objectDirty;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp
index 683a214a..591cbdda 100644
--- a/src/datavisualization/engine/surface3dcontroller.cpp
+++ b/src/datavisualization/engine/surface3dcontroller.cpp
@@ -66,11 +66,6 @@ void Surface3DController::synchDataToRenderer()
if (!isInitialized())
return;
- if (m_changedSeriesList.size()) {
- m_renderer->modifiedSeriesList(m_changedSeriesList);
- m_changedSeriesList.clear();
- }
-
Abstract3DController::synchDataToRenderer();
// Notify changes to renderer
@@ -98,7 +93,7 @@ void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation(
Q_UNUSED(orientation)
Q_UNUSED(autoAdjust)
- adjustValueAxisRange();
+ adjustAxisRanges();
}
void Surface3DController::handleAxisRangeChangedBySender(QObject *sender)
@@ -113,8 +108,6 @@ void Surface3DController::handleSeriesVisibilityChangedBySender(QObject *sender)
{
Abstract3DController::handleSeriesVisibilityChangedBySender(sender);
- adjustValueAxisRange();
-
// Visibility changes may require disabling slicing,
// so just reset selection to ensure everything is still valid.
setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
@@ -150,9 +143,6 @@ void Surface3DController::addSeries(QAbstract3DSeries *series)
Abstract3DController::addSeries(series);
- if (series->isVisible())
- adjustValueAxisRange();
-
QSurface3DSeries *surfaceSeries = static_cast<QSurface3DSeries *>(series);
if (surfaceSeries->selectedPoint() != invalidSelectionPosition())
setSelectedPoint(surfaceSeries->selectedPoint(), surfaceSeries, false);
@@ -168,7 +158,7 @@ void Surface3DController::removeSeries(QAbstract3DSeries *series)
setSelectedPoint(invalidSelectionPosition(), 0, false);
if (wasVisible)
- adjustValueAxisRange();
+ adjustAxisRanges();
}
QList<QSurface3DSeries *> Surface3DController::surfaceSeriesList()
@@ -292,11 +282,12 @@ void Surface3DController::handleArrayReset()
{
QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(sender())->series();
if (series->isVisible()) {
- adjustValueAxisRange();
- if (!m_changedSeriesList.contains(series))
- m_changedSeriesList.append(series);
+ adjustAxisRanges();
m_isDataDirty = true;
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
+
// Clear selection unless still valid
setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
series->d_ptr->markItemLabelDirty();
@@ -345,7 +336,7 @@ void Surface3DController::handleRowsChanged(int startIndex, int count)
if (m_changedRows.size()) {
m_changeTracker.rowsChanged = true;
- adjustValueAxisRange();
+ adjustAxisRanges();
// Clear selection unless still valid
setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
emitNeedRender();
@@ -373,7 +364,7 @@ void Surface3DController::handleItemChanged(int rowIndex, int columnIndex)
if (series == m_selectedSeries && m_selectedPoint == candidate)
series->d_ptr->markItemLabelDirty();
- adjustValueAxisRange();
+ adjustAxisRanges();
// Clear selection unless still valid
setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
emitNeedRender();
@@ -386,11 +377,11 @@ void Surface3DController::handleRowsAdded(int startIndex, int count)
Q_UNUSED(count)
QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(sender())->series();
if (series->isVisible()) {
- adjustValueAxisRange();
+ adjustAxisRanges();
m_isDataDirty = true;
- if (!m_changedSeriesList.contains(series))
- m_changedSeriesList.append(series);
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
@@ -409,11 +400,11 @@ void Surface3DController::handleRowsInserted(int startIndex, int count)
}
if (series->isVisible()) {
- adjustValueAxisRange();
+ adjustAxisRanges();
m_isDataDirty = true;
- if (!m_changedSeriesList.contains(series))
- m_changedSeriesList.append(series);
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
@@ -437,16 +428,16 @@ void Surface3DController::handleRowsRemoved(int startIndex, int count)
}
if (series->isVisible()) {
- adjustValueAxisRange();
+ adjustAxisRanges();
m_isDataDirty = true;
- if (!m_changedSeriesList.contains(series))
- m_changedSeriesList.append(series);
}
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
emitNeedRender();
}
-void Surface3DController::adjustValueAxisRange()
+void Surface3DController::adjustAxisRanges()
{
QValue3DAxis *valueAxisX = static_cast<QValue3DAxis *>(m_axisX);
QValue3DAxis *valueAxisY = static_cast<QValue3DAxis *>(m_axisY);
diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h
index 14c0dd40..b742b6bb 100644
--- a/src/datavisualization/engine/surface3dcontroller_p.h
+++ b/src/datavisualization/engine/surface3dcontroller_p.h
@@ -77,7 +77,6 @@ private:
bool m_flatShadingSupported;
QVector<ChangeItem> m_changedItems;
QVector<ChangeRow> m_changedRows;
- QVector<QSurface3DSeries *> m_changedSeriesList;
public:
explicit Surface3DController(QRect rect, Q3DScene *scene = 0);
@@ -97,6 +96,7 @@ public:
virtual void handleAxisRangeChangedBySender(QObject *sender);
virtual void handleSeriesVisibilityChangedBySender(QObject *sender);
virtual void handlePendingClick();
+ virtual void adjustAxisRanges();
static QPoint invalidSelectionPosition();
bool isFlatShadingSupported();
@@ -119,8 +119,6 @@ signals:
void selectedSeriesChanged(QSurface3DSeries *series);
private:
- void adjustValueAxisRange();
-
Q_DISABLE_COPY(Surface3DController)
};
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 9e591383..9e5f0b37 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -144,12 +144,6 @@ Surface3DRenderer::~Surface3DRenderer()
delete m_gridLineObj;
#endif
delete m_labelObj;
-
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
- cache->cleanup(m_textureHelper);
- delete cache;
- }
- m_renderCacheList.clear();
}
void Surface3DRenderer::initializeOpenGL()
@@ -194,22 +188,25 @@ void Surface3DRenderer::updateData()
{
calculateSceneScalingFactors();
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
- const QSurface3DSeries *currentSeries = cache->series();
- QSurfaceDataProxy *dataProxy = currentSeries->dataProxy();
- const QSurfaceDataArray &array = *dataProxy->array();
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
+ if (cache->isVisible() && cache->dataDirty()) {
+ const QSurface3DSeries *currentSeries = cache->series();
+ QSurfaceDataProxy *dataProxy = currentSeries->dataProxy();
+ const QSurfaceDataArray &array = *dataProxy->array();
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ QRect sampleSpace;
- // Need minimum of 2x2 array to draw a surface
- if (array.size() >= 2 && array.at(0)->size() >= 2) {
- QRect sampleSpace = calculateSampleRect(array);
+ // Need minimum of 2x2 array to draw a surface
+ if (array.size() >= 2 && array.at(0)->size() >= 2)
+ sampleSpace = calculateSampleRect(array);
- QSurfaceDataArray &dataArray = cache->dataArray();
- bool dimensionChanged = false;
+ bool dimensionsChanged = false;
if (cache->sampleSpace() != sampleSpace) {
if (sampleSpace.width() >= 2)
m_selectionTexturesDirty = true;
- dimensionChanged = true;
+ dimensionsChanged = true;
cache->setSampleSpace(sampleSpace);
for (int i = 0; i < dataArray.size(); i++)
@@ -218,7 +215,7 @@ void Surface3DRenderer::updateData()
}
if (sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
- if (dimensionChanged) {
+ if (dimensionsChanged) {
dataArray.reserve(sampleSpace.height());
for (int i = 0; i < sampleSpace.height(); i++)
dataArray << new QSurfaceDataRow(sampleSpace.width());
@@ -230,13 +227,13 @@ void Surface3DRenderer::updateData()
}
}
- if (dataArray.size() > 0 && (cache->objectDirty() || dimensionChanged)) {
- checkFlatSupport(cache);
- updateObjects(cache, dimensionChanged);
- cache->setObjectDirty(false);
- cache->setFlatStatusDirty(false);
- }
+ checkFlatSupport(cache);
+ updateObjects(cache, dimensionsChanged);
+ cache->setFlatStatusDirty(false);
+ } else {
+ cache->surfaceObject()->clear();
}
+ cache->setDataDirty(false);
}
}
@@ -246,26 +243,15 @@ void Surface3DRenderer::updateData()
updateSelectedPoint(m_selectedPoint, m_selectedSeries);
}
-void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList,
- bool updateVisibility)
+void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList)
{
- Q_UNUSED(updateVisibility);
-
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList)
- cache->setValid(false);
+ Abstract3DRenderer::updateSeries(seriesList);
bool noSelection = true;
foreach (QAbstract3DSeries *series, seriesList) {
QSurface3DSeries *surfaceSeries = static_cast<QSurface3DSeries *>(series);
- SurfaceSeriesRenderCache *cache = m_renderCacheList.value(surfaceSeries);
- if (!cache) {
- cache = new SurfaceSeriesRenderCache(this);
- m_renderCacheList[surfaceSeries] = cache;
- m_selectionTexturesDirty = true;
- }
- cache->setValid(true);
- cache->populate(surfaceSeries, this);
-
+ SurfaceSeriesRenderCache *cache =
+ static_cast<SurfaceSeriesRenderCache *>( m_renderCacheList.value(series));
if (noSelection
&& surfaceSeries->selectedPoint() != QSurface3DSeries::invalidSelectionPosition()
&& selectionLabel() != cache->itemLabel()) {
@@ -280,26 +266,15 @@ void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
}
}
- if (noSelection && !selectionLabel().isEmpty())
+ if (noSelection && !selectionLabel().isEmpty()) {
m_selectionLabelDirty = true;
-
- // Remove non-valid objects from the cache list
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
- if (!cache->isValid()) {
- if (cache->series() == m_selectedSeries)
- updateSelectedPoint(Surface3DController::invalidSelectionPosition(), 0);
-
- m_renderCacheList.remove(cache->series());
- cache->cleanup(m_textureHelper);
- delete cache;
-
- m_selectionTexturesDirty = true;
- }
+ updateSelectedPoint(Surface3DController::invalidSelectionPosition(), 0);
}
// Selection pointer issues
if (m_selectedSeries) {
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
QVector3D highlightColor =
Utils::vectorFromColor(cache->series()->singleHighlightColor());
SelectionPointer *slicePointer = cache->sliceSelectionPointer();
@@ -318,19 +293,23 @@ void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
}
}
-void Surface3DRenderer::modifiedSeriesList(const QVector<QSurface3DSeries *> &seriesList)
+SeriesRenderCache *Surface3DRenderer::createNewCache(QAbstract3DSeries *series)
{
- foreach (QSurface3DSeries *series, seriesList) {
- SurfaceSeriesRenderCache *cache = m_renderCacheList.value(series);
- if (cache)
- cache->setObjectDirty(true);
- }
+ m_selectionTexturesDirty = true;
+ return new SurfaceSeriesRenderCache(series, this);
+}
+
+void Surface3DRenderer::cleanCache(SeriesRenderCache *cache)
+{
+ Abstract3DRenderer::cleanCache(cache);
+ m_selectionTexturesDirty = true;
}
void Surface3DRenderer::updateRows(const QVector<Surface3DController::ChangeRow> &rows)
{
foreach (Surface3DController::ChangeRow item, rows) {
- SurfaceSeriesRenderCache *cache = m_renderCacheList.value(item.series);
+ SurfaceSeriesRenderCache *cache =
+ static_cast<SurfaceSeriesRenderCache *>(m_renderCacheList.value(item.series));
QSurfaceDataArray &dstArray = cache->dataArray();
const QRect &sampleSpace = cache->sampleSpace();
@@ -367,7 +346,8 @@ void Surface3DRenderer::updateRows(const QVector<Surface3DController::ChangeRow>
void Surface3DRenderer::updateItem(const QVector<Surface3DController::ChangeItem> &points)
{
foreach (Surface3DController::ChangeItem item, points) {
- SurfaceSeriesRenderCache *cache = m_renderCacheList.value(item.series);
+ SurfaceSeriesRenderCache *cache =
+ static_cast<SurfaceSeriesRenderCache *>(m_renderCacheList.value(item.series));
QSurfaceDataArray &dstArray = cache->dataArray();
const QRect &sampleSpace = cache->sampleSpace();
@@ -404,38 +384,22 @@ void Surface3DRenderer::updateItem(const QVector<Surface3DController::ChangeItem
updateSelectedPoint(m_selectedPoint, m_selectedSeries);
}
-void Surface3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min,
- float max)
-{
- Abstract3DRenderer::updateAxisRange(orientation, min, max);
-
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList)
- cache->setObjectDirty(true);
-}
-
-void Surface3DRenderer::updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation,
- QValue3DAxisFormatter *formatter)
-{
- Abstract3DRenderer::updateAxisFormatter(orientation, formatter);
-
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList)
- cache->setObjectDirty(true);
-}
-
void Surface3DRenderer::updateSliceDataModel(const QPoint &point)
{
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList)
- cache->sliceSurfaceObject()->clear();
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList)
+ static_cast<SurfaceSeriesRenderCache *>(baseCache)->sliceSurfaceObject()->clear();
if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries)) {
// Find axis coordinates for the selected point
- SurfaceSeriesRenderCache *selectedCache =
+ SeriesRenderCache *selectedCache =
m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
- QSurfaceDataArray &dataArray = selectedCache->dataArray();
+ QSurfaceDataArray &dataArray =
+ static_cast<SurfaceSeriesRenderCache *>(selectedCache)->dataArray();
QSurfaceDataItem item = dataArray.at(point.x())->at(point.y());
QPointF coords(item.x(), item.z());
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
if (cache->series() != m_selectedSeries) {
QPoint mappedPoint = mapCoordsToSampleSpace(cache, coords);
updateSliceObject(cache, mappedPoint);
@@ -446,9 +410,10 @@ void Surface3DRenderer::updateSliceDataModel(const QPoint &point)
} else {
if (m_selectedSeries) {
SurfaceSeriesRenderCache *cache =
- m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ static_cast<SurfaceSeriesRenderCache *>(
+ m_renderCacheList.value(m_selectedSeries));
if (cache)
- updateSliceObject(cache, point);
+ updateSliceObject(static_cast<SurfaceSeriesRenderCache *>(cache), point);
}
}
}
@@ -728,7 +693,8 @@ void Surface3DRenderer::render(GLuint defaultFboHandle)
// Render selection ball
if (m_selectionActive
&& m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem)) {
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
if (cache->slicePointerActive() && cache->renderable() &&
m_cachedIsSlicingActivated ) {
cache->sliceSelectionPointer()->render(defaultFboHandle);
@@ -780,7 +746,8 @@ void Surface3DRenderer::drawSlicedScene()
if (m_renderCacheList.size()) {
bool drawGrid = false;
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
if (cache->sliceSurfaceObject()->indexCount() && cache->renderable()) {
if (!drawGrid && cache->surfaceGridVisible()) {
glEnable(GL_POLYGON_OFFSET_FILL);
@@ -838,10 +805,13 @@ void Surface3DRenderer::drawSlicedScene()
m_surfaceGridShader->bind();
m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(),
Utils::vectorFromColor(m_cachedTheme->gridLineColor()));
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
- if (cache->sliceSurfaceObject()->indexCount() && cache->isSeriesVisible() &&
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache =
+ static_cast<SurfaceSeriesRenderCache *>(baseCache);
+ if (cache->sliceSurfaceObject()->indexCount() && cache->isVisible() &&
cache->surfaceGridVisible()) {
- m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), cache->MVPMatrix());
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(),
+ cache->MVPMatrix());
m_drawer->drawSurfaceGrid(m_surfaceGridShader, cache->sliceSurfaceObject());
}
}
@@ -1101,9 +1071,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glDisable(GL_CULL_FACE);
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
SurfaceObject *object = cache->surfaceObject();
- if (object->indexCount() && cache->surfaceVisible() && cache->isSeriesVisible()
+ if (object->indexCount() && cache->surfaceVisible() && cache->isVisible()
&& cache->sampleSpace().width() >= 2 && cache->sampleSpace().height() >= 2) {
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
@@ -1134,9 +1105,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_depthModelTexture, 0);
glClear(GL_DEPTH_BUFFER_BIT);
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
SurfaceObject *object = cache->surfaceObject();
- if (object->indexCount() && cache->surfaceVisible() && cache->isSeriesVisible()
+ if (object->indexCount() && cache->surfaceVisible() && cache->isVisible()
&& cache->sampleSpace().width() >= 2 && cache->sampleSpace().height() >= 2) {
m_depthShader->setUniformValue(m_depthShader->MVP(), cache->MVPMatrix());
@@ -1195,7 +1167,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glDisable(GL_CULL_FACE);
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
if (cache->surfaceObject()->indexCount() && cache->renderable()) {
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
@@ -1242,7 +1215,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
bool drawGrid = false;
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
QMatrix4x4 itModelMatrix;
@@ -1255,7 +1229,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
cache->setMVPMatrix(MVPMatrix);
const QRect &sampleSpace = cache->sampleSpace();
- if (cache->surfaceObject()->indexCount() && cache->isSeriesVisible() &&
+ if (cache->surfaceObject()->indexCount() && cache->isVisible() &&
sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
noShadows = false;
if (!drawGrid && cache->surfaceGridVisible()) {
@@ -1318,13 +1292,18 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glDisable(GL_POLYGON_OFFSET_FILL);
m_surfaceGridShader->bind();
m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(),
- Utils::vectorFromColor(m_cachedTheme->gridLineColor()));
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
- m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), cache->MVPMatrix());
+ Utils::vectorFromColor(
+ m_cachedTheme->gridLineColor()));
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache =
+ static_cast<SurfaceSeriesRenderCache *>(baseCache);
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(),
+ cache->MVPMatrix());
const QRect &sampleSpace = cache->sampleSpace();
- if (cache->surfaceObject()->indexCount() && cache->surfaceGridVisible() &&
- cache->isSeriesVisible() && sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ if (cache->surfaceObject()->indexCount() && cache->surfaceGridVisible()
+ && cache->isVisible() && sampleSpace.width() >= 2
+ && sampleSpace.height() >= 2) {
m_drawer->drawSurfaceGrid(m_surfaceGridShader, cache->surfaceObject());
}
}
@@ -1746,7 +1725,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
QPoint visiblePoint = Surface3DController::invalidSelectionPosition();
if (m_selectedSeries) {
SurfaceSeriesRenderCache *cache =
- m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ static_cast<SurfaceSeriesRenderCache *>(
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries)));
if (cache && m_selectedPoint != Surface3DController::invalidSelectionPosition()) {
const QRect &sampleSpace = cache->sampleSpace();
int x = m_selectedPoint.x() - sampleSpace.y();
@@ -1985,7 +1965,9 @@ void Surface3DRenderer::updateSelectionTextures()
{
uint lastSelectionId = 1;
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache =
+ static_cast<SurfaceSeriesRenderCache *>(baseCache);
GLuint texture = cache->selectionTexture();
m_textureHelper->deleteTexture(&texture);
createSelectionTexture(cache, lastSelectionId);
@@ -2113,14 +2095,13 @@ void Surface3DRenderer::updateObjects(SurfaceSeriesRenderCache *cache, bool dime
QSurfaceDataArray &dataArray = cache->dataArray();
const QRect &sampleSpace = cache->sampleSpace();
-
if (cache->isFlatShadingEnabled())
cache->surfaceObject()->setUpData(dataArray, sampleSpace, dimensionChanged);
else
cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, dimensionChanged);
}
-void Surface3DRenderer::updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series)
+void Surface3DRenderer::updateSelectedPoint(const QPoint &position, QSurface3DSeries *series)
{
m_selectedPoint = position;
m_selectedSeries = series;
@@ -2153,7 +2134,9 @@ void Surface3DRenderer::loadGridLineMesh()
void Surface3DRenderer::surfacePointSelected(const QPoint &point)
{
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache =
+ static_cast<SurfaceSeriesRenderCache *>(baseCache);
cache->setSlicePointerActivity(false);
cache->setMainPointerActivity(false);
}
@@ -2161,12 +2144,15 @@ void Surface3DRenderer::surfacePointSelected(const QPoint &point)
if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries)) {
// Find axis coordinates for the selected point
SurfaceSeriesRenderCache *selectedCache =
- m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ static_cast<SurfaceSeriesRenderCache *>(
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries)));
QSurfaceDataArray &dataArray = selectedCache->dataArray();
QSurfaceDataItem item = dataArray.at(point.x())->at(point.y());
QPointF coords(item.x(), item.z());
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache =
+ static_cast<SurfaceSeriesRenderCache *>(baseCache);
if (cache->series() != m_selectedSeries) {
QPoint mappedPoint = mapCoordsToSampleSpace(cache, coords);
updateSelectionPoint(cache, mappedPoint, false);
@@ -2177,7 +2163,8 @@ void Surface3DRenderer::surfacePointSelected(const QPoint &point)
} else {
if (m_selectedSeries) {
SurfaceSeriesRenderCache *cache =
- m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ static_cast<SurfaceSeriesRenderCache *>(
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries)));
if (cache)
updateSelectionPoint(cache, point, true);
}
@@ -2262,7 +2249,8 @@ QPoint Surface3DRenderer::selectionIdToSurfacePoint(uint id)
// Not a label selection
SurfaceSeriesRenderCache *selectedCache = 0;
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
if (cache->isWithinIdRange(id)) {
selectedCache = cache;
break;
@@ -2346,7 +2334,8 @@ void Surface3DRenderer::updateSlicingActive(bool isSlicing)
m_selectionDirty = true;
- foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
+ SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>(baseCache);
if (cache->mainSelectionPointer())
cache->mainSelectionPointer()->updateBoundingRect(m_primarySubViewport);
}
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index 39e96f55..e1147e3c 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -95,9 +95,8 @@ private:
QSizeF m_areaSize;
bool m_hasHeightAdjustmentChanged;
QPoint m_selectedPoint;
- const QSurface3DSeries *m_selectedSeries;
+ QSurface3DSeries *m_selectedSeries;
QPoint m_clickedPosition;
- QHash<QSurface3DSeries *, SurfaceSeriesRenderCache *> m_renderCacheList;
bool m_selectionTexturesDirty;
GLuint m_noShadowTexture;
@@ -106,17 +105,15 @@ public:
~Surface3DRenderer();
void updateData();
- void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility);
+ void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
+ SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
+ void cleanCache(SeriesRenderCache *cache);
void updateSelectionMode(QAbstract3DGraph::SelectionFlags mode);
- void modifiedSeriesList(const QVector<QSurface3DSeries *> &seriesList);
void updateRows(const QVector<Surface3DController::ChangeRow> &rows);
void updateItem(const QVector<Surface3DController::ChangeItem> &points);
- void updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, float max);
- void updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation,
- QValue3DAxisFormatter *formatter);
void updateScene(Q3DScene *scene);
void updateSlicingActive(bool isSlicing);
- void updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series);
+ void updateSelectedPoint(const QPoint &position, QSurface3DSeries *series);
inline QPoint clickedPosition() const { return m_clickedPosition; }
void resetClickedStatus();
diff --git a/src/datavisualization/engine/surfaceseriesrendercache.cpp b/src/datavisualization/engine/surfaceseriesrendercache.cpp
index ad81f714..db3fa9f7 100644
--- a/src/datavisualization/engine/surfaceseriesrendercache.cpp
+++ b/src/datavisualization/engine/surfaceseriesrendercache.cpp
@@ -19,16 +19,18 @@
#include "seriesrendercache_p.h"
#include "surfaceseriesrendercache_p.h"
#include "objecthelper_p.h"
-#include "abstract3drenderer_p.h"
+#include "surface3drenderer_p.h"
#include "texturehelper_p.h"
#include "utils_p.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
-SurfaceSeriesRenderCache::SurfaceSeriesRenderCache(Surface3DRenderer *renderer)
- : m_surfaceVisible(false),
+SurfaceSeriesRenderCache::SurfaceSeriesRenderCache(QAbstract3DSeries *series,
+ Surface3DRenderer *renderer)
+ : SeriesRenderCache(series, renderer),
+ m_surfaceVisible(false),
m_surfaceGridVisible(false),
- m_surfaceFlatShading(true),
+ m_surfaceFlatShading(false),
m_surfaceObj(new SurfaceObject(renderer)),
m_sliceSurfaceObj(new SurfaceObject(renderer)),
m_sampleSpace(QRect(0, 0, 0 , 0)),
@@ -36,13 +38,11 @@ SurfaceSeriesRenderCache::SurfaceSeriesRenderCache(Surface3DRenderer *renderer)
m_selectionIdStart(0),
m_selectionIdEnd(0),
m_flatChangeAllowed(true),
- m_flatStatusDirty(false),
+ m_flatStatusDirty(true),
m_sliceSelectionPointer(0),
m_mainSelectionPointer(0),
m_slicePointerActive(false),
- m_mainPointerActive(false),
- m_valid(false),
- m_objectDirty(true)
+ m_mainPointerActive(false)
{
}
@@ -50,17 +50,15 @@ SurfaceSeriesRenderCache::~SurfaceSeriesRenderCache()
{
}
-void SurfaceSeriesRenderCache::populate(QSurface3DSeries *series, Abstract3DRenderer *renderer)
+void SurfaceSeriesRenderCache::populate(bool newSeries)
{
- Q_ASSERT(series);
+ SeriesRenderCache::populate(newSeries);
- SeriesRenderCache::populate(series, renderer);
-
- QSurface3DSeries::DrawFlags drawMode = series->drawMode();
+ QSurface3DSeries::DrawFlags drawMode = series()->drawMode();
m_surfaceVisible = drawMode.testFlag(QSurface3DSeries::DrawSurface);
m_surfaceGridVisible = drawMode.testFlag(QSurface3DSeries::DrawWireframe);
- if (m_flatChangeAllowed && m_surfaceFlatShading != series->isFlatShadingEnabled()) {
- m_surfaceFlatShading = series->isFlatShadingEnabled();
+ if (m_flatChangeAllowed && m_surfaceFlatShading != series()->isFlatShadingEnabled()) {
+ m_surfaceFlatShading = series()->isFlatShadingEnabled();
m_flatStatusDirty = true;
}
}
diff --git a/src/datavisualization/engine/surfaceseriesrendercache_p.h b/src/datavisualization/engine/surfaceseriesrendercache_p.h
index bab16201..9d373812 100644
--- a/src/datavisualization/engine/surfaceseriesrendercache_p.h
+++ b/src/datavisualization/engine/surfaceseriesrendercache_p.h
@@ -48,10 +48,10 @@ class TextureHelper;
class SurfaceSeriesRenderCache : public SeriesRenderCache
{
public:
- SurfaceSeriesRenderCache(Surface3DRenderer *renderer);
+ SurfaceSeriesRenderCache(QAbstract3DSeries *series, Surface3DRenderer *renderer);
virtual ~SurfaceSeriesRenderCache();
- void populate(QSurface3DSeries *series, Abstract3DRenderer *renderer);
+ virtual void populate(bool newSeries);
virtual void cleanup(TextureHelper *texHelper);
inline bool surfaceVisible() const { return m_surfaceVisible; }
@@ -59,8 +59,6 @@ public:
inline bool isFlatShadingEnabled() const { return m_surfaceFlatShading; }
inline void setFlatShadingEnabled(bool enabled) { m_surfaceFlatShading = enabled; }
inline void setFlatChangeAllowed(bool allowed) { m_flatChangeAllowed = allowed; }
- inline void setValid(bool valid) { m_valid = valid; }
- inline bool isValid() const { return m_valid; }
inline SurfaceObject *surfaceObject() { return m_surfaceObj; }
inline SurfaceObject *sliceSurfaceObject() { return m_sliceSurfaceObj; }
inline const QRect &sampleSpace() const { return m_sampleSpace; }
@@ -68,11 +66,8 @@ public:
inline QSurface3DSeries *series() const { return static_cast<QSurface3DSeries *>(m_series); }
inline QSurfaceDataArray &dataArray() { return m_dataArray; }
inline QSurfaceDataArray &sliceDataArray() { return m_sliceDataArray; }
- inline bool isSeriesVisible() const { return m_series->isVisible(); }
- inline bool renderable() const { return m_series->isVisible() && (m_surfaceVisible ||
- m_surfaceGridVisible); }
- inline void setObjectDirty(bool state) { m_objectDirty = state; }
- inline bool objectDirty() const { return m_objectDirty; }
+ inline bool renderable() const { return m_visible && (m_surfaceVisible ||
+ m_surfaceGridVisible); }
inline void setSelectionTexture(GLuint texture) { m_selectionTexture = texture; }
inline GLuint selectionTexture() const { return m_selectionTexture; }
inline void setSelectionIdRange(uint start, uint end) { m_selectionIdStart = start;
@@ -82,7 +77,6 @@ public:
selection <= m_selectionIdEnd; }
inline bool isFlatStatusDirty() const { return m_flatStatusDirty; }
inline void setFlatStatusDirty(bool status) { m_flatStatusDirty = status; }
- // m_MVPMatrix is volatile, used only for optimizing rendering a bit
inline void setMVPMatrix(const QMatrix4x4 &matrix) { m_MVPMatrix = matrix; }
inline const QMatrix4x4 &MVPMatrix() { return m_MVPMatrix; }
@@ -115,9 +109,6 @@ protected:
SelectionPointer *m_mainSelectionPointer;
bool m_slicePointerActive;
bool m_mainPointerActive;
-
- bool m_valid;
- bool m_objectDirty;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index b21961cb..96d04094 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -673,6 +673,8 @@ void SurfaceObject::clear()
m_gridIndexCount = 0;
m_indexCount = 0;
m_surfaceType = Undefined;
+ m_vertices.clear();
+ m_normals.clear();
}
QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c)
diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp
index 0a8bef55..2c095cf8 100644
--- a/tests/barstest/chart.cpp
+++ b/tests/barstest/chart.cpp
@@ -71,7 +71,8 @@ GraphModifier::GraphModifier(Q3DBars *barchart, QColorDialog *colorDialog)
m_defaultInputHandler(0),
m_ownTheme(0),
m_builtinTheme(new Q3DTheme(Q3DTheme::ThemeStoneMoss)),
- m_customInputHandler(new CustomInputHandler)
+ m_customInputHandler(new CustomInputHandler),
+ m_extraSeries(0)
{
m_temperatureData->setObjectName("m_temperatureData");
m_temperatureData2->setObjectName("m_temperatureData2");
@@ -1149,6 +1150,67 @@ void GraphModifier::changeLogBase(const QString &text)
formatter->setBase(qreal(text.toDouble()));
}
+void GraphModifier::addRemoveSeries()
+{
+ static int counter = 0;
+
+ switch (counter) {
+ case 0: {
+ qDebug() << __FUNCTION__ << counter << "New series";
+ m_extraSeries = new QBar3DSeries;
+ m_graph->addSeries(m_extraSeries);
+ QObject::connect(m_extraSeries, &QBar3DSeries::selectedBarChanged, this,
+ &GraphModifier::handleSelectionChange);
+ }
+ break;
+ case 1: {
+ qDebug() << __FUNCTION__ << counter << "Add data to series";
+ QBarDataArray *array = new QBarDataArray;
+ array->reserve(5);
+ for (int i = 0; i < 5; i++) {
+ array->append(new QBarDataRow(10));
+ for (int j = 0; j < 10; j++)
+ (*array->at(i))[j].setValue(i * j);
+ }
+ m_extraSeries->dataProxy()->resetArray(array);
+ }
+ break;
+ case 2: {
+ qDebug() << __FUNCTION__ << counter << "Hide series";
+ m_extraSeries->setVisible(false);
+ }
+ break;
+ case 3: {
+ qDebug() << __FUNCTION__ << counter << "Modify data when hidden";
+ QBarDataArray array;
+ array.reserve(5);
+ for (int i = 0; i < 5; i++) {
+ array.append(new QBarDataRow(10));
+ for (int j = 0; j < 10; j++)
+ (*array.at(i))[j].setValue(2 * i * j);
+ }
+ m_extraSeries->dataProxy()->addRows(array);
+ }
+ break;
+ case 4: {
+ qDebug() << __FUNCTION__ << counter << "Show series again";
+ m_extraSeries->setVisible(true);
+ }
+ break;
+ case 5: {
+ qDebug() << __FUNCTION__ << counter << "Remove series";
+ m_graph->removeSeries(m_extraSeries);
+ delete m_extraSeries;
+ m_extraSeries = 0;
+ }
+ break;
+ default:
+ qDebug() << __FUNCTION__ << "Resetting test";
+ counter = -1;
+ }
+ counter++;
+}
+
void GraphModifier::changeValueAxisSegments(int value)
{
qDebug() << __FUNCTION__ << value;
diff --git a/tests/barstest/chart.h b/tests/barstest/chart.h
index 214c4e17..e64b282a 100644
--- a/tests/barstest/chart.h
+++ b/tests/barstest/chart.h
@@ -91,6 +91,7 @@ public:
void changeValueAxisFormat(const QString & text);
void changeLogBase(const QString & text);
void setFpsLabel(QLabel *fpsLabel) { m_fpsLabel = fpsLabel; }
+ void addRemoveSeries();
public slots:
void flipViews();
@@ -162,6 +163,7 @@ private:
QTimer m_selectionTimer;
QTimer m_rotationTimer;
QLabel *m_fpsLabel;
+ QBar3DSeries *m_extraSeries;
};
#endif
diff --git a/tests/barstest/main.cpp b/tests/barstest/main.cpp
index b1589e0f..e02bddce 100644
--- a/tests/barstest/main.cpp
+++ b/tests/barstest/main.cpp
@@ -66,6 +66,10 @@ int main(int argc, char **argv)
hLayout->addLayout(vLayout);
hLayout->addLayout(vLayout2);
+ QPushButton *addSeriesButton = new QPushButton(widget);
+ addSeriesButton->setText(QStringLiteral("Add / Remove a series"));
+ addSeriesButton->setEnabled(true);
+
QPushButton *addDataButton = new QPushButton(widget);
addDataButton->setText(QStringLiteral("Add a row of data"));
addDataButton->setEnabled(false);
@@ -305,6 +309,7 @@ int main(int argc, char **argv)
valueAxisSegmentsSpin->setMaximum(100);
valueAxisSegmentsSpin->setValue(10);
+ vLayout->addWidget(addSeriesButton, 0, Qt::AlignTop);
vLayout->addWidget(addDataButton, 0, Qt::AlignTop);
vLayout->addWidget(addMultiDataButton, 0, Qt::AlignTop);
vLayout->addWidget(insertDataButton, 0, Qt::AlignTop);
@@ -419,6 +424,7 @@ int main(int argc, char **argv)
QObject::connect(labelButton, &QPushButton::clicked, modifier,
&GraphModifier::changeLabelStyle);
QObject::connect(addDataButton, &QPushButton::clicked, modifier, &GraphModifier::addRow);
+ QObject::connect(addSeriesButton, &QPushButton::clicked, modifier, &GraphModifier::addRemoveSeries);
QObject::connect(addMultiDataButton, &QPushButton::clicked, modifier, &GraphModifier::addRows);
QObject::connect(insertDataButton, &QPushButton::clicked, modifier, &GraphModifier::insertRow);
QObject::connect(insertMultiDataButton, &QPushButton::clicked, modifier, &GraphModifier::insertRows);
diff --git a/tests/scattertest/main.cpp b/tests/scattertest/main.cpp
index fbe257f5..2bd60aff 100644
--- a/tests/scattertest/main.cpp
+++ b/tests/scattertest/main.cpp
@@ -102,6 +102,9 @@ int main(int argc, char **argv)
QPushButton *setSelectedItemButton = new QPushButton(widget);
setSelectedItemButton->setText(QStringLiteral("Select/deselect item 3"));
+ QPushButton *clearSeriesDataButton = new QPushButton(widget);
+ clearSeriesDataButton->setText(QStringLiteral("Clear series data"));
+
QPushButton *addSeriesButton = new QPushButton(widget);
addSeriesButton->setText(QStringLiteral("Add Series"));
@@ -220,6 +223,7 @@ int main(int argc, char **argv)
vLayout->addWidget(removeOneButton, 0, Qt::AlignTop);
vLayout->addWidget(removeBunchButton, 0, Qt::AlignTop);
vLayout->addWidget(setSelectedItemButton, 0, Qt::AlignTop);
+ vLayout->addWidget(clearSeriesDataButton, 0, Qt::AlignTop);
vLayout->addWidget(addSeriesButton, 0, Qt::AlignTop);
vLayout->addWidget(removeSeriesButton, 0, Qt::AlignTop);
vLayout->addWidget(toggleSeriesVisibilityButton, 0, Qt::AlignTop);
@@ -280,6 +284,8 @@ int main(int argc, char **argv)
&ScatterDataModifier::removeBunch);
QObject::connect(setSelectedItemButton, &QPushButton::clicked, modifier,
&ScatterDataModifier::selectItem);
+ QObject::connect(clearSeriesDataButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::clearSeriesData);
QObject::connect(addSeriesButton, &QPushButton::clicked, modifier,
&ScatterDataModifier::addSeries);
QObject::connect(removeSeriesButton, &QPushButton::clicked, modifier,
diff --git a/tests/scattertest/scatterchart.cpp b/tests/scattertest/scatterchart.cpp
index a589919f..2e208926 100644
--- a/tests/scattertest/scatterchart.cpp
+++ b/tests/scattertest/scatterchart.cpp
@@ -459,6 +459,12 @@ void ScatterDataModifier::setGradient()
}
}
+void ScatterDataModifier::clearSeriesData()
+{
+ if (m_targetSeries)
+ m_targetSeries->dataProxy()->resetArray(0);
+}
+
void ScatterDataModifier::addSeries()
{
QScatter3DSeries *series = createAndAddSeries();
diff --git a/tests/scattertest/scatterchart.h b/tests/scattertest/scatterchart.h
index 23071c85..1470f07b 100644
--- a/tests/scattertest/scatterchart.h
+++ b/tests/scattertest/scatterchart.h
@@ -71,6 +71,7 @@ public slots:
void selectItem();
void handleSelectionChange(int index);
void setGradient();
+ void clearSeriesData();
void addSeries();
void removeSeries();
void toggleSeriesVisibility();
diff --git a/tests/surfacetest/graphmodifier.cpp b/tests/surfacetest/graphmodifier.cpp
index e1fed76a..c87eb2fc 100644
--- a/tests/surfacetest/graphmodifier.cpp
+++ b/tests/surfacetest/graphmodifier.cpp
@@ -1093,6 +1093,44 @@ void GraphModifier::removeRow()
m_zCount--;
}
+void GraphModifier::resetArray()
+{
+ qDebug() << "Reset series data array";
+ int rows = 10;
+ int columns = 10;
+ float randFactor = float(rand() % 100) / 100.0f;
+ QSurfaceDataArray *planeArray = new QSurfaceDataArray;
+ planeArray->reserve(rows);
+
+ for (int i = 0; i < rows; i++) {
+ planeArray->append(new QSurfaceDataRow);
+ (*planeArray)[i]->resize(columns);
+ for (int j = 0; j < columns; j++) {
+ (*planeArray->at(i))[j].setX(float(j) * randFactor);
+ (*planeArray->at(i))[j].setY(float(i - j) * randFactor);
+ (*planeArray->at(i))[j].setZ(float(i));
+ }
+ }
+
+#ifdef MULTI_SERIES
+ int series = rand() % 4;
+ m_multiseries[series]->dataProxy()->resetArray(planeArray);
+#else
+ m_theSeries->dataProxy()->resetArray(planeArray);
+#endif
+}
+
+void GraphModifier::resetArrayEmpty()
+{
+ QSurfaceDataArray *emptryArray = new QSurfaceDataArray;
+#ifdef MULTI_SERIES
+ int series = rand() % 4;
+ m_multiseries[series]->dataProxy()->resetArray(emptryArray);
+#else
+ m_theSeries->dataProxy()->resetArray(emptryArray);
+#endif
+}
+
void GraphModifier::changeMesh()
{
static int model = 0;
diff --git a/tests/surfacetest/graphmodifier.h b/tests/surfacetest/graphmodifier.h
index 9fd0360b..5c4ed033 100644
--- a/tests/surfacetest/graphmodifier.h
+++ b/tests/surfacetest/graphmodifier.h
@@ -105,6 +105,8 @@ public:
void insertRow();
void insertRows();
void removeRow();
+ void resetArray();
+ void resetArrayEmpty();
public slots:
void changeShadowQuality(int quality);
diff --git a/tests/surfacetest/main.cpp b/tests/surfacetest/main.cpp
index 6b54b8dd..bddb2d11 100644
--- a/tests/surfacetest/main.cpp
+++ b/tests/surfacetest/main.cpp
@@ -338,6 +338,12 @@ int main(int argc, char *argv[])
QPushButton *removeRowButton = new QPushButton(widget);
removeRowButton->setText(QStringLiteral("Remove a row"));
+ QPushButton *resetArrayButton = new QPushButton(widget);
+ resetArrayButton->setText(QStringLiteral("Reset Series Array to plane"));
+
+ QPushButton *resetArrayEmptyButton = new QPushButton(widget);
+ resetArrayEmptyButton->setText(QStringLiteral("Reset Series Array to empty"));
+
QFrame* line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
@@ -423,6 +429,8 @@ int main(int argc, char *argv[])
vLayout2->addWidget(insertRowButton);
vLayout2->addWidget(insertRowsButton);
vLayout2->addWidget(removeRowButton);
+ vLayout2->addWidget(resetArrayButton);
+ vLayout2->addWidget(resetArrayEmptyButton);
widget->show();
@@ -574,6 +582,10 @@ int main(int argc, char *argv[])
modifier, &GraphModifier::insertRows);
QObject::connect(removeRowButton,&QPushButton::clicked,
modifier, &GraphModifier::removeRow);
+ QObject::connect(resetArrayButton,&QPushButton::clicked,
+ modifier, &GraphModifier::resetArray);
+ QObject::connect(resetArrayEmptyButton,&QPushButton::clicked,
+ modifier, &GraphModifier::resetArrayEmpty);
#ifdef MULTI_SERIES
modifier->setSeries1CB(series1CB);