summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization/data/qheightmapsurfacedataproxy.cpp')
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp101
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