From 9a40207d83b66072fff4aaa03eca15b02f8a11c1 Mon Sep 17 00:00:00 2001 From: Mika Salmela Date: Thu, 28 Aug 2014 10:29:39 +0300 Subject: Range gradient for points on static optimization Change-Id: Ic44a6a28617f272540d146f02bf50b4bd84cd9c8 Reviewed-by: Miikka Heikkinen --- ...tdatavisualization-qml-abstractdeclarative.qdoc | 11 ++--- src/datavisualization/engine/drawer.cpp | 22 +++++++++- src/datavisualization/engine/drawer_p.h | 2 +- src/datavisualization/engine/qabstract3dgraph.cpp | 3 +- src/datavisualization/engine/scatter3drenderer.cpp | 24 ++++++++--- .../utils/scatterobjectbufferhelper.cpp | 2 +- .../utils/scatterpointbufferhelper.cpp | 50 ++++++++++++++++++++++ .../utils/scatterpointbufferhelper_p.h | 7 +++ 8 files changed, 103 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc index dfa65877..5dc7b35c 100644 --- a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc @@ -343,13 +343,10 @@ * \since QtDataVisualization 1.1 * * 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 - * 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 - * with massive data sets is not advisable. - * Defaults to \c{OptimizationDefault} + * reasonable performance. Static 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 with + * massive data sets is not advisable. Static works only on the Scatter graph. + * Defaults to \c{OptimizationDefault}. */ /*! diff --git a/src/datavisualization/engine/drawer.cpp b/src/datavisualization/engine/drawer.cpp index 4191efc4..2cb88e5c 100644 --- a/src/datavisualization/engine/drawer.cpp +++ b/src/datavisualization/engine/drawer.cpp @@ -223,13 +223,27 @@ void Drawer::drawPoint(ShaderHelper *shader) glDisableVertexAttribArray(shader->posAtt()); } -void Drawer::drawPoints(ShaderHelper *shader, ScatterPointBufferHelper *object) +void Drawer::drawPoints(ShaderHelper *shader, ScatterPointBufferHelper *object, GLuint textureId) { + if (textureId) { + // Activate texture + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textureId); + shader->setUniformValue(shader->texture(), 0); + } + // 1st attribute buffer : vertices glEnableVertexAttribArray(shader->posAtt()); glBindBuffer(GL_ARRAY_BUFFER, object->pointBuf()); glVertexAttribPointer(shader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void*)0); + // 2nd attribute buffer : UVs + if (textureId) { + glEnableVertexAttribArray(shader->uvAtt()); + glBindBuffer(GL_ARRAY_BUFFER, object->uvBuf()); + glVertexAttribPointer(shader->uvAtt(), 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + } + // Draw the points glDrawArrays(GL_POINTS, 0, object->indexCount()); @@ -237,6 +251,12 @@ void Drawer::drawPoints(ShaderHelper *shader, ScatterPointBufferHelper *object) glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableVertexAttribArray(shader->posAtt()); + + if (textureId) { + glDisableVertexAttribArray(shader->uvAtt()); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + } } void Drawer::drawLine(ShaderHelper *shader) diff --git a/src/datavisualization/engine/drawer_p.h b/src/datavisualization/engine/drawer_p.h index 709503dd..0c96724c 100644 --- a/src/datavisualization/engine/drawer_p.h +++ b/src/datavisualization/engine/drawer_p.h @@ -79,7 +79,7 @@ public: void drawSelectionObject(ShaderHelper *shader, AbstractObjectHelper *object); void drawSurfaceGrid(ShaderHelper *shader, SurfaceObject *object); void drawPoint(ShaderHelper *shader); - void drawPoints(ShaderHelper *shader, ScatterPointBufferHelper *object); + void drawPoints(ShaderHelper *shader, ScatterPointBufferHelper *object, GLuint textureId); void drawLine(ShaderHelper *shader); void drawLabel(const AbstractRenderItem &item, const LabelItem &labelItem, const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix, diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp index c797f554..03eeedf6 100644 --- a/src/datavisualization/engine/qabstract3dgraph.cpp +++ b/src/datavisualization/engine/qabstract3dgraph.cpp @@ -638,8 +638,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 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 with - * massive data sets is not advisable. Static works only on the Scatter graph and lacks the range gradient - * color style for points. + * massive data sets is not advisable. Static works only on the Scatter graph. * Defaults to \c{OptimizationDefault}. */ void QAbstract3DGraph::setOptimizationHints(OptimizationHints hints) diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 4b6a258e..0a670fe8 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -181,6 +181,7 @@ void Scatter3DRenderer::updateData() points = new ScatterPointBufferHelper(); cache->setBufferPoints(points); } + points->setScaleY(m_scaleY); points->load(cache); } else { ScatterObjectBufferHelper *object = cache->bufferObject(); @@ -219,7 +220,7 @@ void Scatter3DRenderer::updateSeries(const QList &seriesLis if (changeTracker.baseGradientChanged || changeTracker.colorStyleChanged) { ScatterSeriesRenderCache *cache = static_cast(m_renderCacheList.value(scatterSeries)); - if (cache && cache->mesh() != QAbstract3DSeries::MeshPoint) + if (cache) cache->setStaticObjectUVDirty(true); } } @@ -265,8 +266,13 @@ void Scatter3DRenderer::updateSeries(const QList &seriesLis } if (cache->staticObjectUVDirty()) { - ScatterObjectBufferHelper *object = cache->bufferObject(); - object->updateUVs(cache); + if (cache->mesh() == QAbstract3DSeries::MeshPoint) { + ScatterPointBufferHelper *object = cache->bufferPoints(); + object->updateUVs(cache); + } else { + ScatterObjectBufferHelper *object = cache->bufferObject(); + object->updateUVs(cache); + } cache->setStaticObjectUVDirty(false); } } @@ -522,7 +528,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) if (optimizationDefault) m_drawer->drawPoint(m_depthShader); else - m_drawer->drawPoints(m_depthShader, cache->bufferPoints()); + m_drawer->drawPoints(m_depthShader, cache->bufferPoints(), 0); } else { if (optimizationDefault) { // 1st attribute buffer : vertices @@ -853,6 +859,12 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) gradientTexture = cache->baseGradientTexture(); } + if (!optimizationDefault && rangeGradientPoints) { + dotShader = m_labelShader; + dotShader->bind(); + gradientTexture = cache->baseGradientTexture(); + } + GLfloat lightStrength = m_cachedTheme->lightStrength(); if (optimizationDefault && selectedSeries && (m_selectedItemIndex == i)) { if (useColor) @@ -905,7 +917,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) if (optimizationDefault) m_drawer->drawPoint(dotShader); else - m_drawer->drawPoints(dotShader, cache->bufferPoints()); + m_drawer->drawPoints(dotShader, cache->bufferPoints(), gradientTexture); } } else #endif @@ -923,7 +935,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) if (optimizationDefault) m_drawer->drawPoint(dotShader); else - m_drawer->drawPoints(dotShader, cache->bufferPoints()); + m_drawer->drawPoints(dotShader, cache->bufferPoints(), gradientTexture); } } } diff --git a/src/datavisualization/utils/scatterobjectbufferhelper.cpp b/src/datavisualization/utils/scatterobjectbufferhelper.cpp index 9ecdffdd..5e98363e 100644 --- a/src/datavisualization/utils/scatterobjectbufferhelper.cpp +++ b/src/datavisualization/utils/scatterobjectbufferhelper.cpp @@ -220,7 +220,7 @@ uint ScatterObjectBufferHelper::createRangeGradientUVs(ScatterSeriesRenderCache if (!item.isVisible()) continue; - float y = ((item.translation().y() + m_scaleY) * 0.5f ) / m_scaleY; + 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++) diff --git a/src/datavisualization/utils/scatterpointbufferhelper.cpp b/src/datavisualization/utils/scatterpointbufferhelper.cpp index b14d84ad..2ddee31c 100644 --- a/src/datavisualization/utils/scatterpointbufferhelper.cpp +++ b/src/datavisualization/utils/scatterpointbufferhelper.cpp @@ -17,6 +17,7 @@ ****************************************************************************/ #include "scatterpointbufferhelper_p.h" +#include QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -86,9 +87,14 @@ void ScatterPointBufferHelper::load(ScatterSeriesRenderCache *cache) if (m_meshDataLoaded) { // Delete old data glDeleteBuffers(1, &m_pointbuffer); + glDeleteBuffers(1, &m_uvbuffer); m_bufferedPoints.clear(); } + QVector buffered_uvs; + if (cache->colorStyle() == Q3DTheme::ColorStyleRangeGradient) + createRangeGradientUVs(cache, buffered_uvs); + bool itemsVisible = false; m_bufferedPoints.resize(renderArraySize); for (int i = 0; i < renderArraySize; i++) { @@ -110,10 +116,54 @@ void ScatterPointBufferHelper::load(ScatterSeriesRenderCache *cache) glBufferData(GL_ARRAY_BUFFER, m_bufferedPoints.size() * sizeof(QVector3D), &m_bufferedPoints.at(0), GL_DYNAMIC_DRAW); + + if (buffered_uvs.size()) { + glGenBuffers(1, &m_uvbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); + glBufferData(GL_ARRAY_BUFFER, buffered_uvs.size() * sizeof(QVector2D), + &buffered_uvs.at(0), GL_STATIC_DRAW); + } + glBindBuffer(GL_ARRAY_BUFFER, 0); m_meshDataLoaded = true; } } +void ScatterPointBufferHelper::updateUVs(ScatterSeriesRenderCache *cache) +{ + QVector buffered_uvs; + + createRangeGradientUVs(cache, buffered_uvs); + + if (buffered_uvs.size()) { + if (!m_uvbuffer) + glGenBuffers(1, &m_uvbuffer); + + glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); + glBufferData(GL_ARRAY_BUFFER, buffered_uvs.size() * sizeof(QVector2D), + &buffered_uvs.at(0), GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + } +} + +void ScatterPointBufferHelper::createRangeGradientUVs(ScatterSeriesRenderCache *cache, + QVector &buffered_uvs) +{ + const ScatterRenderItemArray &renderArray = cache->renderArray(); + const uint renderArraySize = renderArray.size(); + buffered_uvs.resize(renderArraySize); + + QVector2D uv; + uv.setX(0.0f); + for (uint i = 0; i < renderArraySize; i++) { + const ScatterRenderItem &item = renderArray.at(i); + + float y = ((item.translation().y() + m_scaleY) * 0.5f) / m_scaleY; + uv.setY(y); + buffered_uvs[i] = uv; + } +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/utils/scatterpointbufferhelper_p.h b/src/datavisualization/utils/scatterpointbufferhelper_p.h index d09ce0f7..3edc4c8f 100644 --- a/src/datavisualization/utils/scatterpointbufferhelper_p.h +++ b/src/datavisualization/utils/scatterpointbufferhelper_p.h @@ -46,14 +46,21 @@ public: void pushPoint(uint pointIndex); void popPoint(); void load(ScatterSeriesRenderCache *cache); + void setScaleY(float scale) { m_scaleY = scale; } + void updateUVs(ScatterSeriesRenderCache *cache); public: GLuint m_pointbuffer; +private: + void createRangeGradientUVs(ScatterSeriesRenderCache *cache, + QVector &buffered_uvs); + private: QVector m_bufferedPoints; uint m_oldRemoveIndex; bool m_oldRemove; + float m_scaleY; }; QT_END_NAMESPACE_DATAVISUALIZATION -- cgit v1.2.3