From df2571bdf0b15237a324471c63913989c80349d8 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 2 Oct 2014 16:19:33 +0300 Subject: Fix changing items in static optimization mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTRD-3344 Change-Id: I8c1d2e2ae4afd6f9058c59adfc3d784b5f724358 Reviewed-by: Tomi Korpipää --- .../utils/scatterobjectbufferhelper.cpp | 89 +++++++++++++-------- .../utils/scatterpointbufferhelper.cpp | 91 +++++++++++++++------- .../utils/scatterpointbufferhelper_p.h | 4 +- 3 files changed, 125 insertions(+), 59 deletions(-) (limited to 'src/datavisualization/utils') diff --git a/src/datavisualization/utils/scatterobjectbufferhelper.cpp b/src/datavisualization/utils/scatterobjectbufferhelper.cpp index 5e98363e..5eb74011 100644 --- a/src/datavisualization/utils/scatterobjectbufferhelper.cpp +++ b/src/datavisualization/utils/scatterobjectbufferhelper.cpp @@ -49,7 +49,7 @@ void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal if (renderArraySize == 0) return; // No use to go forward - uint itemCount = renderArraySize; + uint itemCount = 0; QQuaternion seriesRotation(cache->meshRotation()); if (m_meshDataLoaded) { @@ -96,7 +96,6 @@ void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal buffered_vertices.resize(verticeCount * renderArraySize); buffered_normals.resize(normalsCount * renderArraySize); buffered_uvs.resize(uvsCount * renderArraySize); - uint pos = 0; if (cache->colorStyle() == Q3DTheme::ColorStyleRangeGradient) createRangeGradientUVs(cache, buffered_uvs); @@ -105,14 +104,16 @@ void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal QVector2D dummyUV(0.0f, 0.0f); + cache->bufferIndices().resize(renderArraySize); + for (uint i = 0; i < renderArraySize; i++) { const ScatterRenderItem &item = renderArray.at(i); - if (!item.isVisible()) { - itemCount--; + if (!item.isVisible()) continue; - } + else + cache->bufferIndices()[i] = itemCount; - int offset = pos * verticeCount; + int offset = itemCount * verticeCount; if (item.rotation().isIdentity()) { for (int j = 0; j < verticeCount; j++) { buffered_vertices[j + offset] = scaled_vertices[j] + item.translation(); @@ -134,18 +135,17 @@ void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal } if (cache->colorStyle() == Q3DTheme::ColorStyleUniform) { - offset = pos * uvsCount; + offset = itemCount * uvsCount; for (int j = 0; j < uvsCount; j++) buffered_uvs[j + offset] = dummyUV; } - int offsetVertice = i * verticeCount; - offset = pos * indicesCount; - for (int j = 0; j < indicesCount; j++) { + int offsetVertice = itemCount * verticeCount; + offset = itemCount * indicesCount; + for (int j = 0; j < indicesCount; j++) buffered_indices[j + offset] = GLuint(indices[j] + offsetVertice); - } - pos++; + itemCount++; } m_indexCount = indicesCount * itemCount; @@ -185,9 +185,14 @@ 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(); + const bool updateAll = (cache->updateIndices().size() == 0); + const int updateSize = updateAll ? renderArray.size() : cache->updateIndices().size(); + + if (!updateSize) + return; + QVector buffered_uvs; - buffered_uvs.resize(uvsCount * renderArraySize); + buffered_uvs.resize(uvsCount * updateSize); uint itemCount = 0; if (cache->colorStyle() == Q3DTheme::ColorStyleRangeGradient) { @@ -198,9 +203,20 @@ void ScatterObjectBufferHelper::updateUVs(ScatterSeriesRenderCache *cache) } glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); - glBufferData(GL_ARRAY_BUFFER, uvsCount * itemCount * sizeof(QVector2D), - &buffered_uvs.at(0), GL_STATIC_DRAW); - + int itemSize = uvsCount * sizeof(QVector2D); + if (cache->updateIndices().size()) { + int pos = 0; + for (int i = 0; i < updateSize; i++) { + int index = cache->updateIndices().at(i); + if (renderArray.at(index).isVisible()) { + int dataPos = cache->bufferIndices().at(index); + glBufferSubData(GL_ARRAY_BUFFER, itemSize * dataPos, itemSize, + &buffered_uvs.at(uvsCount * pos++)); + } + } + } else { + glBufferData(GL_ARRAY_BUFFER, itemSize * itemCount, &buffered_uvs.at(0), GL_STATIC_DRAW); + } glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -210,13 +226,15 @@ uint ScatterObjectBufferHelper::createRangeGradientUVs(ScatterSeriesRenderCache ObjectHelper *dotObj = cache->object(); const int uvsCount = dotObj->indexedUVs().count(); const ScatterRenderItemArray &renderArray = cache->renderArray(); - const uint renderArraySize = renderArray.size(); + const bool updateAll = (cache->updateIndices().size() == 0); + const int updateSize = updateAll ? renderArray.size() : cache->updateIndices().size(); QVector2D uv; uv.setX(0.0f); uint pos = 0; - for (uint i = 0; i < renderArraySize; i++) { - const ScatterRenderItem &item = renderArray.at(i); + for (int i = 0; i < updateSize; i++) { + int index = updateAll ? i : cache->updateIndices().at(i); + const ScatterRenderItem &item = renderArray.at(index); if (!item.isVisible()) continue; @@ -263,13 +281,15 @@ uint ScatterObjectBufferHelper::createObjectGradientUVs(ScatterSeriesRenderCache void ScatterObjectBufferHelper::update(ScatterSeriesRenderCache *cache, qreal dotScale) { - initializeOpenGLFunctions(); - ObjectHelper *dotObj = cache->object(); const ScatterRenderItemArray &renderArray = cache->renderArray(); - const int renderArraySize = renderArray.size(); + const bool updateAll = (cache->updateIndices().size() == 0); + const int updateSize = updateAll ? renderArray.size() : cache->updateIndices().size(); QQuaternion seriesRotation(cache->meshRotation()); + if (!updateSize) + return; + // Index vertices const QVector indexed_vertices = dotObj->indexedvertices(); int verticeCount = indexed_vertices.count(); @@ -292,10 +312,11 @@ void ScatterObjectBufferHelper::update(ScatterSeriesRenderCache *cache, qreal do scaled_vertices[i] = indexed_vertices[i] * modelMatrix; QVector buffered_vertices; + buffered_vertices.resize(verticeCount * updateSize); - buffered_vertices.resize(verticeCount * renderArraySize); - for (int i = 0; i < renderArraySize; i++) { - const ScatterRenderItem &item = renderArray.at(i); + for (int i = 0; i < updateSize; i++) { + int index = updateAll ? i : cache->updateIndices().at(i); + const ScatterRenderItem &item = renderArray.at(index); if (!item.isVisible()) continue; @@ -316,12 +337,18 @@ void ScatterObjectBufferHelper::update(ScatterSeriesRenderCache *cache, qreal do } glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); - glBufferData(GL_ARRAY_BUFFER, buffered_vertices.size() * sizeof(QVector3D), - &buffered_vertices.at(0), - GL_DYNAMIC_DRAW); - + if (updateAll) { + glBufferData(GL_ARRAY_BUFFER, buffered_vertices.size() * sizeof(QVector3D), + &buffered_vertices.at(0), GL_DYNAMIC_DRAW); + } else { + int itemSize = verticeCount * sizeof(QVector3D); + for (int i = 0; i < updateSize; i++) { + int index = updateAll ? i : cache->updateIndices().at(i); + glBufferSubData(GL_ARRAY_BUFFER, cache->bufferIndices().at(index) * itemSize, + itemSize, &buffered_vertices.at(i * verticeCount)); + } + } glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); m_meshDataLoaded = true; } diff --git a/src/datavisualization/utils/scatterpointbufferhelper.cpp b/src/datavisualization/utils/scatterpointbufferhelper.cpp index 2ddee31c..5076502f 100644 --- a/src/datavisualization/utils/scatterpointbufferhelper.cpp +++ b/src/datavisualization/utils/scatterpointbufferhelper.cpp @@ -25,8 +25,7 @@ const QVector3D hiddenPos(-1000.0f, -1000.0f, -1000.0f); ScatterPointBufferHelper::ScatterPointBufferHelper() : m_pointbuffer(0), - m_oldRemoveIndex(0), - m_oldRemove(false) + m_oldRemoveIndex(-1) { m_indicesType = GL_UNSIGNED_INT; } @@ -48,7 +47,8 @@ void ScatterPointBufferHelper::pushPoint(uint pointIndex) { glBindBuffer(GL_ARRAY_BUFFER, m_pointbuffer); - if (m_oldRemove && m_oldRemoveIndex < pointIndex) { + // Pop the previous point if it is still pushed + if (m_oldRemoveIndex >= 0) { glBufferSubData(GL_ARRAY_BUFFER, m_oldRemoveIndex * sizeof(QVector3D), sizeof(QVector3D), &m_bufferedPoints.at(m_oldRemoveIndex)); } @@ -60,20 +60,18 @@ void ScatterPointBufferHelper::pushPoint(uint pointIndex) glBindBuffer(GL_ARRAY_BUFFER, 0); m_oldRemoveIndex = pointIndex; - m_oldRemove = true; } void ScatterPointBufferHelper::popPoint() { - if (m_oldRemove) { + if (m_oldRemoveIndex >= 0) { glBindBuffer(GL_ARRAY_BUFFER, m_pointbuffer); glBufferSubData(GL_ARRAY_BUFFER, m_oldRemoveIndex * sizeof(QVector3D), sizeof(QVector3D), &m_bufferedPoints.at(m_oldRemoveIndex)); glBindBuffer(GL_ARRAY_BUFFER, 0); } - m_oldRemoveIndex = 0; - m_oldRemove = false; + m_oldRemoveIndex = -1; } void ScatterPointBufferHelper::load(ScatterSeriesRenderCache *cache) @@ -91,14 +89,10 @@ void ScatterPointBufferHelper::load(ScatterSeriesRenderCache *cache) 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++) { - ScatterRenderItem &item = renderArray[i]; + const ScatterRenderItem &item = renderArray.at(i); if (!item.isVisible()) { m_bufferedPoints[i] = hiddenPos; } else { @@ -107,10 +101,14 @@ void ScatterPointBufferHelper::load(ScatterSeriesRenderCache *cache) } } + QVector buffered_uvs; if (itemsVisible) m_indexCount = renderArraySize; if (m_indexCount > 0) { + if (cache->colorStyle() == Q3DTheme::ColorStyleRangeGradient) + createRangeGradientUVs(cache, buffered_uvs); + glGenBuffers(1, &m_pointbuffer); glBindBuffer(GL_ARRAY_BUFFER, m_pointbuffer); glBufferData(GL_ARRAY_BUFFER, m_bufferedPoints.size() * sizeof(QVector3D), @@ -130,21 +128,60 @@ void ScatterPointBufferHelper::load(ScatterSeriesRenderCache *cache) } } -void ScatterPointBufferHelper::updateUVs(ScatterSeriesRenderCache *cache) +void ScatterPointBufferHelper::update(ScatterSeriesRenderCache *cache) { - QVector buffered_uvs; + // It may be that the buffer hasn't yet been initialized, in case the entire series was + // hidden items. No need to update in that case. + if (m_indexCount > 0) { + const ScatterRenderItemArray &renderArray = cache->renderArray(); + const int updateSize = cache->updateIndices().size(); - createRangeGradientUVs(cache, buffered_uvs); + glBindBuffer(GL_ARRAY_BUFFER, m_pointbuffer); + for (int i = 0; i < updateSize; i++) { + int index = cache->updateIndices().at(i); + const ScatterRenderItem &item = renderArray.at(index); + if (!item.isVisible()) + m_bufferedPoints[index] = hiddenPos; + else + m_bufferedPoints[index] = item.translation(); + + if (index != m_oldRemoveIndex) { + glBufferSubData(GL_ARRAY_BUFFER, index * sizeof(QVector3D), + sizeof(QVector3D), &m_bufferedPoints.at(index)); + } + } + glBindBuffer(GL_ARRAY_BUFFER, 0); + } +} - if (buffered_uvs.size()) { - if (!m_uvbuffer) - glGenBuffers(1, &m_uvbuffer); +void ScatterPointBufferHelper::updateUVs(ScatterSeriesRenderCache *cache) +{ + // It may be that the buffer hasn't yet been initialized, in case the entire series was + // hidden items. No need to update in that case. + if (m_indexCount > 0) { + QVector buffered_uvs; + createRangeGradientUVs(cache, buffered_uvs); - glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); - glBufferData(GL_ARRAY_BUFFER, buffered_uvs.size() * sizeof(QVector2D), - &buffered_uvs.at(0), GL_STATIC_DRAW); + if (buffered_uvs.size()) { + if (!m_uvbuffer) + glGenBuffers(1, &m_uvbuffer); - glBindBuffer(GL_ARRAY_BUFFER, 0); + int updateSize = cache->updateIndices().size(); + glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); + if (updateSize) { + for (int i = 0; i < updateSize; i++) { + int index = cache->updateIndices().at(i); + glBufferSubData(GL_ARRAY_BUFFER, index * sizeof(QVector2D), + sizeof(QVector2D), &buffered_uvs.at(i)); + + } + } else { + glBufferData(GL_ARRAY_BUFFER, buffered_uvs.size() * sizeof(QVector2D), + &buffered_uvs.at(0), GL_STATIC_DRAW); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + } } } @@ -152,13 +189,15 @@ void ScatterPointBufferHelper::createRangeGradientUVs(ScatterSeriesRenderCache * QVector &buffered_uvs) { const ScatterRenderItemArray &renderArray = cache->renderArray(); - const uint renderArraySize = renderArray.size(); - buffered_uvs.resize(renderArraySize); + const bool updateAll = (cache->updateIndices().size() == 0); + const int updateSize = updateAll ? renderArray.size() : cache->updateIndices().size(); + buffered_uvs.resize(updateSize); QVector2D uv; uv.setX(0.0f); - for (uint i = 0; i < renderArraySize; i++) { - const ScatterRenderItem &item = renderArray.at(i); + for (int i = 0; i < updateSize; i++) { + int index = updateAll ? i : cache->updateIndices().at(i); + const ScatterRenderItem &item = renderArray.at(index); float y = ((item.translation().y() + m_scaleY) * 0.5f) / m_scaleY; uv.setY(y); diff --git a/src/datavisualization/utils/scatterpointbufferhelper_p.h b/src/datavisualization/utils/scatterpointbufferhelper_p.h index 3edc4c8f..8b34542d 100644 --- a/src/datavisualization/utils/scatterpointbufferhelper_p.h +++ b/src/datavisualization/utils/scatterpointbufferhelper_p.h @@ -46,6 +46,7 @@ public: void pushPoint(uint pointIndex); void popPoint(); void load(ScatterSeriesRenderCache *cache); + void update(ScatterSeriesRenderCache *cache); void setScaleY(float scale) { m_scaleY = scale; } void updateUVs(ScatterSeriesRenderCache *cache); @@ -58,8 +59,7 @@ private: private: QVector m_bufferedPoints; - uint m_oldRemoveIndex; - bool m_oldRemove; + int m_oldRemoveIndex; float m_scaleY; }; -- cgit v1.2.3