diff options
author | Mika Salmela <mika.salmela@digia.com> | 2014-08-19 09:33:53 +0300 |
---|---|---|
committer | Mika Salmela <mika.salmela@digia.com> | 2014-08-19 09:47:37 +0300 |
commit | 68b3ea782608cbcd457cbe1abc0c83aceb356777 (patch) | |
tree | 70f58d966316e0a8462326a839588693d1459dbb /src/datavisualization | |
parent | 1574c9353885ec48dbf9d5d7618e496d00c3862c (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')
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 |