diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-23 13:57:47 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-24 09:50:51 +0300 |
commit | f842e21c7fa44d806c06a1463c723632b10e6172 (patch) | |
tree | 544b03ec20521c203a884cf74809972410532730 /src/datavisualization/data/qheightmapsurfacedataproxy.cpp | |
parent | ac789c99ad04e5e907365d408d5f94df1685a668 (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/data/qheightmapsurfacedataproxy.cpp')
-rw-r--r-- | src/datavisualization/data/qheightmapsurfacedataproxy.cpp | 101 |
1 files changed, 56 insertions, 45 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 |