summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/datavisualization/data/qabstract3dseries.h1
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp13
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h1
-rw-r--r--src/datavisualization/engine/engine.pri6
-rw-r--r--src/datavisualization/engine/seriesrendercache.cpp4
-rw-r--r--src/datavisualization/engine/seriesrendercache_p.h2
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp25
-rw-r--r--src/datavisualization/engine/surface3dcontroller_p.h1
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp751
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h24
-rw-r--r--src/datavisualization/engine/surfaceseriesrendercache.cpp73
-rw-r--r--src/datavisualization/engine/surfaceseriesrendercache_p.h101
-rw-r--r--src/datavisualization/global/datavisualizationglobal_p.h2
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp7
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h13
-rw-r--r--src/datavisualization/utils/texturehelper.cpp12
-rw-r--r--src/datavisualization/utils/texturehelper_p.h1
-rw-r--r--tests/surfacetest/graphmodifier.cpp333
-rw-r--r--tests/surfacetest/graphmodifier.h39
-rw-r--r--tests/surfacetest/main.cpp200
20 files changed, 1219 insertions, 390 deletions
diff --git a/src/datavisualization/data/qabstract3dseries.h b/src/datavisualization/data/qabstract3dseries.h
index ebb22b7f..c45bb801 100644
--- a/src/datavisualization/data/qabstract3dseries.h
+++ b/src/datavisualization/data/qabstract3dseries.h
@@ -142,6 +142,7 @@ private:
friend class Abstract3DController;
friend class Bars3DController;
friend class Surface3DController;
+ friend class Surface3DRenderer;
friend class Scatter3DController;
friend class QBar3DSeries;
friend class SeriesRenderCache;
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
index e3ec7c9a..e62f2a00 100644
--- a/src/datavisualization/engine/abstract3drenderer.cpp
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -426,8 +426,17 @@ void Abstract3DRenderer::lowerShadowQuality()
updateShadowQuality(newQuality);
}
-void Abstract3DRenderer::fixGradientAndGenerateTexture(QLinearGradient *gradient,
- GLuint *gradientTexture)
+void Abstract3DRenderer::generateBaseColorTexture(const QColor &color, GLuint *texture)
+{
+ if (*texture) {
+ m_textureHelper->deleteTexture(texture);
+ *texture = 0;
+ }
+
+ *texture = m_textureHelper->createUniformTexture(color);
+}
+
+void Abstract3DRenderer::fixGradientAndGenerateTexture(QLinearGradient *gradient, GLuint *gradientTexture)
{
// Readjust start/stop to match gradient texture size
gradient->setStart(qreal(gradientTextureWidth), qreal(gradientTextureHeight));
diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h
index e7591a10..a381adf8 100644
--- a/src/datavisualization/engine/abstract3drenderer_p.h
+++ b/src/datavisualization/engine/abstract3drenderer_p.h
@@ -94,6 +94,7 @@ public:
virtual void updateAxisLabelFormat(QAbstract3DAxis::AxisOrientation orientation, const QString &format);
virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh);
+ void generateBaseColorTexture(const QColor &color, GLuint *texture);
void fixGradientAndGenerateTexture(QLinearGradient *gradient, GLuint *gradientTexture);
inline bool isClickPending() { return m_clickPending; }
diff --git a/src/datavisualization/engine/engine.pri b/src/datavisualization/engine/engine.pri
index e13a9a04..b686397c 100644
--- a/src/datavisualization/engine/engine.pri
+++ b/src/datavisualization/engine/engine.pri
@@ -26,7 +26,8 @@ HEADERS += $$PWD/qabstract3dgraph_p.h \
$$PWD/q3dbox.h \
$$PWD/q3dobject.h \
$$PWD/q3dobject_p.h \
- $$PWD/q3dscene_p.h
+ $$PWD/q3dscene_p.h \
+ $$PWD/surfaceseriesrendercache_p.h
SOURCES += $$PWD/qabstract3dgraph.cpp \
$$PWD/q3dbars.cpp \
@@ -48,6 +49,7 @@ SOURCES += $$PWD/qabstract3dgraph.cpp \
$$PWD/q3dlight.cpp \
$$PWD/q3dbox.cpp \
$$PWD/q3dobject.cpp \
- $$PWD/q3dscene.cpp
+ $$PWD/q3dscene.cpp \
+ $$PWD/surfaceseriesrendercache.cpp
RESOURCES += engine/engine.qrc
diff --git a/src/datavisualization/engine/seriesrendercache.cpp b/src/datavisualization/engine/seriesrendercache.cpp
index fe2db319..5d20e761 100644
--- a/src/datavisualization/engine/seriesrendercache.cpp
+++ b/src/datavisualization/engine/seriesrendercache.cpp
@@ -30,6 +30,7 @@ SeriesRenderCache::SeriesRenderCache()
: m_series(0),
m_object(0),
m_mesh(QAbstract3DSeries::MeshCube),
+ m_baseUniformTexture(0),
m_baseGradientTexture(0),
m_singleHighlightGradientTexture(0),
m_multiHighlightGradientTexture(0)
@@ -138,6 +139,8 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *
if (seriesChanged || changeTracker.baseColorChanged) {
m_baseColor = Utils::vectorFromColor(series->baseColor());
+ if (m_series->type() == QAbstract3DSeries::SeriesTypeSurface)
+ renderer->generateBaseColorTexture(series->baseColor(), &m_baseUniformTexture);
changeTracker.baseColorChanged = false;
}
@@ -178,6 +181,7 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *
void SeriesRenderCache::cleanup(TextureHelper *texHelper)
{
delete m_object;
+ texHelper->deleteTexture(&m_baseUniformTexture);
texHelper->deleteTexture(&m_baseGradientTexture);
texHelper->deleteTexture(&m_singleHighlightGradientTexture);
texHelper->deleteTexture(&m_multiHighlightGradientTexture);
diff --git a/src/datavisualization/engine/seriesrendercache_p.h b/src/datavisualization/engine/seriesrendercache_p.h
index 82f69ccd..7994339a 100644
--- a/src/datavisualization/engine/seriesrendercache_p.h
+++ b/src/datavisualization/engine/seriesrendercache_p.h
@@ -58,6 +58,7 @@ public:
inline ObjectHelper *object() const { return m_object; }
inline const Q3DTheme::ColorStyle &colorStyle() const { return m_colorStyle; }
inline const QVector3D &baseColor() const { return m_baseColor; }
+ inline const GLuint &baseUniformTexture() const { return m_baseUniformTexture; }
inline const GLuint &baseGradientTexture() const { return m_baseGradientTexture; }
inline const QVector3D &singleHighlightColor() const { return m_singleHighlightColor; }
inline const GLuint &singleHighlightGradientTexture() const { return m_singleHighlightGradientTexture; }
@@ -74,6 +75,7 @@ protected:
Q3DTheme::ColorStyle m_colorStyle;
QVector3D m_baseColor;
+ GLuint m_baseUniformTexture;
GLuint m_baseGradientTexture;
QVector3D m_singleHighlightColor;
GLuint m_singleHighlightGradientTexture;
diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp
index 664c4a71..553166e1 100644
--- a/src/datavisualization/engine/surface3dcontroller.cpp
+++ b/src/datavisualization/engine/surface3dcontroller.cpp
@@ -68,6 +68,11 @@ void Surface3DController::synchDataToRenderer()
if (!isInitialized())
return;
+ if (m_changedSeriesList.size()) {
+ m_renderer->modifiedSeriesList(m_changedSeriesList);
+ m_changedSeriesList.clear();
+ }
+
Abstract3DController::synchDataToRenderer();
// Notify changes to renderer
@@ -143,14 +148,10 @@ void Surface3DController::addSeries(QAbstract3DSeries *series)
{
Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeSurface);
- if (!m_seriesList.size()) {
- Abstract3DController::addSeries(series);
+ Abstract3DController::addSeries(series);
- if (series->isVisible())
- adjustValueAxisRange();
- } else {
- qWarning("Surface graph only supports a single series.");
- }
+ if (series->isVisible())
+ adjustValueAxisRange();
QSurface3DSeries *surfaceSeries = static_cast<QSurface3DSeries *>(series);
if (surfaceSeries->selectedPoint() != invalidSelectionPosition())
@@ -260,7 +261,7 @@ void Surface3DController::setSelectedPoint(const QPoint &position, QSurface3DSer
emitNeedRender();
}
- if (pos != m_selectedPoint) {
+ if (pos != m_selectedPoint || series != m_selectedSeries) {
m_selectedPoint = pos;
m_selectedSeries = series;
m_changeTracker.selectedPointChanged = true;
@@ -288,6 +289,8 @@ void Surface3DController::handleArrayReset()
QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(sender())->series();
if (series->isVisible()) {
adjustValueAxisRange();
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
m_isDataDirty = true;
}
// Clear selection unless still valid
@@ -375,6 +378,8 @@ void Surface3DController::handleRowsAdded(int startIndex, int count)
if (series->isVisible()) {
adjustValueAxisRange();
m_isDataDirty = true;
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
}
emitNeedRender();
}
@@ -396,6 +401,8 @@ void Surface3DController::handleRowsInserted(int startIndex, int count)
if (series->isVisible()) {
adjustValueAxisRange();
m_isDataDirty = true;
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
}
emitNeedRender();
@@ -422,6 +429,8 @@ void Surface3DController::handleRowsRemoved(int startIndex, int count)
if (series->isVisible()) {
adjustValueAxisRange();
m_isDataDirty = true;
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
}
emitNeedRender();
diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h
index 4ca9c8e2..64a57b3b 100644
--- a/src/datavisualization/engine/surface3dcontroller_p.h
+++ b/src/datavisualization/engine/surface3dcontroller_p.h
@@ -67,6 +67,7 @@ private:
bool m_flatShadingSupported;
QVector<QPoint> m_changedItems;
QVector<int> m_changedRows;
+ QVector<QSurface3DSeries *> m_changedSeriesList;
public:
explicit Surface3DController(QRect rect, Q3DScene *scene = 0);
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 4dbd48ba..48d10932 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -60,7 +60,8 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_cachedIsSlicingActivated(false),
m_depthShader(0),
m_backgroundShader(0),
- m_surfaceShader(0),
+ m_surfaceFlatShader(0),
+ m_surfaceSmoothShader(0),
m_surfaceGridShader(0),
m_selectionShader(0),
m_labelShader(0),
@@ -84,19 +85,15 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_gridLineObj(0),
m_labelObj(0),
m_surfaceObj(0),
- m_sliceSurfaceObj(0),
m_depthTexture(0),
m_depthModelTexture(0),
m_depthFrameBuffer(0),
m_selectionFrameBuffer(0),
m_selectionDepthBuffer(0),
- m_selectionTexture(0),
m_selectionResultTexture(0),
m_shadowQualityToShader(33.3f),
m_cachedFlatShading(false),
m_flatSupported(true),
- m_cachedSurfaceVisible(true),
- m_cachedSurfaceGridOn(true),
m_selectionPointer(0),
m_selectionActive(false),
m_xFlipped(false),
@@ -108,8 +105,8 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_hasHeightAdjustmentChanged(true),
m_selectedPoint(Surface3DController::invalidSelectionPosition()),
m_selectedSeries(0),
- m_uniformGradientTexture(0),
- m_clickedPosition(Surface3DController::invalidSelectionPosition())
+ m_clickedPosition(Surface3DController::invalidSelectionPosition()),
+ m_selectionTexturesDirty(false)
{
// Check if flat feature is supported
ShaderHelper tester(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
@@ -125,9 +122,6 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
initializeOpenGLFunctions();
initializeOpenGL();
-
- // Create initial uniform gradient
- generateUniformGradient(m_uniformGradientTextureColor);
}
Surface3DRenderer::~Surface3DRenderer()
@@ -139,32 +133,29 @@ Surface3DRenderer::~Surface3DRenderer()
m_textureHelper->deleteTexture(&m_depthTexture);
m_textureHelper->deleteTexture(&m_depthModelTexture);
- m_textureHelper->deleteTexture(&m_selectionTexture);
m_textureHelper->deleteTexture(&m_selectionResultTexture);
- m_textureHelper->deleteTexture(&m_uniformGradientTexture);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ GLuint texture = cache->selectionTexture();
+ m_textureHelper->deleteTexture(&texture);
+ }
}
delete m_depthShader;
delete m_backgroundShader;
delete m_selectionShader;
- delete m_surfaceShader;
+ delete m_surfaceFlatShader;
+ delete m_surfaceSmoothShader;
delete m_surfaceGridShader;
delete m_labelShader;
delete m_backgroundObj;
- delete m_surfaceObj;
- delete m_sliceSurfaceObj;
delete m_gridLineObj;
delete m_labelObj;
delete m_selectionPointer;
- for (int i = 0; i < m_dataArray.size(); i++)
- delete m_dataArray.at(i);
- m_dataArray.clear();
-
- for (int i = 0; i < m_sliceDataArray.size(); i++)
- delete m_sliceDataArray.at(i);
- m_sliceDataArray.clear();
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList)
+ delete cache;
+ m_renderCacheList.clear();
}
void Surface3DRenderer::initializeOpenGL()
@@ -200,77 +191,56 @@ void Surface3DRenderer::initializeOpenGL()
void Surface3DRenderer::updateData()
{
- // Surface only supports single series for now, so we are only interested in the first series
- const QSurfaceDataArray *array = 0;
- if (m_visibleSeriesList.size()) {
- QSurface3DSeries *firstSeries = static_cast<QSurface3DSeries *>(m_visibleSeriesList.at(0).series());
- QSurfaceDataProxy *dataProxy = firstSeries->dataProxy();
- if (dataProxy)
- array = dataProxy->array();
- }
-
calculateSceneScalingFactors();
- // Need minimum of 2x2 array to draw a surface
- if (array && array->size() >= 2 && array->at(0)->size() >= 2) {
- QRect sampleSpace = calculateSampleRect(*array);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ const QSurface3DSeries *currentSeries = cache->series();
+ QSurfaceDataProxy *dataProxy = currentSeries->dataProxy();
+ const QSurfaceDataArray &array = *dataProxy->array();
- bool dimensionChanged = false;
- if (m_sampleSpace != sampleSpace) {
- dimensionChanged = true;
- m_sampleSpace = sampleSpace;
+ // Need minimum of 2x2 array to draw a surface
+ if (array.size() >= 2 && array.at(0)->size() >= 2) {
+ QRect sampleSpace = calculateSampleRect(array);
- for (int i = 0; i < m_dataArray.size(); i++)
- delete m_dataArray.at(i);
- m_dataArray.clear();
- }
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ bool dimensionChanged = false;
+ if (cache->sampleSpace() != sampleSpace) {
+ if (cache->sampleSpace().width())
+ m_selectionTexturesDirty = true;
- if (sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
- if (dimensionChanged) {
- m_dataArray.reserve(sampleSpace.height());
- for (int i = 0; i < sampleSpace.height(); i++)
- m_dataArray << new QSurfaceDataRow(sampleSpace.width());
- }
- for (int i = 0; i < sampleSpace.height(); i++) {
- for (int j = 0; j < sampleSpace.width(); j++)
- (*(m_dataArray.at(i)))[j] = array->at(i + sampleSpace.y())->at(
- j + sampleSpace.x());
- }
+ dimensionChanged = true;
+ cache->setSampleSpace(sampleSpace);
- if (m_dataArray.size() > 0) {
- if (!m_surfaceObj)
- loadSurfaceObj();
+ for (int i = 0; i < dataArray.size(); i++)
+ delete dataArray.at(i);
+ dataArray.clear();
+ }
- // Note: Data setup can change sample space (as min width/height is 1)
- if (!m_cachedFlatShading) {
- m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- m_axisCacheY.min(), dimensionChanged);
- } else {
- m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- m_axisCacheY.min(), dimensionChanged);
+ if (sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ if (dimensionChanged) {
+ dataArray.reserve(sampleSpace.height());
+ for (int i = 0; i < sampleSpace.height(); i++)
+ dataArray << new QSurfaceDataRow(sampleSpace.width());
+ }
+ for (int i = 0; i < sampleSpace.height(); i++) {
+ for (int j = 0; j < sampleSpace.width(); j++) {
+ (*(dataArray.at(i)))[j] = array.at(i + sampleSpace.y())->at(
+ j + sampleSpace.x());
+ }
}
- if (dimensionChanged)
- updateSelectionTexture();
+ if (dataArray.size() > 0 && (cache->objectDirty() || dimensionChanged)) {
+ checkFlatSupport(cache);
+ updateObjects(cache, dimensionChanged);
+ cache->setObjectDirty(false);
+ cache->setFlatStatusDirty(false);
+ }
}
}
- } else {
- for (int i = 0; i < m_dataArray.size(); i++)
- delete m_dataArray.at(i);
- m_dataArray.clear();
- m_sampleSpace = QRect();
-
- delete m_surfaceObj;
- m_surfaceObj = 0;
-#if !defined(QT_OPENGL_ES_2)
- m_textureHelper->fillDepthTexture(m_depthTexture, m_primarySubViewport.size(),
- m_shadowQualityMultiplier, 1.0f);
-#endif
}
- for (int i = 0; i < m_sliceDataArray.size(); i++)
- delete m_sliceDataArray.at(i);
- m_sliceDataArray.clear();
+ if (m_selectionTexturesDirty && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone)
+ updateSelectionTextures();
updateSelectedPoint(m_selectedPoint, m_selectedSeries);
}
@@ -278,35 +248,69 @@ void Surface3DRenderer::updateData()
void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList,
bool updateVisibility)
{
- Abstract3DRenderer::updateSeries(seriesList, updateVisibility);
+ Q_UNUSED(updateVisibility);
- if (m_visibleSeriesList.size()) {
- QSurface3DSeries *series = static_cast<QSurface3DSeries *>(m_visibleSeriesList.at(0).series());
- updateFlatStatus(series->isFlatShadingEnabled());
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList)
+ cache->setValid(false);
- QSurface3DSeries::DrawFlags drawMode = series->drawMode();
- m_cachedSurfaceVisible = drawMode.testFlag(QSurface3DSeries::DrawSurface);
-#if !defined(QT_OPENGL_ES_2)
- if (!m_cachedSurfaceVisible) {
- m_textureHelper->fillDepthTexture(m_depthTexture, m_primarySubViewport.size(),
- m_shadowQualityMultiplier, 1.0f);
+ foreach (QAbstract3DSeries *series, seriesList) {
+ // Item selection label may need update
+ if (series->d_ptr->m_changeTracker.nameChanged
+ || series->d_ptr->m_changeTracker.itemLabelFormatChanged) {
+ m_selectionLabelDirty = true;
}
-#endif
- m_cachedSurfaceGridOn = drawMode.testFlag(QSurface3DSeries::DrawWireframe);
- QVector3D seriesColor = Utils::vectorFromColor(series->baseColor());
- if (m_uniformGradientTextureColor != seriesColor)
- generateUniformGradient(seriesColor);
- if (m_selectionPointer) {
+ QSurface3DSeries *surfaceSeries = static_cast<QSurface3DSeries *>(series);
+ SurfaceSeriesRenderCache *cache = m_renderCacheList.value(surfaceSeries);
+ if (!cache) {
+ cache = new SurfaceSeriesRenderCache;
+ m_renderCacheList[surfaceSeries] = cache;
+
+ m_selectionTexturesDirty = true;
+ }
+ cache->setValid(true);
+ cache->populate(surfaceSeries, this);
+ if (cache->isFlatStatusDirty() && cache->sampleSpace().width()) {
+ checkFlatSupport(cache);
+ updateObjects(cache, true);
+ cache->setFlatStatusDirty(false);
+ }
+ }
+
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (!cache->isValid()) {
+ if (cache->series() == m_selectedSeries)
+ updateSelectedPoint(Surface3DController::invalidSelectionPosition(), 0);
+
+ m_renderCacheList.remove(cache->series());
+ delete cache;
+
+ m_selectionTexturesDirty = true;
+ }
+ }
+
+ if (m_selectionPointer && m_selectedSeries) {
+ SurfaceSeriesRenderCache *cache =
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ if (cache) {
m_selectionPointer->setHighlightColor(
- Utils::vectorFromColor(series->singleHighlightColor()));
+ Utils::vectorFromColor(m_selectedSeries->singleHighlightColor()));
// Make sure selection pointer object reference is still good
- m_selectionPointer->setPointerObject(m_visibleSeriesList.at(0).object());
- m_selectionPointer->setRotation(m_visibleSeriesList.at(0).meshRotation());
+ m_selectionPointer->setPointerObject(cache->object());
+ m_selectionPointer->setRotation(cache->meshRotation());
}
}
}
+void Surface3DRenderer::modifiedSeriesList(const QVector<QSurface3DSeries *> &seriesList)
+{
+ foreach (QSurface3DSeries *series, seriesList) {
+ SurfaceSeriesRenderCache *cache = m_renderCacheList.value(series);
+ if (cache)
+ cache->setObjectDirty(true);
+ }
+}
+
void Surface3DRenderer::updateRows(const QVector<int> &rows)
{
// Surface only supports single series for now, so we are only interested in the first series
@@ -392,52 +396,53 @@ void Surface3DRenderer::updateSliceDataModel(const QPoint &point)
int column = point.y();
int row = point.x();
- for (int i = 0; i < m_sliceDataArray.size(); i++)
- delete m_sliceDataArray.at(i);
- m_sliceDataArray.clear();
-
- m_sliceDataArray.reserve(2);
- QSurfaceDataRow *sliceRow;
-
- float adjust = (0.025f * m_heightNormalizer) / 2.0f;
- float stepDown = 2.0f * adjust;
- if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow)) {
- QSurfaceDataRow *src = m_dataArray.at(row);
- sliceRow = new QSurfaceDataRow(src->size());
- for (int i = 0; i < sliceRow->size(); i++)
- (*sliceRow)[i].setPosition(QVector3D(src->at(i).x(), src->at(i).y() + adjust, -1.0f));
- } else {
- sliceRow = new QSurfaceDataRow(m_sampleSpace.height());
- for (int i = 0; i < m_sampleSpace.height(); i++) {
- (*sliceRow)[i].setPosition(QVector3D(m_dataArray.at(i)->at(column).z(),
- m_dataArray.at(i)->at(column).y() + adjust,
- -1.0f));
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ QSurfaceDataArray &sliceDataArray = cache->sliceDataArray();
+ for (int i = 0; i < sliceDataArray.size(); i++)
+ delete sliceDataArray.at(i);
+ sliceDataArray.clear();
+ sliceDataArray.reserve(2);
+
+ QSurfaceDataRow *sliceRow;
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ float adjust = (0.025f * m_heightNormalizer) / 2.0f;
+ float stepDown = 2.0f * adjust;
+ if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow)) {
+ QSurfaceDataRow *src = dataArray.at(row);
+ sliceRow = new QSurfaceDataRow(src->size());
+ for (int i = 0; i < sliceRow->size(); i++)
+ (*sliceRow)[i].setPosition(QVector3D(src->at(i).x(), src->at(i).y() + adjust, -1.0f));
+ } else {
+ QRect sampleSpace = cache->sampleSpace();
+ sliceRow = new QSurfaceDataRow(sampleSpace.height());
+ for (int i = 0; i < sampleSpace.height(); i++) {
+ (*sliceRow)[i].setPosition(QVector3D(dataArray.at(i)->at(column).z(),
+ dataArray.at(i)->at(column).y() + adjust,
+ -1.0f));
+ }
}
- }
- m_sliceDataArray << sliceRow;
+ sliceDataArray << sliceRow;
- // Make a duplicate, so that we get a little bit depth
- QSurfaceDataRow *duplicateRow = new QSurfaceDataRow(*sliceRow);
- for (int i = 0; i < sliceRow->size(); i++) {
- (*sliceRow)[i].setPosition(QVector3D(sliceRow->at(i).x(), sliceRow->at(i).y() - stepDown,
- 1.0f));
- }
-
- m_sliceDataArray << duplicateRow;
+ // Make a duplicate, so that we get a little bit depth
+ QSurfaceDataRow *duplicateRow = new QSurfaceDataRow(*sliceRow);
+ for (int i = 0; i < sliceRow->size(); i++) {
+ (*sliceRow)[i].setPosition(QVector3D(sliceRow->at(i).x(), sliceRow->at(i).y() - stepDown,
+ 1.0f));
+ }
- QRect sliceRect(0, 0, sliceRow->size(), 2);
+ sliceDataArray << duplicateRow;
- if (sliceRow->size() > 0) {
- if (!m_sliceSurfaceObj)
- loadSliceSurfaceObj();
+ QRect sliceRect(0, 0, sliceRow->size(), 2);
- if (!m_cachedFlatShading) {
- m_sliceSurfaceObj->setUpSmoothData(m_sliceDataArray, sliceRect, m_heightNormalizer,
- m_axisCacheY.min(), true);
- } else {
- m_sliceSurfaceObj->setUpData(m_sliceDataArray, sliceRect, m_heightNormalizer,
- m_axisCacheY.min(), true);
+ if (sliceRow->size() > 0) {
+ if (cache->isFlatShadingEnabled()) {
+ cache->sliceSurfaceObject()->setUpData(sliceDataArray, sliceRect, m_heightNormalizer,
+ m_axisCacheY.min(), true);
+ } else {
+ cache->sliceSurfaceObject()->setUpSmoothData(sliceDataArray, sliceRect, m_heightNormalizer,
+ m_axisCacheY.min(), true);
+ }
}
}
}
@@ -612,13 +617,11 @@ void Surface3DRenderer::drawSlicedScene()
offset = -m_surfaceOffsetZ;
}
- if (m_surfaceObj) {
+ if (m_renderCacheList.size()) {
QMatrix4x4 MVPMatrix;
QMatrix4x4 modelMatrix;
QMatrix4x4 itModelMatrix;
- const SeriesRenderCache &series = m_visibleSeriesList.at(0);
-
modelMatrix.translate(offset, 0.0f, 0.0f);
QVector3D scaling(scaleX, 1.0f, sliceZScale);
modelMatrix.scale(scaling);
@@ -626,41 +629,49 @@ void Surface3DRenderer::drawSlicedScene()
MVPMatrix = projectionViewMatrix * modelMatrix;
- if (m_cachedSurfaceVisible) {
- if (m_cachedSurfaceGridOn) {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(0.5f, 1.0f);
- }
+ bool drawGrid = false;
+
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->surfaceVisible()) {
+ if (cache->surfaceGridVisible()) {
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(0.5f, 1.0f);
+ drawGrid = true;
+ }
- ShaderHelper *surfaceShader = m_surfaceShader;
- surfaceShader->bind();
-
- GLuint baseGradientTexture = m_uniformGradientTexture;
- if (series.colorStyle() != Q3DTheme::ColorStyleUniform)
- baseGradientTexture = series.baseGradientTexture();
-
- // Set shader bindings
- surfaceShader->setUniformValue(surfaceShader->lightP(), lightPos);
- surfaceShader->setUniformValue(surfaceShader->view(), viewMatrix);
- surfaceShader->setUniformValue(surfaceShader->model(), modelMatrix);
- surfaceShader->setUniformValue(surfaceShader->nModel(),
- itModelMatrix.inverted().transposed());
- surfaceShader->setUniformValue(surfaceShader->MVP(), MVPMatrix);
- surfaceShader->setUniformValue(surfaceShader->lightS(), 0.15f);
- surfaceShader->setUniformValue(surfaceShader->ambientS(),
- m_cachedTheme->ambientLightStrength() * 2.3f);
- surfaceShader->setUniformValue(surfaceShader->lightColor(), lightColor);
-
- m_drawer->drawObject(surfaceShader, m_sliceSurfaceObj, baseGradientTexture);
+ ShaderHelper *surfaceShader = m_surfaceFlatShader;
+ surfaceShader->bind();
+
+ GLuint colorTexture = cache->baseUniformTexture();;
+ if (cache->colorStyle() != Q3DTheme::ColorStyleUniform)
+ colorTexture = cache->baseGradientTexture();
+
+ // Set shader bindings
+ surfaceShader->setUniformValue(surfaceShader->lightP(), lightPos);
+ surfaceShader->setUniformValue(surfaceShader->view(), viewMatrix);
+ surfaceShader->setUniformValue(surfaceShader->model(), modelMatrix);
+ surfaceShader->setUniformValue(surfaceShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ surfaceShader->setUniformValue(surfaceShader->MVP(), MVPMatrix);
+ surfaceShader->setUniformValue(surfaceShader->lightS(), 0.15f);
+ surfaceShader->setUniformValue(surfaceShader->ambientS(),
+ m_cachedTheme->ambientLightStrength() * 2.3f);
+ surfaceShader->setUniformValue(surfaceShader->lightColor(), lightColor);
+
+ m_drawer->drawObject(surfaceShader, cache->sliceSurfaceObject(), colorTexture);
+ }
}
// Draw surface grid
- if (m_cachedSurfaceGridOn) {
+ if (drawGrid) {
m_surfaceGridShader->bind();
m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(),
Utils::vectorFromColor(m_cachedTheme->gridLineColor()));
m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), MVPMatrix);
- m_drawer->drawSurfaceGrid(m_surfaceGridShader, m_sliceSurfaceObj);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->surfaceGridVisible())
+ m_drawer->drawSurfaceGrid(m_surfaceGridShader, cache->sliceSurfaceObject());
+ }
glDisable(GL_POLYGON_OFFSET_FILL);
}
@@ -849,8 +860,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_primarySubViewport.width(),
m_primarySubViewport.height());
- // Specify viewport
-
// Set up projection matrix
QMatrix4x4 projectionMatrix;
projectionMatrix.perspective(45.0f, (GLfloat)m_primarySubViewport.width()
@@ -893,8 +902,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// Draw depth buffer
#if !defined(QT_OPENGL_ES_2)
GLfloat adjustedLightStrength = m_cachedTheme->lightStrength() / 10.0f;
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && m_surfaceObj
- && m_cachedSurfaceVisible) {
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && m_renderCacheList.size()) {
// Render scene into a depth texture for using with shadow mapping
// Enable drawing to depth framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer);
@@ -943,18 +951,23 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(m_depthShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, m_surfaceObj->vertexBuf());
- glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
- (void *)0);
-
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceObj->elementBuf());
-
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, m_surfaceObj->indexCount(), m_surfaceObj->indicesType(),
- (void *)0);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->surfaceVisible() && cache->isSeriesVisible()) {
+ SurfaceObject *object = cache->surfaceObject();
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, object->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, object->indexCount(),
+ object->indicesType(), (void *)0);
+ }
+ }
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
@@ -963,9 +976,23 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_depthModelTexture, 0);
glClear(GL_DEPTH_BUFFER_BIT);
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, m_surfaceObj->indexCount(), m_surfaceObj->indicesType(),
- (void *)0);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->surfaceVisible() && cache->isSeriesVisible()) {
+ SurfaceObject *object = cache->surfaceObject();
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, object->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, object->indexCount(),
+ object->indicesType(), (void *)0);
+ }
+ }
// Free buffers
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -991,10 +1018,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glEnable(GL_TEXTURE_2D);
// Draw selection buffer
- if (!m_cachedIsSlicingActivated && m_surfaceObj && m_selectionState == SelectOnScene
- && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone
- && (m_cachedSurfaceVisible || m_cachedSurfaceGridOn)
- && m_visibleSeriesList.size() > 0) {
+ if (!m_cachedIsSlicingActivated && m_renderCacheList.size() && m_selectionState == SelectOnScene
+ && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone) {
m_selectionShader->bind();
glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
glViewport(0,
@@ -1019,7 +1044,12 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
- m_drawer->drawObject(m_selectionShader, m_surfaceObj, m_selectionTexture);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->surfaceVisible() && cache->isSeriesVisible()) {
+ m_drawer->drawObject(m_selectionShader, cache->surfaceObject(),
+ cache->selectionTexture());
+ }
+ }
glEnable(GL_DITHER);
@@ -1037,7 +1067,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
#endif
m_clickedPosition = selectionIdToSurfacePoint(selectionId);
- m_clickedSeries = m_visibleSeriesList.at(0).series();
emit needRender();
@@ -1049,14 +1078,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
}
// Draw the surface
- if (m_surfaceObj && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
- m_surfaceShader->bind();
+ if (m_renderCacheList.size()) {
// For surface we can see climpses from underneath
glDisable(GL_CULL_FACE);
- if (m_cachedSurfaceGridOn) {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(0.5f, 1.0f);
- }
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
@@ -1071,57 +1095,77 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
#else
MVPMatrix = projectionViewMatrix * modelMatrix;
#endif
+ bool drawGrid = false;
+
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ QRect sampleSpace = cache->sampleSpace();
+ if (cache->isSeriesVisible() && sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ if (cache->surfaceGridVisible()) {
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(0.5f, 1.0f);
+ drawGrid = true;
+ }
- if (m_cachedSurfaceVisible) {
- // Set shader bindings
- m_surfaceShader->setUniformValue(m_surfaceShader->lightP(), lightPos);
- m_surfaceShader->setUniformValue(m_surfaceShader->view(), viewMatrix);
- m_surfaceShader->setUniformValue(m_surfaceShader->model(), modelMatrix);
- m_surfaceShader->setUniformValue(m_surfaceShader->nModel(),
- itModelMatrix.inverted().transposed());
- m_surfaceShader->setUniformValue(m_surfaceShader->MVP(), MVPMatrix);
- m_surfaceShader->setUniformValue(m_surfaceShader->ambientS(),
- m_cachedTheme->ambientLightStrength());
- m_surfaceShader->setUniformValue(m_surfaceShader->lightColor(), lightColor);
-
- GLuint gradientTexture;
- if (m_visibleSeriesList.at(0).colorStyle() == Q3DTheme::ColorStyleUniform)
- gradientTexture = m_uniformGradientTexture;
- else
- gradientTexture = m_visibleSeriesList.at(0).baseGradientTexture();
-
-#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- // Set shadow shader bindings
- QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
- m_surfaceShader->setUniformValue(m_surfaceShader->shadowQ(),
- m_shadowQualityToShader);
- m_surfaceShader->setUniformValue(m_surfaceShader->depth(), depthMVPMatrix);
- m_surfaceShader->setUniformValue(m_surfaceShader->lightS(), adjustedLightStrength);
-
- // Draw the object
- m_drawer->drawObject(m_surfaceShader, m_surfaceObj, gradientTexture,
- m_depthModelTexture);
- } else
-#endif
- {
- // Set shadowless shader bindings
- m_surfaceShader->setUniformValue(m_surfaceShader->lightS(),
- m_cachedTheme->lightStrength());
-
- // Draw the object
- m_drawer->drawObject(m_surfaceShader, m_surfaceObj, gradientTexture);
+ if (cache->surfaceVisible()) {
+ ShaderHelper *shader = m_surfaceFlatShader;
+ if (!cache->isFlatShadingEnabled())
+ shader = m_surfaceSmoothShader;
+ shader->bind();
+
+ // Set shader bindings
+ shader->setUniformValue(shader->lightP(), lightPos);
+ shader->setUniformValue(shader->view(), viewMatrix);
+ shader->setUniformValue(shader->model(), modelMatrix);
+ shader->setUniformValue(shader->nModel(),
+ itModelMatrix.inverted().transposed());
+ shader->setUniformValue(shader->MVP(), MVPMatrix);
+ shader->setUniformValue(shader->ambientS(),
+ m_cachedTheme->ambientLightStrength());
+ shader->setUniformValue(shader->lightColor(), lightColor);
+
+ GLuint gradientTexture;
+ if (cache->colorStyle() == Q3DTheme::ColorStyleUniform)
+ gradientTexture = cache->baseUniformTexture();
+ else
+ gradientTexture = cache->baseGradientTexture();
+
+ #if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ shader->setUniformValue(shader->shadowQ(), m_shadowQualityToShader);
+ shader->setUniformValue(shader->depth(), depthMVPMatrix);
+ shader->setUniformValue(shader->lightS(), adjustedLightStrength);
+
+ // Draw the objects
+ m_drawer->drawObject(shader, cache->surfaceObject(), gradientTexture, m_depthModelTexture);
+ } else
+ #endif
+ {
+ // Set shadowless shader bindings
+ shader->setUniformValue(shader->lightS(),
+ m_cachedTheme->lightStrength());
+
+ // Draw the objects
+ m_drawer->drawObject(shader, cache->surfaceObject(), gradientTexture);
+ }
+ }
}
- glEnable(GL_CULL_FACE);
}
+ glEnable(GL_CULL_FACE);
// Draw surface grid
- if (m_cachedSurfaceGridOn) {
+ if (drawGrid) {
m_surfaceGridShader->bind();
m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(),
Utils::vectorFromColor(m_cachedTheme->gridLineColor()));
m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), MVPMatrix);
- m_drawer->drawSurfaceGrid(m_surfaceGridShader, m_surfaceObj);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ QRect sampleSpace = cache->sampleSpace();
+ if (cache->surfaceGridVisible() && cache->isSeriesVisible() &&
+ sampleSpace.width() >= 2 && sampleSpace.height() >= 2)
+ m_drawer->drawSurfaceGrid(m_surfaceGridShader, cache->surfaceObject());
+ }
glDisable(GL_POLYGON_OFFSET_FILL);
}
@@ -1699,12 +1743,17 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// Selection handling
if (m_selectionDirty || m_selectionLabelDirty) {
QPoint visiblePoint = Surface3DController::invalidSelectionPosition();
- if (m_selectedPoint != Surface3DController::invalidSelectionPosition()) {
- int x = m_selectedPoint.x() - m_sampleSpace.y();
- int y = m_selectedPoint.y() - m_sampleSpace.x();
- if (x >= 0 && y >= 0 && x < m_sampleSpace.height() && y < m_sampleSpace.width()
- && m_dataArray.size()) {
- visiblePoint = QPoint(x, y);
+ if (m_selectedSeries) {
+ SurfaceSeriesRenderCache *cache =
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ if (cache && m_selectedPoint != Surface3DController::invalidSelectionPosition()) {
+ QRect sampleSpace = cache->sampleSpace();
+ int x = m_selectedPoint.x() - sampleSpace.y();
+ int y = m_selectedPoint.y() - sampleSpace.x();
+ if (x >= 0 && y >= 0 && x < sampleSpace.height() && y < sampleSpace.width()
+ && cache->dataArray().size()) {
+ visiblePoint = QPoint(x, y);
+ }
}
}
@@ -1723,47 +1772,64 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
-// This one needs to be called when the data size changes
-void Surface3DRenderer::updateSelectionTexture()
+void Surface3DRenderer::updateSelectionMode(QAbstract3DGraph::SelectionFlags mode)
+{
+ Abstract3DRenderer::updateSelectionMode(mode);
+
+ if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone)
+ updateSelectionTextures();
+}
+
+void Surface3DRenderer::updateSelectionTextures()
+{
+ uint lastSelectionId = 1;
+
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ GLuint texture = cache->selectionTexture();
+ m_textureHelper->deleteTexture(&texture);
+ createSelectionTexture(cache, lastSelectionId);
+ }
+ m_selectionTexturesDirty = false;
+}
+
+void Surface3DRenderer::createSelectionTexture(SurfaceSeriesRenderCache *cache, uint &lastSelectionId)
{
// Create the selection ID image. Each grid corner gets 2x2 pixel area of
// ID color so that each vertex (data point) has 4x4 pixel area of ID color
- int idImageWidth = (m_sampleSpace.width() - 1) * 4;
- int idImageHeight = (m_sampleSpace.height() - 1) * 4;
+ QRect sampleSpace = cache->sampleSpace();
+ int idImageWidth = (sampleSpace.width() - 1) * 4;
+ int idImageHeight = (sampleSpace.height() - 1) * 4;
int stride = idImageWidth * 4 * sizeof(uchar); // 4 = number of color components (rgba)
+ uint idStart = lastSelectionId;
uchar *bits = new uchar[idImageWidth * idImageHeight * 4 * sizeof(uchar)];
- uint id = 1;
for (int i = 0; i < idImageHeight; i += 4) {
for (int j = 0; j < idImageWidth; j += 4) {
int p = (i * idImageWidth + j) * 4;
uchar r, g, b, a;
- idToRGBA(id, &r, &g, &b, &a);
+ idToRGBA(lastSelectionId, &r, &g, &b, &a);
fillIdCorner(&bits[p], r, g, b, a, stride);
- idToRGBA(id + 1, &r, &g, &b, &a);
+ idToRGBA(lastSelectionId + 1, &r, &g, &b, &a);
fillIdCorner(&bits[p + 8], r, g, b, a, stride);
- idToRGBA(id + m_sampleSpace.width(), &r, &g, &b, &a);
+ idToRGBA(lastSelectionId + sampleSpace.width(), &r, &g, &b, &a);
fillIdCorner(&bits[p + 2 * stride], r, g, b, a, stride);
- idToRGBA(id + m_sampleSpace.width() + 1, &r, &g, &b, &a);
+ idToRGBA(lastSelectionId + sampleSpace.width() + 1, &r, &g, &b, &a);
fillIdCorner(&bits[p + 2 * stride + 8], r, g, b, a, stride);
- id++;
+ lastSelectionId++;
}
- id++;
- }
-
- // If old texture exists, delete it
- if (m_selectionTexture) {
- m_textureHelper->deleteTexture(&m_selectionTexture);
- m_selectionTexture = 0;
+ lastSelectionId++;
}
+ lastSelectionId += sampleSpace.width();
+ cache->setSelectionIdRange(idStart, lastSelectionId - 1);
// Move the ID image (bits) to the texture
QImage image = QImage(bits, idImageWidth, idImageHeight, QImage::Format_RGB32);
- m_selectionTexture = m_textureHelper->create2DTexture(image, false, false, false);
+ GLuint selectionTexture = m_textureHelper->create2DTexture(image, false, false, false);
+ cache->setSelectionTexture(selectionTexture);
// Release the temp bits allocation
delete[] bits;
@@ -1823,33 +1889,29 @@ void Surface3DRenderer::calculateSceneScalingFactors()
m_scaleZWithBackground = m_scaleZ * backgroundMargin;
}
-bool Surface3DRenderer::updateFlatStatus(bool enable)
+void Surface3DRenderer::checkFlatSupport(SurfaceSeriesRenderCache *cache)
{
- if (enable && !m_flatSupported) {
+ bool flatEnable = cache->isFlatShadingEnabled();
+ if (flatEnable && !m_flatSupported) {
qWarning() << "Warning: Flat qualifier not supported on your platform's GLSL language."
" Requires at least GLSL version 1.2 with GL_EXT_gpu_shader4 extension.";
- enable = false;
+ cache->setFlatShadingEnabled(false);
+ cache->setFlatChangeAllowed(false);
}
+}
- bool changed = false;
- if (enable != m_cachedFlatShading) {
- m_cachedFlatShading = enable;
- changed = true;
- initSurfaceShaders();
- }
+void Surface3DRenderer::updateObjects(SurfaceSeriesRenderCache *cache, bool dimensionChanged)
+{
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ const QRect sampleSpace = cache->sampleSpace();
- // If no surface object created yet, don't try to update the object
- if (m_surfaceObj && changed && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
- if (!m_cachedFlatShading) {
- m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- m_axisCacheY.min(), true);
- } else {
- m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- m_axisCacheY.min(), true);
- }
+ if (cache->isFlatShadingEnabled()) {
+ cache->surfaceObject()->setUpData(dataArray, sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), dimensionChanged);
+ } else {
+ cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), dimensionChanged);
}
-
- return m_cachedFlatShading;
}
void Surface3DRenderer::updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series)
@@ -1865,11 +1927,6 @@ void Surface3DRenderer::resetClickedStatus()
m_clickedSeries = 0;
}
-void Surface3DRenderer::updateSurfaceGridStatus(bool enable)
-{
- m_cachedSurfaceGridOn = enable;
-}
-
void Surface3DRenderer::loadBackgroundMesh()
{
if (m_backgroundObj)
@@ -1878,20 +1935,6 @@ void Surface3DRenderer::loadBackgroundMesh()
m_backgroundObj->load();
}
-void Surface3DRenderer::loadSurfaceObj()
-{
- if (m_surfaceObj)
- delete m_surfaceObj;
- m_surfaceObj = new SurfaceObject();
-}
-
-void Surface3DRenderer::loadSliceSurfaceObj()
-{
- if (m_sliceSurfaceObj)
- delete m_sliceSurfaceObj;
- m_sliceSurfaceObj = new SurfaceObject();
-}
-
void Surface3DRenderer::loadGridLineMesh()
{
if (m_gridLineObj)
@@ -1905,7 +1948,9 @@ void Surface3DRenderer::surfacePointSelected(const QPoint &point)
int row = point.x();
int column = point.y();
- float value = m_dataArray.at(row)->at(column).y();
+ SurfaceSeriesRenderCache *cache = m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ float value = dataArray.at(row)->at(column).y();
if (!m_selectionPointer)
m_selectionPointer = new SelectionPointer(m_drawer);
@@ -1913,20 +1958,20 @@ void Surface3DRenderer::surfacePointSelected(const QPoint &point)
QVector3D pos;
if (m_cachedIsSlicingActivated) {
if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow)) {
- pos = m_sliceSurfaceObj->vertexAt(column, 0);
+ pos = cache->sliceSurfaceObject()->vertexAt(column, 0);
pos *= QVector3D(m_surfaceScaleX, 1.0f, 0.0f);
pos += QVector3D(m_surfaceOffsetX, 0.0f, 0.0f);
m_selectionPointer->updateBoundingRect(m_secondarySubViewport);
m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
} else if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionColumn)) {
- pos = m_sliceSurfaceObj->vertexAt(row, 0);
+ pos = cache->sliceSurfaceObject()->vertexAt(row, 0);
pos *= QVector3D(m_surfaceScaleZ, 1.0f, 0.0f);
pos += QVector3D(-m_surfaceOffsetZ, 0.0f, 0.0f);
m_selectionPointer->updateBoundingRect(m_secondarySubViewport);
m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
}
} else {
- pos = m_surfaceObj->vertexAt(column, row);
+ pos = cache->surfaceObject()->vertexAt(column, row);
pos *= QVector3D(m_surfaceScaleX, 1.0f, m_surfaceScaleZ);;
pos += QVector3D(m_surfaceOffsetX, 0.0f, m_surfaceOffsetZ);
m_selectionPointer->updateBoundingRect(m_primarySubViewport);
@@ -1935,23 +1980,42 @@ void Surface3DRenderer::surfacePointSelected(const QPoint &point)
m_selectionPointer->setPosition(pos);
m_selectionPointer->setLabel(createSelectionLabel(value, column, row));
- m_selectionPointer->setPointerObject(m_visibleSeriesList.at(0).object());
- m_selectionPointer->setHighlightColor(m_visibleSeriesList.at(0).singleHighlightColor());
+ m_selectionPointer->setPointerObject(cache->object());
+ m_selectionPointer->setHighlightColor(cache->singleHighlightColor());
m_selectionPointer->updateScene(m_cachedScene);
- m_selectionPointer->setRotation(m_visibleSeriesList.at(0).meshRotation());
+ m_selectionPointer->setRotation(cache->meshRotation());
}
// Maps selection Id to surface point in data array
QPoint Surface3DRenderer::selectionIdToSurfacePoint(uint id)
{
- int column = ((id - 1) % m_sampleSpace.width()) + m_sampleSpace.x();
- int row = ((id - 1) / m_sampleSpace.width()) + m_sampleSpace.y();
+ SurfaceSeriesRenderCache *selectedCache = 0;
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->isWithinIdRange(id)) {
+ selectedCache = cache;
+ break;
+ }
+ }
+ if (!selectedCache) {
+ m_clickedSeries = 0;
+ return Surface3DController::invalidSelectionPosition();
+ }
+
+ uint idInSeries = id - selectedCache->selectionIdStart() + 1;
+ QRect sampleSpace = selectedCache->sampleSpace();
+ int column = ((idInSeries - 1) % sampleSpace.width()) + sampleSpace.x();
+ int row = ((idInSeries - 1) / sampleSpace.width()) + sampleSpace.y();
+
+ m_clickedSeries = selectedCache->series();
return QPoint(row, column);
}
QString Surface3DRenderer::createSelectionLabel(float value, int column, int row)
{
- QString labelText = m_visibleSeriesList[0].itemLabelFormat();
+ SurfaceSeriesRenderCache *cache =
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ QString labelText = cache->itemLabelFormat();
static const QString xTitleTag(QStringLiteral("@xTitle"));
static const QString yTitleTag(QStringLiteral("@yTitle"));
static const QString zTitleTag(QStringLiteral("@zTitle"));
@@ -1969,7 +2033,7 @@ QString Surface3DRenderer::createSelectionLabel(float value, int column, int row
if (labelFormat.isEmpty())
labelFormat = Utils::defaultLabelFormat();
QString valueLabelText = generateValueLabel(labelFormat,
- m_dataArray.at(row)->at(column).x());
+ dataArray.at(row)->at(column).x());
labelText.replace(xLabelTag, valueLabelText);
}
if (labelText.contains(yLabelTag)) {
@@ -1984,11 +2048,11 @@ QString Surface3DRenderer::createSelectionLabel(float value, int column, int row
if (labelFormat.isEmpty())
labelFormat = Utils::defaultLabelFormat();
QString valueLabelText = generateValueLabel(labelFormat,
- m_dataArray.at(row)->at(column).z());
+ dataArray.at(row)->at(column).z());
labelText.replace(zLabelTag, valueLabelText);
}
- labelText.replace(seriesNameTag, m_visibleSeriesList[0].name());
+ labelText.replace(seriesNameTag, cache->name());
m_selectionLabelDirty = false;
@@ -2073,31 +2137,34 @@ void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &
Q_UNUSED(fragmentShader);
// draw the shader for the surface according to smooth status, shadow and uniform color
- if (m_surfaceShader)
- delete m_surfaceShader;
+ if (m_surfaceFlatShader)
+ delete m_surfaceFlatShader;
+ if (m_surfaceSmoothShader)
+ delete m_surfaceSmoothShader;
+
#if !defined(QT_OPENGL_ES_2)
- if (!m_cachedFlatShading) {
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentSurfaceShadowNoTex"));
- } else {
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentSurface"));
- }
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ m_surfaceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentSurfaceShadowNoTex"));
} else {
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceShadowFlat"),
+ m_surfaceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentSurface"));
+ }
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ m_surfaceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceShadowFlat"),
QStringLiteral(":/shaders/fragmentSurfaceShadowFlat"));
- } else {
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
+ } else {
+ m_surfaceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
QStringLiteral(":/shaders/fragmentSurfaceFlat"));
- }
}
#else
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentSurfaceES2"));
+ m_surfaceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentSurfaceES2"));
+ m_surfaceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentSurfaceES2"));
#endif
- m_surfaceShader->initialize();
+ m_surfaceSmoothShader->initialize();
+ m_surfaceFlatShader->initialize();
}
void Surface3DRenderer::initBackgroundShaders(const QString &vertexShader,
@@ -2177,16 +2244,4 @@ void Surface3DRenderer::updateDepthBuffer()
}
#endif
-void Surface3DRenderer::generateUniformGradient(const QVector3D newColor)
-{
- if (m_visibleSeriesList.size()) {
- QColor newQColor = Utils::colorFromVector(newColor);
- m_uniformGradientTextureColor = newColor;
- QLinearGradient newGradient;
- newGradient.setColorAt(0.0, newQColor);
- newGradient.setColorAt(1.0, newQColor);
- fixGradientAndGenerateTexture(&newGradient, &m_uniformGradientTexture);
- }
-}
-
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index 06973f43..5f4e70ec 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -34,6 +34,7 @@
#include "abstract3drenderer_p.h"
#include "scatterrenderitem_p.h"
#include "qsurfacedataproxy.h"
+#include "surfaceseriesrendercache_p.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -60,7 +61,8 @@ private:
// Internal attributes purely related to how the scene is drawn with GL.
ShaderHelper *m_depthShader;
ShaderHelper *m_backgroundShader;
- ShaderHelper *m_surfaceShader;
+ ShaderHelper *m_surfaceFlatShader;
+ ShaderHelper *m_surfaceSmoothShader;
ShaderHelper *m_surfaceGridShader;
ShaderHelper *m_selectionShader;
ShaderHelper *m_labelShader;
@@ -84,19 +86,15 @@ private:
ObjectHelper *m_gridLineObj;
ObjectHelper *m_labelObj;
SurfaceObject *m_surfaceObj;
- SurfaceObject *m_sliceSurfaceObj;
GLuint m_depthTexture;
GLuint m_depthModelTexture;
GLuint m_depthFrameBuffer;
GLuint m_selectionFrameBuffer;
GLuint m_selectionDepthBuffer;
- GLuint m_selectionTexture;
GLuint m_selectionResultTexture;
GLfloat m_shadowQualityToShader;
bool m_cachedFlatShading;
bool m_flatSupported;
- bool m_cachedSurfaceVisible;
- bool m_cachedSurfaceGridOn;
SelectionPointer *m_selectionPointer;
bool m_selectionActive;
bool m_xFlipped;
@@ -104,7 +102,6 @@ private:
bool m_yFlipped;
AbstractRenderItem m_dummyRenderItem;
QSurfaceDataArray m_dataArray;
- QSurfaceDataArray m_sliceDataArray;
QRect m_sampleSpace;
GLint m_shadowQualityMultiplier;
QSizeF m_areaSize;
@@ -112,9 +109,10 @@ private:
bool m_hasHeightAdjustmentChanged;
QPoint m_selectedPoint;
const QSurface3DSeries *m_selectedSeries;
- GLuint m_uniformGradientTexture;
QVector3D m_uniformGradientTextureColor;
QPoint m_clickedPosition;
+ QHash<QSurface3DSeries *, SurfaceSeriesRenderCache *> m_renderCacheList;
+ bool m_selectionTexturesDirty;
public:
explicit Surface3DRenderer(Surface3DController *controller);
@@ -122,11 +120,11 @@ public:
void updateData();
void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility);
+ void updateSelectionMode(QAbstract3DGraph::SelectionFlags mode);
+ void modifiedSeriesList(const QVector<QSurface3DSeries *> &seriesList);
void updateRows(const QVector<int> &rows);
void updateItem(const QVector<QPoint> &points);
void updateScene(Q3DScene *scene);
- bool updateFlatStatus(bool enable);
- void updateSurfaceGridStatus(bool enable);
void updateSlicingActive(bool isSlicing);
void updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series);
inline QPoint clickedPosition() const { return m_clickedPosition; }
@@ -142,6 +140,8 @@ signals:
void flatShadingSupportedChanged(bool supported);
private:
+ void checkFlatSupport(SurfaceSeriesRenderCache *cache);
+ void updateObjects(SurfaceSeriesRenderCache *cache, bool dimensionChanged);
void updateSliceDataModel(const QPoint &point);
void updateShadowQuality(QAbstract3DGraph::ShadowQuality quality);
void updateTextures();
@@ -150,8 +150,6 @@ private:
void loadBackgroundMesh();
void loadGridLineMesh();
void loadLabelMesh();
- void loadSurfaceObj();
- void loadSliceSurfaceObj();
void drawScene(GLuint defaultFboHandle);
void calculateSceneScalingFactors();
void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
@@ -160,7 +158,8 @@ private:
void initSurfaceShaders();
void initSelectionBuffer();
void initDepthShader();
- void updateSelectionTexture();
+ void updateSelectionTextures();
+ void createSelectionTexture(SurfaceSeriesRenderCache *cache, uint &lastSelectionId);
void idToRGBA(uint id, uchar *r, uchar *g, uchar *b, uchar *a);
void fillIdCorner(uchar *p, uchar r, uchar g, uchar b, uchar a, int stride);
void surfacePointSelected(const QPoint &point);
@@ -170,7 +169,6 @@ private:
void updateDepthBuffer();
#endif
void emitSelectedPointChanged(QPoint position);
- void generateUniformGradient(const QVector3D newColor);
Q_DISABLE_COPY(Surface3DRenderer)
};
diff --git a/src/datavisualization/engine/surfaceseriesrendercache.cpp b/src/datavisualization/engine/surfaceseriesrendercache.cpp
new file mode 100644
index 00000000..e6243472
--- /dev/null
+++ b/src/datavisualization/engine/surfaceseriesrendercache.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 "seriesrendercache_p.h"
+#include "surfaceseriesrendercache_p.h"
+#include "objecthelper_p.h"
+#include "abstract3drenderer_p.h"
+#include "texturehelper_p.h"
+#include "utils_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+SurfaceSeriesRenderCache::SurfaceSeriesRenderCache()
+ : m_surfaceVisible(false),
+ m_surfaceGridVisible(false),
+ m_surfaceFlatShading(true),
+ m_surfaceObj(new SurfaceObject),
+ m_sliceSurfaceObj(new SurfaceObject),
+ m_sampleSpace(QRect(0, 0, 0 , 0)),
+ m_selectionTexture(0),
+ m_selectionIdStart(0),
+ m_selectionIdEnd(0),
+ m_flatChangeAllowed(true),
+ m_flatStatusDirty(false),
+ m_valid(false),
+ m_objectDirty(true)
+{
+}
+
+SurfaceSeriesRenderCache::~SurfaceSeriesRenderCache()
+{
+ delete m_surfaceObj;
+ delete m_sliceSurfaceObj;
+ for (int i = 0; i < m_dataArray.size(); i++)
+ delete m_dataArray.at(i);
+ m_dataArray.clear();
+
+ for (int i = 0; i < m_sliceDataArray.size(); i++)
+ delete m_sliceDataArray.at(i);
+ m_sliceDataArray.clear();
+}
+
+void SurfaceSeriesRenderCache::populate(QSurface3DSeries *series, Abstract3DRenderer *renderer)
+{
+ Q_ASSERT(series);
+
+ SeriesRenderCache::populate(series, renderer);
+
+ 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();
+ m_flatStatusDirty = true;
+ }
+}
+
+QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/surfaceseriesrendercache_p.h b/src/datavisualization/engine/surfaceseriesrendercache_p.h
new file mode 100644
index 00000000..a0d23e45
--- /dev/null
+++ b/src/datavisualization/engine/surfaceseriesrendercache_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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 SURFACESERIESRENDERCACHE_P_H
+#define SURFACESERIESRENDERCACHE_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "seriesrendercache_p.h"
+#include "qabstract3dseries_p.h"
+#include "qsurface3dseries_p.h"
+#include "surfaceobject_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class Abstract3DRenderer;
+class ObjectHelper;
+class TextureHelper;
+
+class SurfaceSeriesRenderCache : public SeriesRenderCache
+{
+public:
+ SurfaceSeriesRenderCache();
+ virtual ~SurfaceSeriesRenderCache();
+
+ void populate(QSurface3DSeries *series, Abstract3DRenderer *renderer);
+ void cleanup(TextureHelper *texHelper);
+
+ inline bool surfaceVisible() const { return m_surfaceVisible; }
+ inline bool surfaceGridVisible() const { return m_surfaceGridVisible; }
+ 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; }
+ inline void setSampleSpace(const QRect &sampleSpace) { m_sampleSpace = sampleSpace; }
+ 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 void setObjectDirty(bool state) { m_objectDirty = state; }
+ inline bool objectDirty() const { return m_objectDirty; }
+ 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;
+ m_selectionIdEnd = end; }
+ inline uint selectionIdStart() const { return m_selectionIdStart; }
+ inline bool isWithinIdRange(uint selection) const { return selection >= m_selectionIdStart &&
+ selection <= m_selectionIdEnd; }
+ inline bool isFlatStatusDirty() const { return m_flatStatusDirty; }
+ inline void setFlatStatusDirty(bool status) { m_flatStatusDirty = status; }
+
+protected:
+ bool m_surfaceVisible;
+ bool m_surfaceGridVisible;
+ bool m_surfaceFlatShading;
+ SurfaceObject *m_surfaceObj;
+ SurfaceObject *m_sliceSurfaceObj;
+ QRect m_sampleSpace;
+ QSurfaceDataArray m_dataArray;
+ QSurfaceDataArray m_sliceDataArray;
+ GLuint m_selectionTexture;
+ uint m_selectionIdStart;
+ uint m_selectionIdEnd;
+ bool m_flatChangeAllowed;
+ bool m_flatStatusDirty;
+
+ bool m_valid;
+ bool m_objectDirty;
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif
diff --git a/src/datavisualization/global/datavisualizationglobal_p.h b/src/datavisualization/global/datavisualizationglobal_p.h
index 83af408a..2cfa559c 100644
--- a/src/datavisualization/global/datavisualizationglobal_p.h
+++ b/src/datavisualization/global/datavisualizationglobal_p.h
@@ -55,6 +55,8 @@ static const QVector3D selectionSkipColor = QVector3D(255.0f, 255.0f, 255.0f);
static const QVector3D invalidColorVector = QVector3D(-1.0f, -1.0f, -1.0f);
static const GLfloat gradientTextureHeight = 1024.0f;
static const GLfloat gradientTextureWidth = 2.0f;
+static const GLfloat uniformTextureHeight = 64.0f;
+static const GLfloat uniformTextureWidth = 2.0f;
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index b0cd6c82..cfaab09c 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -25,6 +25,10 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
SurfaceObject::SurfaceObject()
+ : m_surfaceType(Undefined),
+ m_columns(0),
+ m_rows(0),
+ m_gridIndexCount(0)
{
m_indicesType = GL_UNSIGNED_INT;
initializeOpenGLFunctions();
@@ -668,6 +672,9 @@ GLuint SurfaceObject::gridIndexCount()
QVector3D SurfaceObject::vertexAt(int column, int row)
{
int pos = 0;
+ if (m_surfaceType == Undefined || !m_vertices.size())
+ return zeroVector;
+
if (m_surfaceType == SurfaceFlat)
pos = row * (m_columns * 2 - 2) + column * 2 - (column > 0);
else
diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index ec1a30bd..f51c2909 100644
--- a/src/datavisualization/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -40,6 +40,13 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class SurfaceObject : public AbstractObjectHelper
{
public:
+ enum SurfaceType {
+ SurfaceSmooth,
+ SurfaceFlat,
+ Undefined
+ };
+
+public:
SurfaceObject();
~SurfaceObject();
@@ -71,11 +78,7 @@ private:
bool changeGeometry);
private:
- enum SurfaceType {
- SurfaceSmooth,
- SurfaceFlat
- };
- int m_surfaceType;
+ SurfaceType m_surfaceType;
int m_columns;
int m_rows;
GLuint m_gridElementbuffer;
diff --git a/src/datavisualization/utils/texturehelper.cpp b/src/datavisualization/utils/texturehelper.cpp
index 91d70946..0f5c8313 100644
--- a/src/datavisualization/utils/texturehelper.cpp
+++ b/src/datavisualization/utils/texturehelper.cpp
@@ -151,6 +151,18 @@ GLuint TextureHelper::createSelectionTexture(const QSize &size, GLuint &frameBuf
return textureid;
}
+GLuint TextureHelper::createUniformTexture(const QColor &color)
+{
+ QImage image(QSize(int(uniformTextureWidth), int(uniformTextureHeight)),
+ QImage::Format_RGB32);
+ QPainter pmp(&image);
+ pmp.setBrush(QBrush(color));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, int(uniformTextureWidth), int(uniformTextureHeight));
+
+ return create2DTexture(image, false, true, false, true);
+}
+
GLuint TextureHelper::createGradientTexture(const QLinearGradient &gradient)
{
QImage image(QSize(int(gradientTextureWidth), int(gradientTextureHeight)),
diff --git a/src/datavisualization/utils/texturehelper_p.h b/src/datavisualization/utils/texturehelper_p.h
index 17553f30..f9a23a08 100644
--- a/src/datavisualization/utils/texturehelper_p.h
+++ b/src/datavisualization/utils/texturehelper_p.h
@@ -48,6 +48,7 @@ class TextureHelper : protected QOpenGLFunctions
GLuint createCubeMapTexture(const QImage &image, bool useTrilinearFiltering = false);
// Returns selection texture and inserts generated framebuffers to framebuffer parameters
GLuint createSelectionTexture(const QSize &size, GLuint &frameBuffer, GLuint &depthBuffer);
+ GLuint createUniformTexture(const QColor &color);
GLuint createGradientTexture(const QLinearGradient &gradient);
#if !defined(QT_OPENGL_ES_2)
GLuint createDepthTexture(const QSize &size, GLuint textureSize);
diff --git a/tests/surfacetest/graphmodifier.cpp b/tests/surfacetest/graphmodifier.cpp
index 528a803b..c6247bb5 100644
--- a/tests/surfacetest/graphmodifier.cpp
+++ b/tests/surfacetest/graphmodifier.cpp
@@ -34,14 +34,18 @@ using namespace QtDataVisualization;
GraphModifier::GraphModifier(Q3DSurface *graph)
: m_graph(graph),
+ m_series1(new QSurface3DSeries),
+ m_series2(new QSurface3DSeries),
+ m_series3(new QSurface3DSeries),
+ m_series4(new QSurface3DSeries),
m_gridSliderX(0),
m_gridSliderZ(0),
m_axisRangeSliderX(0),
m_axisRangeSliderZ(0),
m_axisMinSliderX(0),
m_axisMinSliderZ(0),
- m_xCount(50),
- m_zCount(50),
+ m_xCount(24),
+ m_zCount(24),
m_activeSample(0),
m_fontSize(40),
m_rangeX(16.0),
@@ -53,15 +57,32 @@ GraphModifier::GraphModifier(Q3DSurface *graph)
m_insertTestIndexPos(1),
m_planeArray(0),
m_theSeries(new QSurface3DSeries),
- m_drawMode(QSurface3DSeries::DrawSurfaceAndWireframe)
+ m_drawMode(QSurface3DSeries::DrawSurfaceAndWireframe),
+ m_drawMode2(QSurface3DSeries::DrawSurfaceAndWireframe),
+ m_drawMode3(QSurface3DSeries::DrawSurfaceAndWireframe),
+ m_drawMode4(QSurface3DSeries::DrawSurfaceAndWireframe)
{
m_graph->setAxisX(new QValue3DAxis);
m_graph->setAxisY(new QValue3DAxis);
m_graph->setAxisZ(new QValue3DAxis);
+#ifdef MULTI_SERIES
+ m_limitX = float(m_xCount) / 2.0f;
+ m_limitZ = float(m_zCount) / 2.0f;
+ m_graph->axisX()->setRange(-m_limitX, m_limitX);
+ m_graph->axisY()->setRange(-1.0f, 4.5f);
+ m_graph->axisZ()->setRange(-m_limitZ, m_limitZ);
+#else
m_graph->axisX()->setRange(m_minX, m_minX + m_rangeX);
m_graph->axisZ()->setRange(m_minZ, m_minZ + m_rangeZ);
m_graph->addSeries(m_theSeries);
+#endif
+
+ for (int i = 0; i < 4; i++) {
+ m_multiseries[i] = new QSurface3DSeries;
+ m_multiseries[i]->setItemLabelFormat(QStringLiteral("@seriesName: (@xLabel, @zLabel): @yLabel"));
+ }
+ fillSeries();
changeStyle();
m_theSeries->setItemLabelFormat(QStringLiteral("@seriesName: (@xLabel, @zLabel): @yLabel"));
@@ -82,10 +103,100 @@ GraphModifier::~GraphModifier()
delete m_graph;
}
+void GraphModifier::fillSeries()
+{
+ int full = m_limitX * m_limitZ;
+
+ QSurfaceDataArray *dataArray1 = new QSurfaceDataArray;
+ dataArray1->reserve(m_zCount);
+ QSurfaceDataArray *dataArray2 = new QSurfaceDataArray;
+ dataArray2->reserve(m_zCount);
+ QSurfaceDataArray *dataArray3 = new QSurfaceDataArray;
+ dataArray3->reserve(m_zCount);
+ QSurfaceDataArray *dataArray4 = new QSurfaceDataArray;
+ dataArray4->reserve(m_zCount);
+
+ for (int i = 0; i < m_zCount; i++) {
+ QSurfaceDataRow *newRow1 = new QSurfaceDataRow(m_xCount);
+ QSurfaceDataRow *newRow2 = new QSurfaceDataRow(m_xCount);
+ QSurfaceDataRow *newRow3 = new QSurfaceDataRow(m_xCount);
+ QSurfaceDataRow *newRow4 = new QSurfaceDataRow(m_xCount);
+
+ for (int j = 0; j < m_xCount; j++) {
+ float x = float(j) - m_limitX + 0.5f;
+ float z = float(i) - m_limitZ + 0.5f;
+ float angle = (z * x) / float(full) * 1.57f;
+ (*newRow1)[j].setPosition(QVector3D(x, qSin(angle), z));
+ angle *= 1.3f;
+ (*newRow2)[j].setPosition(QVector3D(x, qSin(angle) + 1.1f, z));
+ angle *= 1.3f;
+ (*newRow3)[j].setPosition(QVector3D(x, qSin(angle) + 2.2f, z));
+ angle *= 1.3f;
+ (*newRow4)[j].setPosition(QVector3D(x, qSin(angle) + 3.3f, z));
+ }
+ *dataArray1 << newRow1;
+ *dataArray2 << newRow2;
+ *dataArray3 << newRow3;
+ *dataArray4 << newRow4;
+ }
+
+ m_multiseries[0]->dataProxy()->resetArray(dataArray1);
+ m_multiseries[1]->dataProxy()->resetArray(dataArray2);
+ m_multiseries[2]->dataProxy()->resetArray(dataArray3);
+ m_multiseries[3]->dataProxy()->resetArray(dataArray4);
+}
+
+void GraphModifier::toggleSeries1(bool enabled)
+{
+ qDebug() << __FUNCTION__ << " enabled = " << enabled;
+
+ if (enabled) {
+ m_graph->addSeries(m_multiseries[0]);
+ } else {
+ m_graph->removeSeries(m_multiseries[0]);
+ }
+}
+
+void GraphModifier::toggleSeries2(bool enabled)
+{
+ qDebug() << __FUNCTION__ << " enabled = " << enabled;
+
+ if (enabled) {
+ m_graph->addSeries(m_multiseries[1]);
+ } else {
+ m_graph->removeSeries(m_multiseries[1]);
+ }
+}
+
+void GraphModifier::toggleSeries3(bool enabled)
+{
+ qDebug() << __FUNCTION__ << " enabled = " << enabled;
+
+ if (enabled) {
+ m_graph->addSeries(m_multiseries[2]);
+ } else {
+ m_graph->removeSeries(m_multiseries[2]);
+ }
+}
+
+void GraphModifier::toggleSeries4(bool enabled)
+{
+ qDebug() << __FUNCTION__ << " enabled = " << enabled;
+
+ if (enabled) {
+ m_graph->addSeries(m_multiseries[3]);
+ } else {
+ m_graph->removeSeries(m_multiseries[3]);
+ }
+}
+
void GraphModifier::toggleSmooth(bool enabled)
{
qDebug() << "GraphModifier::toggleSmooth " << enabled;
m_theSeries->setFlatShadingEnabled(enabled);
+#ifdef MULTI_SERIES
+ m_multiseries[0]->setFlatShadingEnabled(enabled);
+#endif
}
void GraphModifier::toggleSurfaceGrid(bool enable)
@@ -97,6 +208,9 @@ void GraphModifier::toggleSurfaceGrid(bool enable)
m_drawMode &= ~QSurface3DSeries::DrawWireframe;
m_theSeries->setDrawMode(m_drawMode);
+#ifdef MULTI_SERIES
+ m_multiseries[0]->setDrawMode(m_drawMode);
+#endif
}
void GraphModifier::toggleSurface(bool enable)
@@ -108,11 +222,119 @@ void GraphModifier::toggleSurface(bool enable)
m_drawMode &= ~QSurface3DSeries::DrawSurface;
m_theSeries->setDrawMode(m_drawMode);
+#ifdef MULTI_SERIES
+ m_multiseries[0]->setDrawMode(m_drawMode);
+#endif
}
void GraphModifier::toggleSeriesVisible(bool enable)
{
m_theSeries->setVisible(enable);
+#ifdef MULTI_SERIES
+ m_multiseries[0]->setVisible(enable);
+#endif
+}
+
+void GraphModifier::toggleSmoothS2(bool enabled)
+{
+ qDebug() << __FUNCTION__ << enabled;
+ m_multiseries[1]->setFlatShadingEnabled(enabled);
+}
+
+void GraphModifier::toggleSurfaceGridS2(bool enable)
+{
+ qDebug() << __FUNCTION__ << enable;
+ if (enable)
+ m_drawMode2 |= QSurface3DSeries::DrawWireframe;
+ else
+ m_drawMode2 &= ~QSurface3DSeries::DrawWireframe;
+
+ m_multiseries[1]->setDrawMode(m_drawMode2);
+}
+
+void GraphModifier::toggleSurfaceS2(bool enable)
+{
+ qDebug() << __FUNCTION__ << enable;
+ if (enable)
+ m_drawMode2 |= QSurface3DSeries::DrawSurface;
+ else
+ m_drawMode2 &= ~QSurface3DSeries::DrawSurface;
+
+ m_multiseries[1]->setDrawMode(m_drawMode2);
+}
+
+void GraphModifier::toggleSeries2Visible(bool enable)
+{
+ qDebug() << __FUNCTION__ << enable;
+ m_multiseries[1]->setVisible(enable);
+}
+
+void GraphModifier::toggleSmoothS3(bool enabled)
+{
+ qDebug() << __FUNCTION__ << enabled;
+ m_multiseries[2]->setFlatShadingEnabled(enabled);
+}
+
+void GraphModifier::toggleSurfaceGridS3(bool enable)
+{
+ qDebug() << __FUNCTION__ << enable;
+ if (enable)
+ m_drawMode3 |= QSurface3DSeries::DrawWireframe;
+ else
+ m_drawMode3 &= ~QSurface3DSeries::DrawWireframe;
+
+ m_multiseries[2]->setDrawMode(m_drawMode3);
+}
+
+void GraphModifier::toggleSurfaceS3(bool enable)
+{
+ qDebug() << __FUNCTION__ << enable;
+ if (enable)
+ m_drawMode3 |= QSurface3DSeries::DrawSurface;
+ else
+ m_drawMode3 &= ~QSurface3DSeries::DrawSurface;
+
+ m_multiseries[2]->setDrawMode(m_drawMode3);
+}
+
+void GraphModifier::toggleSeries3Visible(bool enable)
+{
+ qDebug() << __FUNCTION__ << enable;
+ m_multiseries[2]->setVisible(enable);
+}
+
+void GraphModifier::toggleSmoothS4(bool enabled)
+{
+ qDebug() << __FUNCTION__ << enabled;
+ m_multiseries[3]->setFlatShadingEnabled(enabled);
+}
+
+void GraphModifier::toggleSurfaceGridS4(bool enable)
+{
+ qDebug() << __FUNCTION__ << enable;
+ if (enable)
+ m_drawMode4 |= QSurface3DSeries::DrawWireframe;
+ else
+ m_drawMode4 &= ~QSurface3DSeries::DrawWireframe;
+
+ m_multiseries[3]->setDrawMode(m_drawMode4);
+}
+
+void GraphModifier::toggleSurfaceS4(bool enable)
+{
+ qDebug() << __FUNCTION__ << enable;
+ if (enable)
+ m_drawMode4 |= QSurface3DSeries::DrawSurface;
+ else
+ m_drawMode4 &= ~QSurface3DSeries::DrawSurface;
+
+ m_multiseries[3]->setDrawMode(m_drawMode4);
+}
+
+void GraphModifier::toggleSeries4Visible(bool enable)
+{
+ qDebug() << __FUNCTION__ << enable;
+ m_multiseries[3]->setVisible(enable);
}
void GraphModifier::toggleSqrtSin(bool enable)
@@ -347,9 +569,14 @@ void GraphModifier::gradientPressed()
gradient.setColorAt(0.33, Qt::blue);
gradient.setColorAt(0.67, Qt::red);
gradient.setColorAt(1.0, Qt::yellow);
- m_graph->seriesList().at(0)->setBaseGradient(gradient);
- m_graph->seriesList().at(0)->setSingleHighlightColor(Qt::red);
- m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
+// m_graph->seriesList().at(0)->setBaseGradient(gradient);
+// m_graph->seriesList().at(0)->setSingleHighlightColor(Qt::red);
+// m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
+
+ QList<QLinearGradient> gradients;
+ gradients << gradient;
+ m_graph->activeTheme()->setBaseGradients(gradients);
+ m_graph->activeTheme()->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
}
void GraphModifier::changeFont(const QFont &font)
@@ -572,7 +799,23 @@ void GraphModifier::addRow()
m_theSeries->dataProxy()->addRow(newRow);
} else {
- qDebug() << "Change row function active only for SqrtSin";
+#ifdef MULTI_SERIES
+ qDebug() << "Adding a row into series 3";
+ int full = m_limitX * m_limitZ;
+
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
+ for (int j = 0; j < m_xCount; j++) {
+ float angle = float((float(m_addRowCounter) - m_limitZ + 0.5f) * (float(j) - m_limitX + 0.5f)) / float(full) * 1.57f;
+ (*newRow)[j].setPosition(QVector3D(float(j) - m_limitX + 0.5f,
+ qSin(angle * 1.3f * 1.3f) + 2.2f,
+ float(m_addRowCounter) - m_limitZ + 0.5f));
+ }
+ m_addRowCounter++;
+
+ m_multiseries[2]->dataProxy()->addRow(newRow);
+#else
+ qDebug() << "Add row function active only for SqrtSin";
+#endif
}
}
@@ -605,7 +848,27 @@ void GraphModifier::addRows()
m_theSeries->dataProxy()->addRows(dataArray);
} else {
- qDebug() << "Change row function active only for SqrtSin";
+#ifdef MULTI_SERIES
+ qDebug() << "Adding 3 rows into series 3";
+ int full = m_limitX * m_limitZ;
+
+ QSurfaceDataArray dataArray;
+ for (int i = 0; i < 3; i++) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
+ for (int j = 0; j < m_xCount; j++) {
+ float angle = float((float(m_addRowCounter) - m_limitZ + 0.5f) * (float(j) - m_limitX + 0.5f)) / float(full) * 1.57f;
+ (*newRow)[j].setPosition(QVector3D(float(j) - m_limitX + 0.5f,
+ qSin(angle * 1.3f * 1.3f) + 2.2f,
+ float(m_addRowCounter) - m_limitZ + 0.5f));
+ }
+ dataArray.append(newRow);
+ m_addRowCounter++;
+ }
+
+ m_multiseries[2]->dataProxy()->addRows(dataArray);
+#else
+ qDebug() << "Add rows function active only for SqrtSin";
+#endif
}
}
@@ -633,7 +896,25 @@ void GraphModifier::insertRow()
m_theSeries->dataProxy()->insertRow(m_insertTestIndexPos, newRow);
m_insertTestIndexPos += 2;
} else {
- qDebug() << "Change row function active only for SqrtSin";
+#ifdef MULTI_SERIES
+ qDebug() << "Inserting a row into series 3";
+ int full = m_limitX * m_limitZ;
+
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
+ for (int j = 0; j < m_xCount; j++) {
+ float angle = float((float(m_insertTestZPos) - m_limitZ) * (float(j) - m_limitX)) / float(full) * 1.57f;
+ (*newRow)[j].setPosition(QVector3D(float(j) - m_limitX + 0.5f,
+ qSin(angle) + 2.4f,
+ float(m_insertTestZPos) - m_limitZ + 1.0f));
+ }
+
+ m_insertTestZPos++;
+
+ m_multiseries[2]->dataProxy()->insertRow(m_insertTestIndexPos, newRow);
+ m_insertTestIndexPos += 2;
+#else
+ qDebug() << "Insert row function active only for SqrtSin";
+#endif
}
}
@@ -665,15 +946,47 @@ void GraphModifier::insertRows()
m_theSeries->dataProxy()->insertRows(m_insertTestIndexPos, dataArray);
m_insertTestIndexPos += 4;
} else {
- qDebug() << "Change row function active only for SqrtSin";
+#ifdef MULTI_SERIES
+ qDebug() << "Inserting 3 rows into series 3";
+ int full = m_limitX * m_limitZ;
+ QSurfaceDataArray dataArray;
+ float zAdd = 0.25f;
+ for (int i = 0; i < 3; i++) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
+ for (int j = 0; j < m_xCount; j++) {
+ float angle = float((float(m_insertTestZPos) - m_limitZ) * (float(j) - m_limitX)) / float(full) * 1.57f;
+ (*newRow)[j].setPosition(QVector3D(float(j) - m_limitX + 0.5f,
+ qSin(angle) + 2.4f,
+ float(m_insertTestZPos) - m_limitZ + 0.5f + zAdd));
+ }
+ zAdd += 0.25f;
+ dataArray.append(newRow);
+ }
+
+ m_insertTestZPos++;
+
+ m_multiseries[2]->dataProxy()->insertRows(m_insertTestIndexPos, dataArray);
+ m_insertTestIndexPos += 4;
+#else
+ qDebug() << "Insert rows function active only for SqrtSin";
+#endif
}
}
void GraphModifier::removeRow()
{
qDebug() << "Remove an arbitrary row";
+ if (m_zCount < 1)
+ return;
+
int row = rand() % m_zCount;
+
+#ifdef MULTI_SERIES
+ int series = rand() % 4;
+ m_multiseries[series]->dataProxy()->removeRows(row, 1);
+#else
m_theSeries->dataProxy()->removeRows(row, 1);
+#endif
m_zCount--;
}
diff --git a/tests/surfacetest/graphmodifier.h b/tests/surfacetest/graphmodifier.h
index 8ccff62f..308db1f0 100644
--- a/tests/surfacetest/graphmodifier.h
+++ b/tests/surfacetest/graphmodifier.h
@@ -25,6 +25,9 @@
#include <QSlider>
#include <QTimer>
#include <QLabel>
+#include <QCheckBox>
+
+#define MULTI_SERIES
using namespace QtDataVisualization;
@@ -41,10 +44,27 @@ public:
explicit GraphModifier(Q3DSurface *graph);
~GraphModifier();
+ void toggleSeries1(bool enabled);
+ void toggleSeries2(bool enabled);
+ void toggleSeries3(bool enabled);
+ void toggleSeries4(bool enabled);
void toggleSmooth(bool enabled);
void toggleSurfaceGrid(bool enable);
void toggleSurface(bool enable);
void toggleSeriesVisible(bool enable);
+ void toggleSmoothS2(bool enabled);
+ void toggleSurfaceGridS2(bool enable);
+ void toggleSurfaceS2(bool enable);
+ void toggleSeries2Visible(bool enable);
+ void toggleSmoothS3(bool enabled);
+ void toggleSurfaceGridS3(bool enable);
+ void toggleSurfaceS3(bool enable);
+ void toggleSeries3Visible(bool enable);
+ void toggleSmoothS4(bool enabled);
+ void toggleSurfaceGridS4(bool enable);
+ void toggleSurfaceS4(bool enable);
+ void toggleSeries4Visible(bool enable);
+
void toggleSqrtSin(bool enable);
void togglePlane(bool enable);
void setHeightMapData(bool enable);
@@ -55,6 +75,10 @@ public:
void setAxisRangeSliderZ(QSlider *slider) { m_axisRangeSliderZ = slider; }
void setAxisMinSliderX(QSlider *slider) { m_axisMinSliderX = slider; }
void setAxisMinSliderZ(QSlider *slider) { m_axisMinSliderZ = slider; }
+ void setSeries1CB(QCheckBox *cb) { m_series1CB = cb; }
+ void setSeries2CB(QCheckBox *cb) { m_series2CB = cb; }
+ void setSeries3CB(QCheckBox *cb) { m_series3CB = cb; }
+ void setSeries4CB(QCheckBox *cb) { m_series4CB = cb; }
void adjustXCount(int count);
void adjustZCount(int count);
void adjustXRange(int range);
@@ -92,16 +116,26 @@ public slots:
void handleAxisZChanged(QValue3DAxis *axis);
private:
+ void fillSeries();
void resetArrayAndSliders(QSurfaceDataArray *array, float minZ, float maxZ, float minX,
float maxX);
Q3DSurface *m_graph;
+ QSurface3DSeries *m_multiseries[4];
+ QSurface3DSeries *m_series1;
+ QSurface3DSeries *m_series2;
+ QSurface3DSeries *m_series3;
+ QSurface3DSeries *m_series4;
QSlider *m_gridSliderX;
QSlider *m_gridSliderZ;
QSlider *m_axisRangeSliderX;
QSlider *m_axisRangeSliderZ;
QSlider *m_axisMinSliderX;
QSlider *m_axisMinSliderZ;
+ QCheckBox *m_series1CB;
+ QCheckBox *m_series2CB;
+ QCheckBox *m_series3CB;
+ QCheckBox *m_series4CB;
bool m_gridSlidersLocked;
int m_xCount;
int m_zCount;
@@ -119,6 +153,11 @@ private:
QLabel *m_selectionInfoLabel;
QSurface3DSeries *m_theSeries;
QSurface3DSeries::DrawFlags m_drawMode;
+ QSurface3DSeries::DrawFlags m_drawMode2;
+ QSurface3DSeries::DrawFlags m_drawMode3;
+ QSurface3DSeries::DrawFlags m_drawMode4;
+ float m_limitX;
+ float m_limitZ;
};
#endif
diff --git a/tests/surfacetest/main.cpp b/tests/surfacetest/main.cpp
index b31586b0..408486f5 100644
--- a/tests/surfacetest/main.cpp
+++ b/tests/surfacetest/main.cpp
@@ -31,6 +31,7 @@
#include <QScreen>
#include <QPainter>
#include <QFontComboBox>
+#include <QFrame>
#include <QDebug>
using namespace QtDataVisualization;
@@ -82,6 +83,72 @@ int main(int argc, char *argv[])
seriesVisibleCB->setText(QStringLiteral("Series Visible"));
seriesVisibleCB->setChecked(true);
+#ifdef MULTI_SERIES
+ smoothCB->setText(QStringLiteral("S1 Flat Surface"));
+ surfaceGridCB->setText(QStringLiteral("S1 Surface Grid"));
+ surfaceCB->setText(QStringLiteral("S1 Surface Visible"));
+ seriesVisibleCB->setText(QStringLiteral("Series 1 Visible"));
+
+ QCheckBox *smoothS2CB = new QCheckBox(widget);
+ smoothS2CB->setText(QStringLiteral("S2 Flat Surface"));
+ smoothS2CB->setChecked(true);
+
+ QCheckBox *surfaceGridS2CB = new QCheckBox(widget);
+ surfaceGridS2CB->setText(QStringLiteral("S2 Surface Grid"));
+ surfaceGridS2CB->setChecked(true);
+
+ QCheckBox *surfaceS2CB = new QCheckBox(widget);
+ surfaceS2CB->setText(QStringLiteral("S2 Surface Visible"));
+ surfaceS2CB->setChecked(true);
+
+ QCheckBox *series2VisibleCB = new QCheckBox(widget);
+ series2VisibleCB->setText(QStringLiteral("Series 2 Visible"));
+ series2VisibleCB->setChecked(true);
+
+ QCheckBox *smoothS3CB = new QCheckBox(widget);
+ smoothS3CB->setText(QStringLiteral("S3 Flat Surface"));
+ smoothS3CB->setChecked(true);
+
+ QCheckBox *surfaceGridS3CB = new QCheckBox(widget);
+ surfaceGridS3CB->setText(QStringLiteral("S3 Surface Grid"));
+ surfaceGridS3CB->setChecked(true);
+
+ QCheckBox *surfaceS3CB = new QCheckBox(widget);
+ surfaceS3CB->setText(QStringLiteral("S3 Surface Visible"));
+ surfaceS3CB->setChecked(true);
+
+ QCheckBox *series3VisibleCB = new QCheckBox(widget);
+ series3VisibleCB->setText(QStringLiteral("Series 3 Visible"));
+ series3VisibleCB->setChecked(true);
+
+ QCheckBox *smoothS4CB = new QCheckBox(widget);
+ smoothS4CB->setText(QStringLiteral("S4 Flat Surface"));
+ smoothS4CB->setChecked(true);
+
+ QCheckBox *surfaceGridS4CB = new QCheckBox(widget);
+ surfaceGridS4CB->setText(QStringLiteral("S4 Surface Grid"));
+ surfaceGridS4CB->setChecked(true);
+
+ QCheckBox *surfaceS4CB = new QCheckBox(widget);
+ surfaceS4CB->setText(QStringLiteral("S4 Surface Visible"));
+ surfaceS4CB->setChecked(true);
+
+ QCheckBox *series4VisibleCB = new QCheckBox(widget);
+ series4VisibleCB->setText(QStringLiteral("Series 4 Visible"));
+ series4VisibleCB->setChecked(true);
+
+ QCheckBox *series1CB = new QCheckBox(widget);
+ series1CB->setText(QStringLiteral("Series 1"));
+
+ QCheckBox *series2CB = new QCheckBox(widget);
+ series2CB->setText(QStringLiteral("Series 2"));
+
+ QCheckBox *series3CB = new QCheckBox(widget);
+ series3CB->setText(QStringLiteral("Series 3"));
+
+ QCheckBox *series4CB = new QCheckBox(widget);
+ series4CB->setText(QStringLiteral("Series 4"));
+#else
//QCheckBox *sqrtSinCB = new QCheckBox(widget);
QRadioButton *sqrtSinCB = new QRadioButton(widget);
sqrtSinCB->setText(QStringLiteral("Sqrt & Sin"));
@@ -111,6 +178,7 @@ int main(int argc, char *argv[])
gridSliderZ->setValue(30);
gridSliderZ->setMaximum(200);
gridSliderZ->setEnabled(true);
+#endif
QSlider *axisRangeSliderX = new QSlider(Qt::Horizontal, widget);
axisRangeSliderX->setTickInterval(1);
@@ -209,6 +277,7 @@ int main(int argc, char *argv[])
int(QAbstract3DGraph::SelectionSlice | QAbstract3DGraph::SelectionItemAndColumn));
selectionMode->setCurrentIndex(1);
+#ifndef MULTI_SERIES
QPushButton *selectButton = new QPushButton(widget);
selectButton->setText(QStringLiteral("Select random point"));
@@ -216,6 +285,7 @@ int main(int argc, char *argv[])
flipViewsButton->setText(QStringLiteral("Flip Views"));
QLabel *selectionInfoLabel = new QLabel(widget);
+#endif
QPushButton *changeRowButton = new QPushButton(widget);
changeRowButton->setText(QStringLiteral("Change a row"));
@@ -247,11 +317,47 @@ int main(int argc, char *argv[])
QPushButton *removeRowButton = new QPushButton(widget);
removeRowButton->setText(QStringLiteral("Remove a row"));
+ QFrame* line = new QFrame();
+ line->setFrameShape(QFrame::HLine);
+ line->setFrameShadow(QFrame::Sunken);
+
+ QFrame* line2 = new QFrame();
+ line2->setFrameShape(QFrame::HLine);
+ line2->setFrameShadow(QFrame::Sunken);
+
+ QFrame* line3 = new QFrame();
+ line3->setFrameShape(QFrame::HLine);
+ line3->setFrameShadow(QFrame::Sunken);
+
// Add controls to the layout
+#ifdef MULTI_SERIES
+ vLayout->addWidget(series1CB);
+#endif
vLayout->addWidget(smoothCB);
vLayout->addWidget(surfaceGridCB);
vLayout->addWidget(surfaceCB);
vLayout->addWidget(seriesVisibleCB);
+#ifdef MULTI_SERIES
+ vLayout->addWidget(line);
+ vLayout->addWidget(series2CB);
+ vLayout->addWidget(smoothS2CB);
+ vLayout->addWidget(surfaceGridS2CB);
+ vLayout->addWidget(surfaceS2CB);
+ vLayout->addWidget(series2VisibleCB);
+ vLayout->addWidget(line2);
+ vLayout->addWidget(series3CB);
+ vLayout->addWidget(smoothS3CB);
+ vLayout->addWidget(surfaceGridS3CB);
+ vLayout->addWidget(surfaceS3CB);
+ vLayout->addWidget(series3VisibleCB);
+ vLayout->addWidget(line3);
+ vLayout->addWidget(series4CB);
+ vLayout->addWidget(smoothS4CB);
+ vLayout->addWidget(surfaceGridS4CB);
+ vLayout->addWidget(surfaceS4CB);
+ vLayout->addWidget(series4VisibleCB);
+#endif
+#ifndef MULTI_SERIES
vLayout->addWidget(new QLabel(QStringLiteral("Select surface sample")));
vLayout->addWidget(sqrtSinCB);
vLayout->addWidget(planeCB);
@@ -260,6 +366,7 @@ int main(int argc, char *argv[])
vLayout->addWidget(gridSlidersLockCB);
vLayout->addWidget(gridSliderX);
vLayout->addWidget(gridSliderZ);
+#endif
vLayout->addWidget(new QLabel(QStringLiteral("Adjust axis range")));
vLayout->addWidget(axisRangeSliderX);
vLayout->addWidget(axisRangeSliderZ);
@@ -277,9 +384,11 @@ int main(int argc, char *argv[])
vLayout->addWidget(shadowQuality);
vLayout->addWidget(new QLabel(QStringLiteral("Selection Mode")));
vLayout->addWidget(selectionMode);
+#ifndef MULTI_SERIES
vLayout->addWidget(selectButton);
vLayout->addWidget(selectionInfoLabel);
vLayout->addWidget(flipViewsButton);
+#endif
vLayout2->addWidget(changeRowButton);
vLayout2->addWidget(changeRowsButton);
@@ -305,6 +414,78 @@ int main(int argc, char *argv[])
modifier, &GraphModifier::toggleSurface);
QObject::connect(seriesVisibleCB, &QCheckBox::stateChanged,
modifier, &GraphModifier::toggleSeriesVisible);
+#ifdef MULTI_SERIES
+ QObject::connect(smoothS2CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSmoothS2);
+ QObject::connect(surfaceGridS2CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSurfaceGridS2);
+ QObject::connect(surfaceS2CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSurfaceS2);
+ QObject::connect(series2VisibleCB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSeries2Visible);
+
+ QObject::connect(smoothS3CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSmoothS3);
+ QObject::connect(surfaceGridS3CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSurfaceGridS3);
+ QObject::connect(surfaceS3CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSurfaceS3);
+ QObject::connect(series3VisibleCB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSeries3Visible);
+
+ QObject::connect(smoothS4CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSmoothS4);
+ QObject::connect(surfaceGridS4CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSurfaceGridS4);
+ QObject::connect(surfaceS4CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSurfaceS4);
+ QObject::connect(series4VisibleCB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSeries4Visible);
+
+ QObject::connect(series1CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSeries1);
+ QObject::connect(series1CB, &QCheckBox::stateChanged,
+ smoothCB, &QPushButton::setEnabled);
+ QObject::connect(series1CB, &QCheckBox::stateChanged,
+ surfaceGridCB, &QPushButton::setEnabled);
+ QObject::connect(series1CB, &QCheckBox::stateChanged,
+ surfaceCB, &QPushButton::setEnabled);
+ QObject::connect(series1CB, &QCheckBox::stateChanged,
+ seriesVisibleCB, &QPushButton::setEnabled);
+
+ QObject::connect(series2CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSeries2);
+ QObject::connect(series2CB, &QCheckBox::stateChanged,
+ smoothS2CB, &QPushButton::setEnabled);
+ QObject::connect(series2CB, &QCheckBox::stateChanged,
+ surfaceGridS2CB, &QPushButton::setEnabled);
+ QObject::connect(series2CB, &QCheckBox::stateChanged,
+ surfaceS2CB, &QPushButton::setEnabled);
+ QObject::connect(series2CB, &QCheckBox::stateChanged,
+ series2VisibleCB, &QPushButton::setEnabled);
+
+ QObject::connect(series3CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSeries3);
+ QObject::connect(series3CB, &QCheckBox::stateChanged,
+ smoothS3CB, &QPushButton::setEnabled);
+ QObject::connect(series3CB, &QCheckBox::stateChanged,
+ surfaceGridS3CB, &QPushButton::setEnabled);
+ QObject::connect(series3CB, &QCheckBox::stateChanged,
+ surfaceS3CB, &QPushButton::setEnabled);
+ QObject::connect(series3CB, &QCheckBox::stateChanged,
+ series3VisibleCB, &QPushButton::setEnabled);
+
+ QObject::connect(series4CB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSeries4);
+ QObject::connect(series4CB, &QCheckBox::stateChanged,
+ smoothS4CB, &QPushButton::setEnabled);
+ QObject::connect(series4CB, &QCheckBox::stateChanged,
+ surfaceGridS4CB, &QPushButton::setEnabled);
+ QObject::connect(series4CB, &QCheckBox::stateChanged,
+ surfaceS4CB, &QPushButton::setEnabled);
+ QObject::connect(series4CB, &QCheckBox::stateChanged,
+ series4VisibleCB, &QPushButton::setEnabled);
+#else
QObject::connect(sqrtSinCB, &QRadioButton::toggled,
modifier, &GraphModifier::toggleSqrtSin);
QObject::connect(planeCB, &QCheckBox::toggled,
@@ -317,6 +498,7 @@ int main(int argc, char *argv[])
modifier, &GraphModifier::adjustXCount);
QObject::connect(gridSliderZ, &QSlider::valueChanged,
modifier, &GraphModifier::adjustZCount);
+#endif
QObject::connect(axisRangeSliderX, &QSlider::valueChanged,
modifier, &GraphModifier::adjustXRange);
QObject::connect(axisRangeSliderZ, &QSlider::valueChanged,
@@ -339,10 +521,12 @@ int main(int argc, char *argv[])
modifier, SLOT(changeShadowQuality(int)));
QObject::connect(selectionMode, SIGNAL(currentIndexChanged(int)),
modifier, SLOT(changeSelectionMode(int)));
+#ifndef MULTI_SERIES
QObject::connect(selectButton, &QPushButton::clicked,
modifier, &GraphModifier::selectButtonClicked);
QObject::connect(flipViewsButton, &QPushButton::clicked,
modifier, &GraphModifier::flipViews);
+#endif
QObject::connect(changeRowButton,&QPushButton::clicked,
modifier, &GraphModifier::changeRow);
QObject::connect(changeRowsButton,&QPushButton::clicked,
@@ -364,15 +548,27 @@ int main(int argc, char *argv[])
QObject::connect(removeRowButton,&QPushButton::clicked,
modifier, &GraphModifier::removeRow);
- modifier->setGridSliderZ(gridSliderZ);
- modifier->setGridSliderX(gridSliderX);
+#ifdef MULTI_SERIES
+ modifier->setSeries1CB(series1CB);
+ modifier->setSeries2CB(series2CB);
+ modifier->setSeries3CB(series3CB);
+ modifier->setSeries4CB(series4CB);
+ series1CB->setChecked(true);
+ series2CB->setChecked(true);
+ series3CB->setChecked(true);
+ series4CB->setChecked(false);
+#endif
modifier->setAxisRangeSliderX(axisRangeSliderX);
modifier->setAxisRangeSliderZ(axisRangeSliderZ);
modifier->setAxisMinSliderX(axisMinSliderX);
modifier->setAxisMinSliderZ(axisMinSliderZ);
+#ifndef MULTI_SERIES
+ modifier->setGridSliderZ(gridSliderZ);
+ modifier->setGridSliderX(gridSliderX);
modifier->toggleGridSliderLock(gridSlidersLockCB->checkState());
modifier->setSelectionInfoLabel(selectionInfoLabel);
sqrtSinCB->setChecked(true);
+#endif
shadowQuality->setCurrentIndex(3);
return app.exec();