summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-23 13:57:47 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-24 09:50:51 +0300
commitf842e21c7fa44d806c06a1463c723632b10e6172 (patch)
tree544b03ec20521c203a884cf74809972410532730 /src/datavisualization
parentac789c99ad04e5e907365d408d5f94df1685a668 (diff)
Made surface axis ranges adjustable.
If the surface is partially off the visible range, only grids that are fully within the visible range will be drawn. If only one row or column is within visible range, surface is not drawn. Task-number: QTRD-2320 Change-Id: If2691577cde61dfd270d79c32b9d6f69984966ba Reviewed-by: Mika Salmela <mika.salmela@digia.com> Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp101
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy_p.h4
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp3
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp178
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h10
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp6
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h4
7 files changed, 184 insertions, 122 deletions
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
index 293eb9eb..f40fa395 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -82,7 +82,7 @@ QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(QObject *parent) :
* \sa heightMap
*/
QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent) :
- QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this, image), parent)
+ QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this), parent)
{
setHeightMap(image);
}
@@ -118,50 +118,17 @@ QHeightMapSurfaceDataProxy::~QHeightMapSurfaceDataProxy()
* grayscale images may improve data conversion speed for large images.
*
* Not recommended formats: all mono formats (for example QImage::Format_Mono).
+ *
+ * The height map is resolved asynchronously. QSurfaceDataProxy::arrayReset() is emitted when the
+ * data has been resolved.
*/
void QHeightMapSurfaceDataProxy::setHeightMap(const QImage &image)
{
dptr()->m_heightMap = image;
- QImage heightImage = image;
- // Convert to RGB32 to be sure we're reading the right bytes
- if (heightImage.format() != QImage::Format_RGB32)
- heightImage = image.convertToFormat(QImage::Format_RGB32);
-
- uchar *bits = heightImage.bits();
-
- int imageHeight = heightImage.height();
- int imageWidth = heightImage.width();
- int bitCount = imageWidth * 4 * (imageHeight - 1);
- int widthBits = imageWidth * 4;
- qreal height = 0;
-
- QSurfaceDataArray *dataArray = new QSurfaceDataArray;
- dataArray->reserve(imageHeight);
- 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 j = 0; j < imageWidth; j++)
- (*newRow)[j] = qreal(bits[bitCount + (j * 4)]) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height
- *dataArray << newRow;
- }
- } 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 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) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height
- }
- *dataArray << newRow;
- }
- }
-
- resetArray(dataArray, 0.0, imageHeight, 0.0, imageWidth);
+ // We do resolving asynchronously to make qml onArrayReset handlers actually get the initial reset
+ if (!dptr()->m_resolveTimer.isActive())
+ dptr()->m_resolveTimer.start(0);
}
QImage QHeightMapSurfaceDataProxy::heightMap() const
@@ -210,17 +177,61 @@ const QHeightMapSurfaceDataProxyPrivate *QHeightMapSurfaceDataProxy::dptrc() con
QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q)
: QSurfaceDataProxyPrivate(q)
{
+ m_resolveTimer.setSingleShot(true);
+ QObject::connect(&m_resolveTimer, &QTimer::timeout,
+ this, &QHeightMapSurfaceDataProxyPrivate::handlePendingResolve);
}
-QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q,
- const QImage &image)
- : QSurfaceDataProxyPrivate(q),
- m_heightMap(image)
+QHeightMapSurfaceDataProxyPrivate::~QHeightMapSurfaceDataProxyPrivate()
{
}
-QHeightMapSurfaceDataProxyPrivate::~QHeightMapSurfaceDataProxyPrivate()
+QHeightMapSurfaceDataProxy *QHeightMapSurfaceDataProxyPrivate::qptr()
{
+ return static_cast<QHeightMapSurfaceDataProxy *>(q_ptr);
+}
+
+void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve()
+{
+ QImage heightImage = m_heightMap;
+ // Convert to RGB32 to be sure we're reading the right bytes
+ if (heightImage.format() != QImage::Format_RGB32)
+ heightImage = heightImage.convertToFormat(QImage::Format_RGB32);
+
+ uchar *bits = heightImage.bits();
+
+ int imageHeight = heightImage.height();
+ int imageWidth = heightImage.width();
+ int bitCount = imageWidth * 4 * (imageHeight - 1);
+ int widthBits = imageWidth * 4;
+ qreal height = 0;
+
+ QSurfaceDataArray *dataArray = new QSurfaceDataArray;
+ dataArray->reserve(imageHeight);
+ 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 j = 0; j < imageWidth; j++)
+ (*newRow)[j] = qreal(bits[bitCount + (j * 4)]) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height
+ *dataArray << newRow;
+ }
+ } 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 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) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height
+ }
+ *dataArray << newRow;
+ }
+ }
+
+ qptr()->resetArray(dataArray, 0.0, imageHeight, 0.0, imageWidth);
}
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
index 3cccb4ed..7140c8ef 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
@@ -31,6 +31,7 @@
#include "qheightmapsurfacedataproxy.h"
#include "qsurfacedataproxy_p.h"
+#include <QTimer>
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
@@ -40,14 +41,15 @@ class QHeightMapSurfaceDataProxyPrivate : public QSurfaceDataProxyPrivate
public:
QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q);
- QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q, const QImage &image);
virtual ~QHeightMapSurfaceDataProxyPrivate();
private:
QHeightMapSurfaceDataProxy *qptr();
+ void handlePendingResolve();
QImage m_heightMap;
QString m_heightMapFile;
+ QTimer m_resolveTimer;
friend class QHeightMapSurfaceDataProxy;
};
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
index 30cc84f1..bd3688dc 100644
--- a/src/datavisualization/data/qsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -39,6 +39,9 @@ const qreal defaultMaxValue = 10.0;
*
* All rows must have same number of values.
*
+ * \note Surfaces with less than two rows or columns are not considered valid surfaces and will
+ * not get rendered.
+ *
* QSurfaceDataProxy supports the following format tags for QAbstractDataProxy::setItemLabelFormat():
* \table
* \row
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 9fea6ddb..67f12b0a 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -76,6 +76,16 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_scaleZ(0.0f),
m_scaleXWithBackground(0.0f),
m_scaleZWithBackground(0.0f),
+ m_surfaceScaleX(0.0f),
+ m_surfaceScaleZ(0.0f),
+ m_surfaceOffsetX(0.0f),
+ m_surfaceOffsetZ(0.0f),
+ m_minVisibleColumnValue(0.0f),
+ m_maxVisibleColumnValue(0.0f),
+ m_minVisibleRowValue(0.0f),
+ m_maxVisibleRowValue(0.0f),
+ m_dataStepX(0.0f),
+ m_dataStepZ(0.0f),
m_backgroundObj(0),
m_gridLineObj(0),
m_labelObj(0),
@@ -196,45 +206,17 @@ void Surface3DRenderer::initializeOpenGL()
void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
{
- // Make a copy of data array.
for (int i = 0; i < m_dataArray.size(); i++)
delete m_dataArray.at(i);
m_dataArray.clear();
- const QSurfaceDataArray *array = dataProxy->array();
-
- QRect sampleSpace = calculateSampleRect(dataProxy);
-
- m_dataArray.reserve(sampleSpace.height());
- 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;
- }
-
- // If data contains only one row, duplicate it to make surface
- if (sampleSpace.height() == 1) {
- QSurfaceDataRow *newRow = new QSurfaceDataRow(*m_dataArray.at(0));
- m_dataArray << newRow;
- sampleSpace.setHeight(2);
- }
-
- // If data contains only one column, duplicate the value to make surface
- if (sampleSpace.width() == 1) {
- for (int i = 0; i < sampleSpace.height(); i++)
- (*m_dataArray.at(i)) << m_dataArray.at(i)->at(0);
- sampleSpace.setWidth(2);
- }
-
calculateSceneScalingFactors();
- if (m_dataArray.size() > 0) {
- if (!m_surfaceObj)
- loadSurfaceObj();
+ const QSurfaceDataArray *array = dataProxy->array();
- sampleSpace.moveTo(0, 0);
+ // Need minimum of 2x2 array to draw a surface
+ if (array->size() >= 2 && array->at(0)->size() >= 2) {
+ QRect sampleSpace = calculateSampleRect(dataProxy);
bool dimensionChanged = false;
if (m_sampleSpace != sampleSpace) {
@@ -242,13 +224,31 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
m_sampleSpace = sampleSpace;
}
- if (m_cachedSmoothSurface)
- m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer, dimensionChanged);
- else
- m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer, dimensionChanged);
+ // TODO: Handle partial surface grids on the graph edges
+ if (sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ m_dataArray.reserve(sampleSpace.height());
+ 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;
+ }
+
+ if (m_dataArray.size() > 0) {
+ if (!m_surfaceObj)
+ loadSurfaceObj();
- if (dimensionChanged)
- updateSelectionTexture();
+ // 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 (dimensionChanged)
+ updateSelectionTexture();
+ }
+ }
}
Abstract3DRenderer::updateDataModel(dataProxy);
@@ -256,19 +256,57 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
QRect Surface3DRenderer::calculateSampleRect(QSurfaceDataProxy *dataProxy)
{
- QRect sampleSpace(0, 0, dataProxy->columnCount(), dataProxy->rowCount());
-
- // TODO: Calculate the actual sample rect, for now it is required data and axis ranges are the same
-#if 0
- if (m_axisCacheX.min() != dataProxy->minValueColumns() || m_axisCacheX.max() != dataProxy->maxValueColumns()
- || m_axisCacheZ.min() != dataProxy->minValueRows() || m_axisCacheZ.max() != dataProxy->maxValueRows()) {
- qWarning() << "Warning: Technology preview doesn't support axis ranges that are different from data ranges -"
- << m_axisCacheX.min() << dataProxy->minValueColumns() << "-"
- << m_axisCacheX.max() << dataProxy->maxValueColumns() << "-"
- << m_axisCacheZ.min() << dataProxy->minValueRows() << "-"
- << m_axisCacheZ.max() << dataProxy->maxValueRows();
+ QRect sampleSpace;
+
+ m_minVisibleColumnValue = dataProxy->minValueColumns();
+ m_maxVisibleColumnValue = dataProxy->maxValueColumns();
+ m_minVisibleRowValue = dataProxy->minValueRows();
+ m_maxVisibleRowValue = dataProxy->maxValueRows();
+ m_dataStepX = (m_maxVisibleColumnValue - m_minVisibleColumnValue) / (dataProxy->columnCount() - 1);
+ m_dataStepZ = (m_maxVisibleRowValue - m_minVisibleRowValue) / (dataProxy->rowCount() - 1);
+
+ if (m_minVisibleColumnValue > m_axisCacheX.max() || m_maxVisibleColumnValue < m_axisCacheX.min()
+ || m_minVisibleRowValue > m_axisCacheZ.max() || m_maxVisibleRowValue < m_axisCacheZ.min()) {
+ sampleSpace.setWidth(-1); // to indicate nothing needs to be shown
}
-#endif
+
+ int index = 0;
+ while (m_minVisibleColumnValue < m_axisCacheX.min()) {
+ m_minVisibleColumnValue += m_dataStepX;
+ index++;
+ }
+ sampleSpace.setLeft(index);
+
+ index = dataProxy->columnCount() - 1;
+ while (m_maxVisibleColumnValue > m_axisCacheX.max()) {
+ m_maxVisibleColumnValue -= m_dataStepX;
+ index--;
+ }
+ sampleSpace.setRight(index);
+
+ index = 0;
+ while (m_minVisibleRowValue < m_axisCacheZ.min()) {
+ m_minVisibleRowValue += m_dataStepZ;
+ index++;
+ }
+ sampleSpace.setTop(index);
+
+ index = dataProxy->rowCount() - 1;
+ while (m_maxVisibleRowValue > m_axisCacheZ.max()) {
+ m_maxVisibleRowValue -= m_dataStepZ;
+ index--;
+ }
+ sampleSpace.setBottom(index);
+
+ m_surfaceScaleX = m_scaleX * (m_maxVisibleColumnValue - m_minVisibleColumnValue) / m_areaSize.width();
+ m_surfaceScaleZ = m_scaleZ * (m_maxVisibleRowValue - m_minVisibleRowValue) / m_areaSize.height();
+ GLfloat axis2XCenterX = (m_axisCacheX.min() + m_axisCacheX.max());
+ GLfloat axis2XCenterZ = (m_axisCacheZ.min() + m_axisCacheZ.max());
+ GLfloat data2XCenterX = (m_minVisibleColumnValue + m_maxVisibleColumnValue);
+ GLfloat data2XCenterZ = (m_minVisibleRowValue + m_maxVisibleRowValue);
+ m_surfaceOffsetX = m_scaleX * (data2XCenterX - axis2XCenterX) / m_areaSize.width();
+ m_surfaceOffsetZ = -m_scaleZ * (data2XCenterZ - axis2XCenterZ) / m_areaSize.height() + zComp;
+
return sampleSpace;
}
@@ -361,6 +399,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// Do the surface drawing
//
+ QVector3D surfaceScaler(m_surfaceScaleX, 1.0f, m_surfaceScaleZ);
+ QVector3D surfaceOffset(m_surfaceOffsetX, 0.0f, m_surfaceOffsetZ);
+
// Draw depth buffer
#if !defined(QT_OPENGL_ES_2)
if (m_cachedShadowQuality > QDataVis::ShadowNone && m_surfaceObj) {
@@ -405,8 +446,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
- modelMatrix.translate(0.0f, 0.0f, zComp);
- modelMatrix.scale(QVector3D(m_scaleX, 1.0f, m_scaleZ));
+ modelMatrix.translate(surfaceOffset);
+ modelMatrix.scale(surfaceScaler);
MVPMatrix = depthProjectionViewMatrix * modelMatrix;
@@ -469,7 +510,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glEnable(GL_TEXTURE_2D);
// Draw selection buffer
- if (m_querySelection && m_surfaceObj) {
+ if (m_querySelection && m_surfaceObj && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
m_selectionShader->bind();
glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
@@ -482,8 +523,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
- modelMatrix.translate(0.0f, 0.0f, zComp);
- modelMatrix.scale(QVector3D(m_scaleX, 1.0f, m_scaleZ));
+ modelMatrix.translate(surfaceOffset);
+ modelMatrix.scale(surfaceScaler);
MVPMatrix = projectionViewMatrix * modelMatrix;
@@ -516,8 +557,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glEnable(GL_CULL_FACE);
}
- // Draw surface
- if (m_surfaceObj) {
+ if (m_surfaceObj && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
m_surfaceShader->bind();
// m_selectionShader->bind(); // IFDEF print selection
@@ -529,9 +569,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
QMatrix4x4 depthMVPMatrix;
QMatrix4x4 itModelMatrix;
- modelMatrix.translate(0.0f, 0.0f, zComp);
- modelMatrix.scale(QVector3D(m_scaleX, 1.0f, m_scaleZ));
- itModelMatrix.scale(QVector3D(m_scaleX, 1.0f, m_scaleZ));
+ modelMatrix.translate(surfaceOffset);
+ modelMatrix.scale(surfaceScaler);
+ itModelMatrix.scale(surfaceScaler);
#ifdef SHOW_DEPTH_TEXTURE_SCENE
MVPMatrix = depthProjectionViewMatrix * modelMatrix;
@@ -1372,7 +1412,6 @@ void Surface3DRenderer::loadSurfaceObj()
if (m_surfaceObj)
delete m_surfaceObj;
m_surfaceObj = new SurfaceObject();
- //m_surfaceObj->setUpData();
}
void Surface3DRenderer::loadGridLineMesh()
@@ -1405,8 +1444,11 @@ void Surface3DRenderer::surfacePointSelected(int id)
if (!m_selectionPointer)
m_selectionPointer = new SelectionPointer(m_controller, m_drawer);
- m_selectionPointer->setPosition(normalize(float(column), value, float(row)));
- m_selectionPointer->setScaling(QVector3D(m_scaleX, 1.0f, m_scaleZ));
+ QVector3D pos(normalize(float(column), value, float(row)));
+ pos += QVector3D(m_surfaceOffsetX, 0.0f, m_surfaceOffsetZ - zComp);
+
+ m_selectionPointer->setPosition(pos);
+ m_selectionPointer->setScaling(QVector3D(m_surfaceScaleX, 1.0f, m_surfaceScaleZ));
m_selectionPointer->setLabel(createSelectionLabel(value, column, row));
m_selectionPointer->updateBoundingRect(m_mainViewPort);
m_selectionPointer->updateScene(m_cachedScene);
@@ -1457,19 +1499,13 @@ QString Surface3DRenderer::createSelectionLabel(qreal value, int column, int row
// Transforms the model column coordinate to axis coordinate
qreal Surface3DRenderer::columnInRange(int column)
{
- // At this point we'll work only with fixed grid and demand that the user uses proper steps on
- // value axis. Zero prevented when doing duplicate from the data.
- qreal stepInRange = (m_axisCacheX.max() - m_axisCacheX.min()) / qreal(m_dataArray.at(0)->size() - 1);
- return stepInRange * qreal(column) + m_axisCacheX.min();
+ return m_dataStepX * qreal(column) + m_minVisibleColumnValue;
}
// Transforms the model row coordinate to axis coordinate
qreal Surface3DRenderer::rowInRange(int row)
{
- // At this point we'll work only with fixed grid and demand that the user uses proper steps on
- // value axis. Zero prevented when doing duplicate from the data.
- qreal stepInRange = (m_axisCacheZ.max() - m_axisCacheZ.min()) / qreal(m_dataArray.size() - 1);
- return stepInRange * qreal(row) + m_axisCacheZ.min();
+ return m_dataStepZ * qreal(row) + m_minVisibleRowValue;
}
QVector3D Surface3DRenderer::normalize(float x, float y, float z)
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index b612cd34..c209e454 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -89,6 +89,16 @@ private:
GLfloat m_scaleZ;
GLfloat m_scaleXWithBackground;
GLfloat m_scaleZWithBackground;
+ GLfloat m_surfaceScaleX;
+ GLfloat m_surfaceScaleZ;
+ GLfloat m_surfaceOffsetX;
+ GLfloat m_surfaceOffsetZ;
+ qreal m_minVisibleColumnValue;
+ qreal m_maxVisibleColumnValue;
+ qreal m_minVisibleRowValue;
+ qreal m_maxVisibleRowValue;
+ qreal m_dataStepX;
+ qreal m_dataStepZ;
ObjectHelper *m_backgroundObj;
ObjectHelper *m_gridLineObj;
ObjectHelper *m_labelObj;
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index a0ed292a..d28ad447 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -29,13 +29,14 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
SurfaceObject::SurfaceObject()
{
m_indicesType = GL_UNSIGNED_INT;
+ initializeOpenGLFunctions();
}
SurfaceObject::~SurfaceObject()
{
}
-void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, QRect space, GLfloat yRange, bool changeGeometry)
+void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, bool changeGeometry)
{
int columns = space.width();
int rows = space.height();
@@ -129,7 +130,7 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, QRect sp
}
-void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, QRect space, GLfloat yRange, bool changeGeometry)
+void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, bool changeGeometry)
{
int columns = space.width();
int rows = space.height();
@@ -226,7 +227,6 @@ void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVec
const QVector<QVector3D> &normals, const GLint *indices,
const GLint *gridIndices, bool changeGeometry)
{
- initializeOpenGLFunctions();
if (m_meshDataLoaded) {
// Delete old data
glDeleteBuffers(1, &m_vertexbuffer);
diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index e9057f88..f19fffc0 100644
--- a/src/datavisualization/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -44,8 +44,8 @@ public:
SurfaceObject();
~SurfaceObject();
- void setUpData(const QSurfaceDataArray &dataArray, QRect space, GLfloat yRange, bool changeGeometry);
- void setUpSmoothData(const QSurfaceDataArray &dataArray, QRect space, GLfloat yRange, bool changeGeometry);
+ void setUpData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, bool changeGeometry);
+ void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, bool changeGeometry);
GLuint gridElementBuf();
GLuint gridIndexCount();