summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-26 11:16:12 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-27 08:05:12 +0300
commitf2a5c09144f17f3240ae6a7e7b48237f1b234d9b (patch)
tree28f40212cd228f66277e8db84885ddef0ebb6c5a /src
parentb776b6d3aa287b973c9346736badc6181e50cbc7 (diff)
Allow resetting with existing array for surface
Improves performance when doing stuff like resetting image data. Task-number: QTRD-2335 Change-Id: I9e8ce49fd520b67125305a7614afc550b2244169 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp27
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp52
-rw-r--r--src/datavisualization/data/qsurfacedataproxy_p.h6
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp43
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler_p.h1
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp54
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp272
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h8
8 files changed, 239 insertions, 224 deletions
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
index 25e2a4db..c0b0723c 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -206,28 +206,35 @@ void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve()
int widthBits = imageWidth * 4;
qreal height = 0;
- QSurfaceDataArray *dataArray = new QSurfaceDataArray;
- dataArray->reserve(imageHeight);
+ // Do not recreate array if dimensions have not changed
+ QSurfaceDataArray *dataArray = m_dataArray;
+ if (imageWidth != qptr()->columnCount() || imageHeight != dataArray->size()) {
+ dataArray = new QSurfaceDataArray;
+ dataArray->reserve(imageHeight);
+ for (int i = 0; i < imageHeight; i++) {
+ QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(imageWidth);
+ dataArray->append(newProxyRow);
+ }
+ }
+
if (heightImage.isGrayscale()) {
// Grayscale, it's enough to read Red byte
- for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) {
- QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth);
+ for (int i = 0; i < imageHeight; i++, bitCount -= widthBits) {
+ QSurfaceDataRow &newRow = *dataArray->at(i);
for (int j = 0; j < imageWidth; j++)
- (*newRow)[j] = qreal(bits[bitCount + (j * 4)]);
- *dataArray << newRow;
+ newRow[j] = qreal(bits[bitCount + (j * 4)]);
}
} else {
// Not grayscale, we'll need to calculate height from RGB
- for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) {
- QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth);
+ for (int i = 0; i < imageHeight; i++, bitCount -= widthBits) {
+ QSurfaceDataRow &newRow = *dataArray->at(i);
for (int j = 0; j < imageWidth; j++) {
int nextpixel = j * 4;
height = (qreal(bits[bitCount + nextpixel])
+ qreal(bits[1 + bitCount + nextpixel])
+ qreal(bits[2 + bitCount + nextpixel]));
- (*newRow)[j] = (height / 3.0);
+ newRow[j] = height / 3.0;
}
- *dataArray << newRow;
}
}
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
index 1a2e29ce..98998f10 100644
--- a/src/datavisualization/data/qsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -143,23 +143,29 @@ QSurfaceDataProxy::~QSurfaceDataProxy()
}
/*!
- * Clears the existing array and takes ownership of the \a newArray. Do not use \a newArray pointer
- * to further modify data after QSurfaceDataProxy assumes ownership of it, as such modifications will
- * not trigger proper signals.
- * Passing null array clears all data.
- * Row and column ranges are reset to defaults.
+ * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is
+ * different than the existing array. If it's the same array, this just triggers arrayReset()
+ * signal.
+ * Passing null array deletes the old array and creates a new empty array.
+ * All rows in \a newArray must be of same length.
+ * Row and column ranges are reset to defaults, unless \a newArray is the same as the old array.
+ * In that case, old row and column ranges are kept.
*/
void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray)
{
- if (dptr()->resetArray(newArray, defaultMinValue, defaultMaxValue, defaultMinValue, defaultMaxValue))
- emit arrayReset();
+ if (dptr()->m_dataArray != newArray) {
+ dptr()->resetArray(newArray, defaultMinValue, defaultMaxValue, defaultMinValue,
+ defaultMaxValue);
+ }
+ emit arrayReset();
}
/*!
- * Clears the existing array and takes ownership of the \a newArray. Do not use \a newArray pointer
- * to further modify data after QSurfaceDataProxy assumes ownership of it, as such modifications will
- * not trigger proper signals.
- * Passing null array clears all data.
+ * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is
+ * different than the existing array. If it's the same array, this just triggers arrayReset()
+ * signal and updates row/column values.
+ * Passing null array deletes the old array and creates a new empty array.
+ * All rows in \a newArray must be of same length.
* Row and column ranges are set to values defined by the rest of the parameters: \a minValueRows,
* \a maxValueRows, \a minValueColumns, and \a maxValueColumns.
*/
@@ -167,8 +173,8 @@ void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray, qreal minValueRo
qreal maxValueRows, qreal minValueColumns,
qreal maxValueColumns)
{
- if (dptr()->resetArray(newArray, minValueRows, maxValueRows, minValueColumns, maxValueColumns))
- emit arrayReset();
+ dptr()->resetArray(newArray, minValueRows, maxValueRows, minValueColumns, maxValueColumns);
+ emit arrayReset();
}
/*!
@@ -346,30 +352,20 @@ QSurfaceDataProxyPrivate::~QSurfaceDataProxyPrivate()
clearArray();
}
-bool QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray, qreal minValueRows,
+void QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray, qreal minValueRows,
qreal maxValueRows, qreal minValueColumns,
qreal maxValueColumns)
{
- if (!m_dataArray->size() && (!newArray || !newArray->size()))
- return false;
-
- clearArray();
+ if (!newArray)
+ newArray = new QSurfaceDataArray;
- if (newArray) {
- for (int i = 0; i < newArray->size(); i++) {
- Q_ASSERT_X((newArray->at(i) && newArray->at(i)->size() == newArray->at(0)->size()),
- __FUNCTION__,
- "All rows of QSurfaceDataArray mustn't be NULL and must be of equal size.");
- }
+ if (newArray != m_dataArray) {
+ clearArray();
m_dataArray = newArray;
- } else {
- m_dataArray = new QSurfaceDataArray;
}
setValueRangeRows(minValueRows, maxValueRows);
setValueRangeColumns(minValueColumns, maxValueColumns);
-
- return true;
}
void QSurfaceDataProxyPrivate::setValueRangeRows(qreal min, qreal max)
diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h
index 8a60e93d..a40e8d65 100644
--- a/src/datavisualization/data/qsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qsurfacedataproxy_p.h
@@ -43,7 +43,7 @@ public:
QSurfaceDataProxyPrivate(QSurfaceDataProxy *q);
virtual ~QSurfaceDataProxyPrivate();
- bool resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows,
+ void resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows,
qreal minValueColumns, qreal maxValueColumns);
void setValueRangeRows(qreal min, qreal max);
@@ -58,12 +58,14 @@ public:
void limitValues(QVector3D &minValues, QVector3D &maxValues);
+protected:
+ QSurfaceDataArray *m_dataArray;
+
private:
QSurfaceDataProxy *qptr();
void clearRow(int rowIndex);
void clearArray();
- QSurfaceDataArray *m_dataArray;
qreal m_minValueRows;
qreal m_maxValueRows;
qreal m_minValueColumns;
diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp
index bc85847c..d32b442b 100644
--- a/src/datavisualization/data/surfaceitemmodelhandler.cpp
+++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp
@@ -23,7 +23,8 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent)
: AbstractItemModelHandler(parent),
- m_proxy(proxy)
+ m_proxy(proxy),
+ m_proxyArray(0)
{
}
@@ -51,7 +52,6 @@ void SurfaceItemModelHandler::resolveModel()
float minColumnValue = 0.0f;
float maxColumnValue = 1.0f;
- QSurfaceDataArray *newProxyArray = new QSurfaceDataArray;
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
// Default to display role if no mapping
@@ -60,11 +60,20 @@ void SurfaceItemModelHandler::resolveModel()
int columnCount = m_itemModel->columnCount();
if (mapping->useModelCategories()) {
+ // If dimensions have changed, recreate the array
+ if (!m_proxyArray || columnCount != m_proxy->columnCount()
+ || rowCount != m_proxyArray->size()) {
+ m_proxyArray = new QSurfaceDataArray;
+ m_proxyArray->reserve(rowCount);
+ for (int i = 0; i < rowCount; i++) {
+ QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(columnCount);
+ m_proxyArray->append(newProxyRow);
+ }
+ }
for (int i = 0; i < rowCount; i++) {
- QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(columnCount);
+ QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
for (int j = 0; j < columnCount; j++)
- (*newProxyRow)[j] = m_itemModel->index(i, j).data(valueRole).toReal();
- newProxyArray->append(newProxyRow);
+ newProxyRow[j] = m_itemModel->index(i, j).data(valueRole).toReal();
}
if (rowCount) {
minRowValue = m_itemModel->headerData(0, Qt::Vertical).toFloat();
@@ -118,12 +127,22 @@ void SurfaceItemModelHandler::resolveModel()
else
columnList = mapping->columnCategories();
- // Create new data array from itemValueMap
- foreach (QString rowKey, rowList) {
- QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(columnList.size());
- for (int i = 0; i < columnList.size(); i++)
- (*newProxyRow)[i] = itemValueMap[rowKey][columnList.at(i)];
- newProxyArray->append(newProxyRow);
+ // If dimensions have changed, recreate the array
+ if (!m_proxyArray || columnList.size() != m_proxy->columnCount()
+ || rowList.size() != m_proxyArray->size()) {
+ m_proxyArray = new QSurfaceDataArray;
+ m_proxyArray->reserve(rowList.size());
+ for (int i = 0; i < rowList.size(); i++) {
+ QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(columnList.size());
+ m_proxyArray->append(newProxyRow);
+ }
+ }
+ // Create data array from itemValueMap
+ for (int i = 0; i < rowList.size(); i++) {
+ QString rowKey = rowList.at(i);
+ QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
+ for (int j = 0; j < columnList.size(); j++)
+ newProxyRow[j] = itemValueMap[rowKey][columnList.at(j)];
}
// Use first and last roles converted to values for limits
@@ -137,7 +156,7 @@ void SurfaceItemModelHandler::resolveModel()
}
}
- m_proxy->resetArray(newProxyArray, minRowValue, maxRowValue, minColumnValue, maxColumnValue);
+ m_proxy->resetArray(m_proxyArray, minRowValue, maxRowValue, minColumnValue, maxColumnValue);
}
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/surfaceitemmodelhandler_p.h b/src/datavisualization/data/surfaceitemmodelhandler_p.h
index 045ac379..bcf642c5 100644
--- a/src/datavisualization/data/surfaceitemmodelhandler_p.h
+++ b/src/datavisualization/data/surfaceitemmodelhandler_p.h
@@ -45,6 +45,7 @@ protected:
void virtual resolveModel();
QItemModelSurfaceDataProxy *m_proxy; // Not owned
+ QSurfaceDataArray *m_proxyArray; // Not owned
};
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 0c234910..25a6a519 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -203,10 +203,6 @@ void Surface3DRenderer::initializeOpenGL()
void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
{
- for (int i = 0; i < m_dataArray.size(); i++)
- delete m_dataArray.at(i);
- m_dataArray.clear();
-
calculateSceneScalingFactors();
const QSurfaceDataArray *array = dataProxy->array();
@@ -219,17 +215,22 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
if (m_sampleSpace != sampleSpace) {
dimensionChanged = true;
m_sampleSpace = sampleSpace;
+
+ for (int i = 0; i < m_dataArray.size(); i++)
+ delete m_dataArray.at(i);
+ m_dataArray.clear();
}
// TODO: Handle partial surface grids on the graph edges
if (sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
- m_dataArray.reserve(sampleSpace.height());
+ 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++) {
- QSurfaceDataRow *newRow = new QSurfaceDataRow();
- newRow->resize(sampleSpace.width());
for (int j = 0; j < sampleSpace.width(); j++)
- (*newRow)[j] = array->at(i + sampleSpace.y())->at(j + sampleSpace.x());
- m_dataArray << newRow;
+ (*(m_dataArray.at(i)))[j] = array->at(i + sampleSpace.y())->at(j + sampleSpace.x());
}
if (m_dataArray.size() > 0) {
@@ -237,10 +238,15 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
loadSurfaceObj();
// Note: Data setup can change samplespace (as min width/height is 1)
- if (m_cachedSmoothSurface)
- m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer, dimensionChanged);
- else
- m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer, dimensionChanged);
+ if (m_cachedSmoothSurface) {
+ m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer,
+ dimensionChanged,
+ m_cachedSelectionMode != QDataVis::ModeNone);
+ } else {
+ m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer,
+ dimensionChanged,
+ m_cachedSelectionMode != QDataVis::ModeNone);
+ }
if (dimensionChanged)
updateSelectionTexture();
@@ -285,10 +291,13 @@ void Surface3DRenderer::updateSliceDataModel(int selectionId)
if (!m_sliceSurfaceObj)
loadSliceSurfaceObj();
- if (m_cachedSmoothSurface)
- m_sliceSurfaceObj->setUpSmoothData(m_sliceDataArray, sliceRect, m_heightNormalizer, true);
- else
- m_sliceSurfaceObj->setUpData(m_sliceDataArray, sliceRect, m_heightNormalizer, true);
+ if (m_cachedSmoothSurface) {
+ m_sliceSurfaceObj->setUpSmoothData(m_sliceDataArray, sliceRect, m_heightNormalizer,
+ true, true);
+ } else {
+ m_sliceSurfaceObj->setUpData(m_sliceDataArray, sliceRect, m_heightNormalizer, true,
+ true);
+ }
}
}
@@ -1736,10 +1745,13 @@ bool Surface3DRenderer::updateSmoothStatus(bool enable)
if (m_cachedSmoothSurface == false && !m_flatSupported)
m_cachedSmoothSurface = true;
- if (m_cachedSmoothSurface)
- m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer, true);
- else
- m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer, true);
+ if (m_cachedSmoothSurface) {
+ m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer, true,
+ m_cachedSelectionMode != QDataVis::ModeNone);
+ } else {
+ m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer, true,
+ m_cachedSelectionMode != QDataVis::ModeNone);
+ }
initSurfaceShaders();
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index d28ad447..0f9bb7e0 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -30,66 +30,87 @@ SurfaceObject::SurfaceObject()
{
m_indicesType = GL_UNSIGNED_INT;
initializeOpenGLFunctions();
+ glGenBuffers(1, &m_vertexbuffer);
+ glGenBuffers(1, &m_normalbuffer);
+ glGenBuffers(1, &m_uvbuffer);
+ glGenBuffers(1, &m_elementbuffer);
+ glGenBuffers(1, &m_gridElementbuffer);
}
SurfaceObject::~SurfaceObject()
{
+ glDeleteBuffers(1, &m_gridElementbuffer);
}
-void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, bool changeGeometry)
+void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space,
+ GLfloat yRange, bool changeGeometry, bool needTexture)
{
int columns = space.width();
int rows = space.height();
+ int totalSize = rows * columns;
GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
GLfloat height = yRange / 2.0f;
- // Create vertice table
- QVector<QVector3D> vertices;
+ // Create/populate vertice table
+ if (changeGeometry)
+ m_vertices.resize(totalSize);
+
QVector<QVector2D> uvs;
+ if (needTexture)
+ uvs.resize(totalSize);
float uvX = 1.0 / float(columns - 1);
float uvY = 1.0 / float(rows - 1);
- int row = 0;
- for (float i = 0.0f; i < float(rows); i += 1.0, row += columns) {
- for (float j = 0; j < columns; j++) {
- vertices.append(QVector3D(j / width - 1.0f,
- dataArray.at(int(i))->at(int(j)) / height - 1.0f,
- i / depth + 1.0f));
- uvs.append(QVector2D(j * uvX, i * uvY));
+ int totalIndex = 0;
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < columns; j++) {
+ m_vertices[totalIndex] = QVector3D(float(j) / width - 1.0f,
+ float(dataArray.at(i)->at(j)) / height - 1.0f,
+ float(i) / depth + 1.0f);
+ if (needTexture)
+ uvs[totalIndex] = QVector2D(float(j) * uvX, float(i) * uvY);
+ totalIndex++;
}
}
// Create normals
- QVector<QVector3D> normals;
- for (int row = 0; row < (rows - 1) * columns; row += columns) {
- for (int j = 0; j < columns - 1; j++) {
- normals.append(normal(vertices.at(row + j),
- vertices.at(row + j + 1),
- vertices.at(row + columns + j)));
+ int rowLimit = rows - 1;
+ int colLimit = columns - 1;
+ int rowColLimit = rowLimit * columns;
+ int totalLimit = totalSize - 1;
+ if (changeGeometry)
+ m_normals.resize(totalSize);
+
+ totalIndex = 0;
+ for (int row = 0; row < rowColLimit; row += columns) {
+ for (int j = 0; j < colLimit; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(row + j),
+ m_vertices.at(row + j + 1),
+ m_vertices.at(row + columns + j));
}
- int p = row + columns - 1;
- normals.append(normal(vertices.at(p),
- vertices.at(p + columns),
- vertices.at(p - 1)));
+ int p = row + colLimit;
+ m_normals[totalIndex++] = normal(m_vertices.at(p),
+ m_vertices.at(p + columns),
+ m_vertices.at(p - 1));
}
- for (int j = (rows - 1) * columns ; j < rows * columns - 1; j++) {
- normals.append(normal(vertices.at(j),
- vertices.at(j - columns),
- vertices.at(j + 1)));
+ for (int j = rowColLimit; j < totalLimit; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j - columns),
+ m_vertices.at(j + 1));
}
- int p = rows * columns - 1;
- normals.append(normal(vertices.at(p),
- vertices.at(p - 1),
- vertices.at(p - columns - 1)));
+ int p = rows * colLimit;
+ m_normals[totalIndex++] = normal(m_vertices.at(p),
+ m_vertices.at(p - 1),
+ m_vertices.at(p - columns - 1));
// Create indices table
GLint *indices = 0;
if (changeGeometry) {
- m_indexCount = 6 * (columns - 1) * (rows - 1);
+ m_indexCount = 6 * colLimit * rowLimit;
indices = new GLint[m_indexCount];
p = 0;
- for (int row = 0; row < (rows - 1) * columns; row += columns) {
- for (int j = 0; j < columns - 1; j++) {
+ for (int row = 0; row < rowLimit * columns; row += columns) {
+ for (int j = 0; j < colLimit; j++) {
// Left triangle
indices[p++] = row + j + 1;
indices[p++] = row + columns + j;
@@ -106,16 +127,16 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
// Create line element indices
GLint *gridIndices = 0;
if (changeGeometry) {
- m_gridIndexCount = 2 * columns * (rows - 1) + 2 * rows * (columns - 1);
+ m_gridIndexCount = 2 * columns * rowLimit + 2 * rows * colLimit;
gridIndices = new GLint[m_gridIndexCount];
p = 0;
for (int i = 0, row = 0; i < rows; i++, row += columns) {
- for (int j = 0; j < columns - 1; j++) {
+ for (int j = 0; j < colLimit; j++) {
gridIndices[p++] = row + j;
gridIndices[p++] = row + j + 1;
}
}
- for (int i = 0, row = 0; i < rows - 1; i++, row += columns) {
+ for (int i = 0, row = 0; i < rowLimit; i++, row += columns) {
for (int j = 0; j < columns; j++) {
gridIndices[p++] = row + j;
gridIndices[p++] = row + j + columns;
@@ -123,17 +144,19 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
}
}
- createBuffers(vertices, uvs, normals, indices, gridIndices, changeGeometry);
+ createBuffers(m_vertices, uvs, m_normals, indices, gridIndices, changeGeometry);
delete[] indices;
delete[] gridIndices;
}
-void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, bool changeGeometry)
+void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &space,
+ GLfloat yRange, bool changeGeometry, bool needTexture)
{
int columns = space.width();
int rows = space.height();
+ int totalSize = rows * columns * 2;
GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
GLfloat height = yRange / 2.0f;
@@ -141,46 +164,63 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
float uvY = 1.0 / float(rows - 1);
// Create vertice table
- QVector<QVector3D> vertices;
+ if (changeGeometry)
+ m_vertices.resize(totalSize);
+
QVector<QVector2D> uvs;
- int row = 0;
- for (float i = 0.0f; i < float(rows); i += 1.0f, row += columns) {
- for (float j = 0.0f; j < float(columns); j += 1.0f) {
- vertices.append(QVector3D(j / width - 1.0f,
- dataArray.at(int(i))->at(int(j)) / height - 1.0f,
- i / depth + 1.0f));
- uvs.append(QVector2D(j * uvX, i * uvY));
- if (j > 0 && j < columns - 1) {
- vertices.append(vertices.last());
- uvs.append(uvs.last());
+ if (needTexture)
+ uvs.resize(totalSize);
+
+ int totalIndex = 0;
+ int rowLimit = rows - 1;
+ int colLimit = columns - 1;
+ int doubleColumns = columns * 2 - 2;
+ int rowColLimit = rowLimit * doubleColumns;
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < columns; j++) {
+ m_vertices[totalIndex] = QVector3D(float(j) / width - 1.0f,
+ float(dataArray.at(i)->at(j)) / height - 1.0f,
+ float(i) / depth + 1.0f);
+
+ if (needTexture)
+ uvs[totalIndex] = QVector2D(float(j) * uvX, float(i) * uvY);
+
+ totalIndex++;
+
+ if (j > 0 && j < colLimit) {
+ m_vertices[totalIndex] = m_vertices[totalIndex - 1];
+ if (needTexture)
+ uvs[totalIndex] = uvs[totalIndex - 1];
+ totalIndex++;
}
}
}
// Create normals & indices table
- QVector<QVector3D> normals;
- int doubleColumns = columns * 2 - 2;
-
GLint *indices = 0;
int p = 0;
if (changeGeometry) {
- m_indexCount = 6 * (columns - 1) * (rows - 1);
+ int normalCount = 2 * colLimit * rowLimit;
+ m_indexCount = 3 * normalCount;
indices = new GLint[m_indexCount];
+ m_normals.resize(normalCount);
}
+ totalIndex = 0;
for (int row = 0, upperRow = doubleColumns;
- row < (rows - 1) * doubleColumns;
+ row < rowColLimit;
row += doubleColumns, upperRow += doubleColumns) {
for (int j = 0; j < doubleColumns; j += 2) {
// Normal for the left triangle
- normals.append(normal(vertices.at(row + j),
- vertices.at(row + j + 1),
- vertices.at(upperRow + j)));
+ m_normals[totalIndex++] = normal(m_vertices.at(row + j),
+ m_vertices.at(row + j + 1),
+ m_vertices.at(upperRow + j));
// Normal for the right triangle
- normals.append(normal(vertices.at(row + j + 1),
- vertices.at(upperRow + j + 1),
- vertices.at(upperRow + j)));
+ m_normals[totalIndex++] = normal(m_vertices.at(row + j + 1),
+ m_vertices.at(upperRow + j + 1),
+ m_vertices.at(upperRow + j));
if (changeGeometry) {
// Left triangle
@@ -197,79 +237,66 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
}
// Create grid line element indices
- m_gridIndexCount = 2 * columns * (rows - 1) + 2 * rows * (columns - 1);
- GLint *gridIndices = new GLint[m_gridIndexCount];
- p = 0;
- int rowLimit = (rows - 1) * doubleColumns;
- for (int row = 0; row < rows * doubleColumns; row += doubleColumns) {
- for (int j = 0; j < doubleColumns; j += 2) {
- gridIndices[p++] = row + j;
- gridIndices[p++] = row + j + 1;
-
- if (row < rowLimit) {
+ GLint *gridIndices = 0;
+ if (changeGeometry) {
+ m_gridIndexCount = 2 * columns * rowLimit + 2 * rows * colLimit;
+ gridIndices = new GLint[m_gridIndexCount];
+ p = 0;
+ int fullRowLimit = rows * doubleColumns;
+ for (int row = 0; row < fullRowLimit; row += doubleColumns) {
+ for (int j = 0; j < doubleColumns; j += 2) {
gridIndices[p++] = row + j;
- gridIndices[p++] = row + j + doubleColumns;
+ gridIndices[p++] = row + j + 1;
+
+ if (row < rowColLimit) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + doubleColumns;
+ }
}
}
- }
- for (int i = doubleColumns - 1; i < rowLimit; i += doubleColumns) {
- gridIndices[p++] = i;
- gridIndices[p++] = i + doubleColumns;
+ for (int i = doubleColumns - 1; i < rowColLimit; i += doubleColumns) {
+ gridIndices[p++] = i;
+ gridIndices[p++] = i + doubleColumns;
+ }
}
- createBuffers(vertices, uvs, normals, indices, gridIndices, changeGeometry);
+ createBuffers(m_vertices, uvs, m_normals, indices, gridIndices, changeGeometry);
delete[] indices;
delete[] gridIndices;
}
void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
- const QVector<QVector3D> &normals, const GLint *indices,
- const GLint *gridIndices, bool changeGeometry)
+ const QVector<QVector3D> &normals, const GLint *indices,
+ const GLint *gridIndices, bool changeGeometry)
{
- if (m_meshDataLoaded) {
- // Delete old data
- glDeleteBuffers(1, &m_vertexbuffer);
- glDeleteBuffers(1, &m_normalbuffer);
- if (changeGeometry) {
- glDeleteBuffers(1, &m_uvbuffer);
- glDeleteBuffers(1, &m_elementbuffer);
- glDeleteBuffers(1, &m_gridElementbuffer);
- }
- }
-
// Move to buffers
- glGenBuffers(1, &m_vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(QVector3D),
- &vertices.at(0), GL_STATIC_DRAW);
+ &vertices.at(0), GL_DYNAMIC_DRAW);
- glGenBuffers(1, &m_normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(QVector3D),
- &normals.at(0), GL_STATIC_DRAW);
+ &normals.at(0), GL_DYNAMIC_DRAW);
if (changeGeometry) {
- glGenBuffers(1, &m_uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
&uvs.at(0), GL_STATIC_DRAW);
- glGenBuffers(1, &m_elementbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount * sizeof(GLint),
indices, GL_STATIC_DRAW);
- glGenBuffers(1, &m_gridElementbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_gridElementbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_gridIndexCount * sizeof(GLint),
gridIndices, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- // We're done. Set the flag ON
m_meshDataLoaded = true;
}
@@ -293,56 +320,3 @@ QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QV
}
QT_DATAVISUALIZATION_END_NAMESPACE
-
-
-
-// For rainy days
-
-// QVector3D vertices[] = {
-// QVector3D(-0.5f, 0.0f, 0.1f),
-// QVector3D(0.5f, 0.0f, 0.1f),
-// QVector3D(0.0f, 1.0f, -0.5f)
-// };
-
-// QVector3D normals[] = {
-// QVector3D(0.5, 0.0, 1.0),
-// QVector3D(0.5, 0.0, 1.0),
-// QVector3D(0.5, 0.0, 1.0)
-// };
-
-// vertices.append(QVector3D(-1.0f, 0.0f, 0.1f));
-// vertices.append(QVector3D(0.0f, 0.0f, 0.1f));
-// vertices.append(QVector3D(0.0f, 0.5f, -0.5f));
-
-// normals.append(QVector3D(0.5, 0.0, 1.0));
-// normals.append(QVector3D(0.5, 0.0, 1.0));
-// normals.append(QVector3D(0.5, 0.0, 1.0));
-
-//GLushort indices[] = {0, 1, 2, 1, 3, 2};
-//GLushort indices[] = {1, 3, 2};
-
-//qDebug() << indices[p + 0] << ", " << indices[p + 1] << ", " << indices[p + 2];
-//qDebug() << indices[p + 3] << ", " << indices[p + 4] << ", " << indices[p + 5];
-
-//qDebug() << "(" << float(j) / width << ", 0.0, " << float(i) / depth * -1.0f << ")";
-
-//normals.append(QVector3D(1,0,0));
-//normals.append(QVector3D(0,1,0));
-//normals.append(QVector3D(0,0,1));
-//normals.append(QVector3D(1,0,1));
-
-//normals.append(QVector3D(1,0,0));
-//normals.append(QVector3D(0,1,0));
-//normals.append(QVector3D(0,0,1));
-//normals.append(QVector3D(1,0,1));
-
-//normals.append(QVector3D(1,0,0));
-//normals.append(QVector3D(0,1,0));
-//normals.append(QVector3D(0,0,1));
-//normals.append(QVector3D(1,0,1));
-
-
-//qDebug() << "Left normal from (" << row + j << ", " << row + j + 1 << ", " << row + doubleColumns + j << ")";
-
-//qDebug() << "right normal from (" << row + j +1 << ", " << row + doubleColumns + j + 1 << ", " << row + doubleColumns + j << ")";
-
diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index f19fffc0..0a52ca7c 100644
--- a/src/datavisualization/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -44,8 +44,10 @@ public:
SurfaceObject();
~SurfaceObject();
- void setUpData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, bool changeGeometry);
- void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, bool changeGeometry);
+ void setUpData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange,
+ bool changeGeometry, bool needTexture);
+ void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange,
+ bool changeGeometry, bool needTexture);
GLuint gridElementBuf();
GLuint gridIndexCount();
@@ -61,6 +63,8 @@ private:
GLfloat m_yRange;
GLuint m_gridElementbuffer;
GLuint m_gridIndexCount;
+ QVector<QVector3D> m_vertices;
+ QVector<QVector3D> m_normals;
};
QT_DATAVISUALIZATION_END_NAMESPACE