summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
authorMika Salmela <mika.salmela@digia.com>2014-08-19 09:33:53 +0300
committerMika Salmela <mika.salmela@digia.com>2014-08-19 09:47:37 +0300
commit68b3ea782608cbcd457cbe1abc0c83aceb356777 (patch)
tree70f58d966316e0a8462326a839588693d1459dbb /src/datavisualization
parent1574c9353885ec48dbf9d5d7618e496d00c3862c (diff)
Gradient color style support for complex meshes on static
Change-Id: Ie9f135a2f3139a429a451c338e03dcf0ea6b4533 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/data/qabstract3dseries.h1
-rw-r--r--src/datavisualization/engine/qabstract3dgraph.cpp2
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp49
-rw-r--r--src/datavisualization/engine/scatter3drenderer_p.h1
-rw-r--r--src/datavisualization/engine/seriesrendercache.cpp3
-rw-r--r--src/datavisualization/engine/seriesrendercache_p.h3
-rw-r--r--src/datavisualization/utils/scatterobjectbufferhelper.cpp119
-rw-r--r--src/datavisualization/utils/scatterobjectbufferhelper_p.h11
8 files changed, 174 insertions, 15 deletions
diff --git a/src/datavisualization/data/qabstract3dseries.h b/src/datavisualization/data/qabstract3dseries.h
index 87c4f3c1..c26c40d1 100644
--- a/src/datavisualization/data/qabstract3dseries.h
+++ b/src/datavisualization/data/qabstract3dseries.h
@@ -153,6 +153,7 @@ private:
friend class Bars3DController;
friend class Surface3DController;
friend class Surface3DRenderer;
+ friend class Scatter3DRenderer;
friend class Scatter3DController;
friend class QBar3DSeries;
friend class SeriesRenderCache;
diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp
index 23290d69..3f199dab 100644
--- a/src/datavisualization/engine/qabstract3dgraph.cpp
+++ b/src/datavisualization/engine/qabstract3dgraph.cpp
@@ -637,7 +637,7 @@ qreal QAbstract3DGraph::aspectRatio() const
*
* Defines if the rendering optimization is default or static. Default mode provides the full feature set at
* reasonable performance. Static is a beta level feature and currently supports only a subset of the
- * features on the Scatter graph. Missing features are object gradient for mesh objects, both gradients
+ * features on the Scatter graph. Missing features are both gradient color styles
* for points, and diffuse and specular color on rotations. At this point static is intended just for
* introducing a new feature. It optimizes graph rendering and is ideal for large non-changing data
* sets. It is slower with dynamic data changes and item rotations. Selection is not optimized, so using it
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index 13f6e02c..bc3893b9 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -190,6 +190,7 @@ void Scatter3DRenderer::updateData()
}
if (renderArraySize != cache->oldArraySize()
|| cache->object()->objectFile() != cache->oldMeshFileName()) {
+ object->setScaleY(m_scaleY);
object->fullLoad(cache, m_dotSizeScale);
cache->setOldArraySize(renderArraySize);
cache->setOldMeshFileName(cache->object()->objectFile());
@@ -207,9 +208,26 @@ void Scatter3DRenderer::updateData()
void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList)
{
+ int seriesCount = seriesList.size();
+
+ // Check OptimizationStatic specific issues before populate marks changeTracker done
+ if (m_cachedOptimizationHint.testFlag(QAbstract3DGraph::OptimizationStatic)) {
+ for (int i = 0; i < seriesCount; i++) {
+ QScatter3DSeries *scatterSeries = static_cast<QScatter3DSeries *>(seriesList[i]);
+ if (scatterSeries->isVisible()) {
+ QAbstract3DSeriesChangeBitField &changeTracker = scatterSeries->d_ptr->m_changeTracker;
+ if (changeTracker.baseGradientChanged || changeTracker.colorStyleChanged) {
+ ScatterSeriesRenderCache *cache =
+ static_cast<ScatterSeriesRenderCache *>(m_renderCacheList.value(scatterSeries));
+ if (cache && cache->mesh() != QAbstract3DSeries::MeshPoint)
+ cache->setStaticObjectUVDirty(true);
+ }
+ }
+ }
+ }
+
Abstract3DRenderer::updateSeries(seriesList);
- int seriesCount = seriesList.size();
float maxItemSize = 0.0f;
float itemSize = 0.0f;
bool noSelection = true;
@@ -245,6 +263,12 @@ void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
else
m_haveGradientMeshSeries = true;
}
+
+ if (cache->staticObjectUVDirty()) {
+ ScatterObjectBufferHelper *object = cache->bufferObject();
+ object->updateUVs(cache);
+ cache->setStaticObjectUVDirty(false);
+ }
}
}
m_maxItemSize = maxItemSize;
@@ -313,6 +337,28 @@ void Scatter3DRenderer::updateAxisTitleVisibility(QAbstract3DAxis::AxisOrientati
calculateSceneScalingFactors();
}
+void Scatter3DRenderer::updateOptimizationHint(QAbstract3DGraph::OptimizationHints hint)
+{
+ Abstract3DRenderer::updateOptimizationHint(hint);
+
+ if (m_cachedOptimizationHint.testFlag(QAbstract3DGraph::OptimizationStatic)) {
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ initGradientShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadow"));
+ } else {
+ initGradientShaders(QStringLiteral(":/shaders/vertexTexture"),
+ QStringLiteral(":/shaders/fragmentTexture"));
+ }
+#else
+ initGradientShaders(QStringLiteral(":/shaders/vertexTexture"),
+ QStringLiteral(":/shaders/fragmentTexture"));
+#endif
+ } else {
+ Abstract3DRenderer::reInitShaders();
+ }
+}
+
void Scatter3DRenderer::resetClickedStatus()
{
m_clickedIndex = Scatter3DController::invalidSelectionIndex();
@@ -2088,6 +2134,7 @@ void Scatter3DRenderer::initGradientShaders(const QString &vertexShader,
{
if (m_dotGradientShader)
delete m_dotGradientShader;
+
m_dotGradientShader = new ShaderHelper(this, vertexShader, fragmentShader);
m_dotGradientShader->initialize();
}
diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h
index 5f82bf70..353dc098 100644
--- a/src/datavisualization/engine/scatter3drenderer_p.h
+++ b/src/datavisualization/engine/scatter3drenderer_p.h
@@ -98,6 +98,7 @@ public:
const QStringList &labels);
void updateAxisTitleVisibility(QAbstract3DAxis::AxisOrientation orientation,
bool visible);
+ void updateOptimizationHint(QAbstract3DGraph::OptimizationHints hint);
QVector3D convertPositionToTranslation(const QVector3D &position, bool isAbsolute);
diff --git a/src/datavisualization/engine/seriesrendercache.cpp b/src/datavisualization/engine/seriesrendercache.cpp
index dc4b9db3..5fcc97f0 100644
--- a/src/datavisualization/engine/seriesrendercache.cpp
+++ b/src/datavisualization/engine/seriesrendercache.cpp
@@ -37,7 +37,8 @@ SeriesRenderCache::SeriesRenderCache(QAbstract3DSeries *series, Abstract3DRender
m_valid(false),
m_visible(false),
m_renderer(renderer),
- m_objectDirty(true)
+ m_objectDirty(true),
+ m_staticObjectUVDirty(false)
{
}
diff --git a/src/datavisualization/engine/seriesrendercache_p.h b/src/datavisualization/engine/seriesrendercache_p.h
index 96b61b87..5047d671 100644
--- a/src/datavisualization/engine/seriesrendercache_p.h
+++ b/src/datavisualization/engine/seriesrendercache_p.h
@@ -71,6 +71,8 @@ public:
inline bool isVisible() const { return m_visible; }
inline void setDataDirty(bool state) { m_objectDirty = state; }
inline bool dataDirty() const { return m_objectDirty; }
+ inline void setStaticObjectUVDirty(bool state) { m_staticObjectUVDirty = state; }
+ inline bool staticObjectUVDirty() { return m_staticObjectUVDirty; }
protected:
QAbstract3DSeries *m_series;
@@ -94,6 +96,7 @@ protected:
bool m_visible;
Abstract3DRenderer *m_renderer;
bool m_objectDirty;
+ bool m_staticObjectUVDirty;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/scatterobjectbufferhelper.cpp b/src/datavisualization/utils/scatterobjectbufferhelper.cpp
index d68b9df4..0ac1dd87 100644
--- a/src/datavisualization/utils/scatterobjectbufferhelper.cpp
+++ b/src/datavisualization/utils/scatterobjectbufferhelper.cpp
@@ -26,6 +26,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
const GLfloat itemScaler = 3.0f;
ScatterObjectBufferHelper::ScatterObjectBufferHelper()
+ : m_scaleY(0.0f)
{
m_indicesType = GL_UNSIGNED_INT;
}
@@ -42,12 +43,15 @@ void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal
m_indexCount = 0;
ObjectHelper *dotObj = cache->object();
- ScatterRenderItemArray &renderArray = cache->renderArray();
+ const ScatterRenderItemArray &renderArray = cache->renderArray();
const uint renderArraySize = renderArray.size();
+
if (renderArraySize == 0)
return; // No use to go forward
+
uint itemCount = renderArraySize;
QQuaternion seriesRotation(cache->meshRotation());
+
if (m_meshDataLoaded) {
// Delete old data
glDeleteBuffers(1, &m_vertexbuffer);
@@ -55,15 +59,16 @@ void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal
glDeleteBuffers(1, &m_normalbuffer);
glDeleteBuffers(1, &m_elementbuffer);
}
+
// Index vertices
const QVector<unsigned short> indices = dotObj->indices();
const QVector<QVector3D> indexed_vertices = dotObj->indexedvertices();
const QVector<QVector2D> indexed_uvs = dotObj->indexedUVs();
const QVector<QVector3D> indexed_normals = dotObj->indexedNormals();
- int indicesCount = indices.count();
- int verticeCount = indexed_vertices.count();
- int uvsCount = indexed_uvs.count();
- int normalsCount = indexed_normals.count();
+ const int indicesCount = indices.count();
+ const int verticeCount = indexed_vertices.count();
+ const int uvsCount = indexed_uvs.count();
+ const int normalsCount = indexed_normals.count();
float itemSize = cache->itemSize() / itemScaler;
if (itemSize == 0.0f)
@@ -89,12 +94,19 @@ void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal
buffered_indices.resize(indicesCount * renderArraySize);
buffered_vertices.resize(verticeCount * renderArraySize);
- buffered_uvs.resize(uvsCount * renderArraySize);
buffered_normals.resize(normalsCount * renderArraySize);
+ buffered_uvs.resize(uvsCount * renderArraySize);
uint pos = 0;
+ if (cache->colorStyle() == Q3DTheme::ColorStyleRangeGradient)
+ createRangeGradientUVs(cache, buffered_uvs);
+ else if (cache->colorStyle() == Q3DTheme::ColorStyleObjectGradient)
+ createObjectGradientUVs(cache, buffered_uvs, indexed_vertices);
+
+ QVector2D dummyUV(0.0f, 0.0f);
+
for (uint i = 0; i < renderArraySize; i++) {
- ScatterRenderItem &item = renderArray[i];
+ const ScatterRenderItem &item = renderArray.at(i);
if (!item.isVisible()) {
itemCount--;
continue;
@@ -119,9 +131,11 @@ void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal
for (int j = 0; j < normalsCount; j++)
buffered_normals[j + offset] = indexed_normals[j];
- offset = pos * uvsCount;
- for (int j = 0; j < uvsCount; j++)
- buffered_uvs[j + offset] = indexed_uvs[j];
+ if (cache->colorStyle() == Q3DTheme::ColorStyleUniform) {
+ offset = pos * uvsCount;
+ for (int j = 0; j < uvsCount; j++)
+ buffered_uvs[j + offset] = dummyUV;
+ }
int offsetVertice = i * verticeCount;
offset = pos * indicesCount;
@@ -164,12 +178,93 @@ void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal
}
}
+void ScatterObjectBufferHelper::updateUVs(ScatterSeriesRenderCache *cache)
+{
+ ObjectHelper *dotObj = cache->object();
+ const int uvsCount = dotObj->indexedUVs().count();
+ const ScatterRenderItemArray &renderArray = cache->renderArray();
+ const uint renderArraySize = renderArray.size();
+ QVector<QVector2D> buffered_uvs;
+ buffered_uvs.resize(uvsCount * renderArraySize);
+
+ uint itemCount;
+ if (cache->colorStyle() == Q3DTheme::ColorStyleRangeGradient) {
+ itemCount = createRangeGradientUVs(cache, buffered_uvs);
+ } else if (cache->colorStyle() == Q3DTheme::ColorStyleObjectGradient) {
+ const QVector<QVector3D> indexed_vertices = dotObj->indexedvertices();
+ itemCount = createObjectGradientUVs(cache, buffered_uvs, indexed_vertices);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer);
+ glBufferData(GL_ARRAY_BUFFER, uvsCount * itemCount * sizeof(QVector2D),
+ &buffered_uvs.at(0), GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+uint ScatterObjectBufferHelper::createRangeGradientUVs(ScatterSeriesRenderCache *cache,
+ QVector<QVector2D> &buffered_uvs)
+{
+ ObjectHelper *dotObj = cache->object();
+ const int uvsCount = dotObj->indexedUVs().count();
+ const ScatterRenderItemArray &renderArray = cache->renderArray();
+ const uint renderArraySize = renderArray.size();
+
+ QVector2D uv;
+ uv.setX(0.0f);
+ uint pos = 0;
+ for (uint i = 0; i < renderArraySize; i++) {
+ const ScatterRenderItem &item = renderArray.at(i);
+ if (!item.isVisible())
+ continue;
+
+ float y = ((item.translation().y() + m_scaleY) * 0.5f ) / m_scaleY;
+ uv.setY(y);
+ int offset = pos * uvsCount;
+ for (int j = 0; j < uvsCount; j++)
+ buffered_uvs[j + offset] = uv;
+
+ pos++;
+ }
+
+ return pos;
+}
+
+uint ScatterObjectBufferHelper::createObjectGradientUVs(ScatterSeriesRenderCache *cache,
+ QVector<QVector2D> &buffered_uvs,
+ const QVector<QVector3D> &indexed_vertices)
+{
+ ObjectHelper *dotObj = cache->object();
+ const int uvsCount = dotObj->indexedUVs().count();
+ const ScatterRenderItemArray &renderArray = cache->renderArray();
+ const uint renderArraySize = renderArray.size();
+
+ QVector2D uv;
+ uv.setX(0.0f);
+ uint pos = 0;
+ for (uint i = 0; i < renderArraySize; i++) {
+ const ScatterRenderItem &item = renderArray.at(i);
+ if (!item.isVisible())
+ continue;
+
+ int offset = pos * uvsCount;
+ for (int j = 0; j < uvsCount; j++) {
+ uv.setY((indexed_vertices.at(j).y() + 1.0f) / 2.0f);
+ buffered_uvs[j + offset] = uv;
+ }
+
+ pos++;
+ }
+
+ return pos;
+}
+
void ScatterObjectBufferHelper::update(ScatterSeriesRenderCache *cache, qreal dotScale)
{
initializeOpenGLFunctions();
ObjectHelper *dotObj = cache->object();
- ScatterRenderItemArray &renderArray = cache->renderArray();
+ const ScatterRenderItemArray &renderArray = cache->renderArray();
const int renderArraySize = renderArray.size();
QQuaternion seriesRotation(cache->meshRotation());
@@ -198,7 +293,7 @@ void ScatterObjectBufferHelper::update(ScatterSeriesRenderCache *cache, qreal do
buffered_vertices.resize(verticeCount * renderArraySize);
for (int i = 0; i < renderArraySize; i++) {
- ScatterRenderItem &item = renderArray[i];
+ const ScatterRenderItem &item = renderArray.at(i);
if (!item.isVisible())
continue;
diff --git a/src/datavisualization/utils/scatterobjectbufferhelper_p.h b/src/datavisualization/utils/scatterobjectbufferhelper_p.h
index 952c3d7d..c45febd1 100644
--- a/src/datavisualization/utils/scatterobjectbufferhelper_p.h
+++ b/src/datavisualization/utils/scatterobjectbufferhelper_p.h
@@ -43,6 +43,17 @@ public:
void fullLoad(ScatterSeriesRenderCache *cache, qreal dotScale);
void update(ScatterSeriesRenderCache *cache, qreal dotScale);
+ void updateUVs(ScatterSeriesRenderCache *cache);
+ void setScaleY(float scale) { m_scaleY = scale; }
+
+private:
+ uint createRangeGradientUVs(ScatterSeriesRenderCache *cache,
+ QVector<QVector2D> &buffered_uvs);
+ uint createObjectGradientUVs(ScatterSeriesRenderCache *cache,
+ QVector<QVector2D> &buffered_uvs,
+ const QVector<QVector3D> &indexed_vertices);
+
+ float m_scaleY;
};
QT_END_NAMESPACE_DATAVISUALIZATION