Skip to content

Commit 458eb50

Browse files
committed
Mandelbrot sample changes to use Thinker-Qt. (Submitted in a single diff for easy review on gitorious)
1 parent ae5205f commit 458eb50

File tree

5 files changed

+133
-133
lines changed

5 files changed

+133
-133
lines changed

examples/mandelbrot/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -4,7 +4,7 @@
4
** All rights reserved.
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
6
**
7-
** This file is part of the examples of the Qt Toolkit.
7+
** Modified 2010 by HostileFork to use http://hostilefork.com/thinker-qt/
8
**
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
9
** $QT_BEGIN_LICENSE:LGPL$
10
** No Commercial Usage
10
** No Commercial Usage
@@ -42,4 +42,4 @@ int main(int argc, char *argv[])
42
MandelbrotWidget widget;
42
MandelbrotWidget widget;
43
widget.show();
43
widget.show();
44
return app.exec();
44
return app.exec();
45-
}
45+
}

examples/mandelbrot/mandelbrotwidget.cpp

Lines changed: 72 additions & 14 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -4,7 +4,7 @@
4
** All rights reserved.
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
6
**
7-
** This file is part of the examples of the Qt Toolkit.
7+
** Modified 2010 by HostileFork to use http://hostilefork.com/thinker-qt/
8
**
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
9
** $QT_BEGIN_LICENSE:LGPL$
10
** No Commercial Usage
10
** No Commercial Usage
@@ -54,9 +54,11 @@ MandelbrotWidget::MandelbrotWidget(QWidget *parent)
54
pixmapScale = DefaultScale;
54
pixmapScale = DefaultScale;
55
curScale = DefaultScale;
55
curScale = DefaultScale;
56

56

57-
qRegisterMetaType<QImage>("QImage");
57+
for (int i = 0; i < ColormapSize; ++i)
58-
connect(&thread, SIGNAL(renderedImage(const QImage &, double)),
58+
colormap[i] = rgbFromWaveLength(380.0 + (i * 400.0 / ColormapSize));
59-
this, SLOT(updatePixmap(const QImage &, double)));
59+
60+
connect(&watcher, SIGNAL(written()), this, SLOT(updatePixmap()));
61+
watcher.setThrottleTime(400);
60

62

61
setWindowTitle(tr("Mandelbrot"));
63
setWindowTitle(tr("Mandelbrot"));
62
#ifndef QT_NO_CURSOR
64
#ifndef QT_NO_CURSOR
@@ -65,6 +67,21 @@ MandelbrotWidget::MandelbrotWidget(QWidget *parent)
65
resize(550, 400);
67
resize(550, 400);
66
}
68
}
67

69

70+
MandelbrotWidget::~MandelbrotWidget()
71+
{
72+
watcher.cancel();
73+
}
74+
75+
void MandelbrotWidget::resetThinker(double centerX, double centerY,
76+
double scaleFactor, QSize resultSize)
77+
{
78+
watcher.cancel();
79+
80+
RenderThinker* thinker = new RenderThinker(centerX, centerY,
81+
scaleFactor, resultSize, colormap);
82+
watcher.setPresent(ThinkerQt::run(thinker));
83+
}
84+
68
void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
85
void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
69
{
86
{
70
QPainter painter(this);
87
QPainter painter(this);
@@ -110,7 +127,7 @@ void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
110

127

111
void MandelbrotWidget::resizeEvent(QResizeEvent * /* event */)
128
void MandelbrotWidget::resizeEvent(QResizeEvent * /* event */)
112
{
129
{
113-
thread.render(centerX, centerY, curScale, size());
130+
resetThinker(centerX, centerY, curScale, size());
114
}
131
}
115

132

116
void MandelbrotWidget::keyPressEvent(QKeyEvent *event)
133
void MandelbrotWidget::keyPressEvent(QKeyEvent *event)
@@ -173,29 +190,70 @@ void MandelbrotWidget::mouseReleaseEvent(QMouseEvent *event)
173
}
190
}
174
}
191
}
175

192

176-
void MandelbrotWidget::updatePixmap(const QImage &image, double scaleFactor)
193+
void MandelbrotWidget::updatePixmap()
177
{
194
{
178
if (!lastDragPos.isNull())
195
if (!lastDragPos.isNull())
179
return;
196
return;
180

197

181-
pixmap = QPixmap::fromImage(image);
198+
RenderThinker::SnapshotPointer snap = watcher.createSnapshot();
182-
pixmapOffset = QPoint();
199+
if (snap->hasImage()) {
183-
lastDragPos = QPoint();
200+
pixmap = QPixmap::fromImage(snap->getImage());
184-
pixmapScale = scaleFactor;
201+
pixmapScale = snap->getScaleFactor();
185-
update();
202+
snap.clear();
203+
pixmapOffset = QPoint();
204+
lastDragPos = QPoint();
205+
update();
206+
}
186
}
207
}
187

208

188
void MandelbrotWidget::zoom(double zoomFactor)
209
void MandelbrotWidget::zoom(double zoomFactor)
189
{
210
{
190
curScale *= zoomFactor;
211
curScale *= zoomFactor;
191
update();
212
update();
192-
thread.render(centerX, centerY, curScale, size());
213+
resetThinker(centerX, centerY, curScale, size());
193
}
214
}
194

215

195
void MandelbrotWidget::scroll(int deltaX, int deltaY)
216
void MandelbrotWidget::scroll(int deltaX, int deltaY)
196
{
217
{
197
centerX += deltaX * curScale;
218
centerX += deltaX * curScale;
198
centerY += deltaY * curScale;
219
centerY += deltaY * curScale;
199
update();
220
update();
200-
thread.render(centerX, centerY, curScale, size());
221+
resetThinker(centerX, centerY, curScale, size());
201-
}
222+
}
223+
224+
uint MandelbrotWidget::rgbFromWaveLength(double wave)
225+
{
226+
double r = 0.0;
227+
double g = 0.0;
228+
double b = 0.0;
229+
230+
if (wave >= 380.0 && wave <= 440.0) {
231+
r = -1.0 * (wave - 440.0) / (440.0 - 380.0);
232+
b = 1.0;
233+
} else if (wave >= 440.0 && wave <= 490.0) {
234+
g = (wave - 440.0) / (490.0 - 440.0);
235+
b = 1.0;
236+
} else if (wave >= 490.0 && wave <= 510.0) {
237+
g = 1.0;
238+
b = -1.0 * (wave - 510.0) / (510.0 - 490.0);
239+
} else if (wave >= 510.0 && wave <= 580.0) {
240+
r = (wave - 510.0) / (580.0 - 510.0);
241+
g = 1.0;
242+
} else if (wave >= 580.0 && wave <= 645.0) {
243+
r = 1.0;
244+
g = -1.0 * (wave - 645.0) / (645.0 - 580.0);
245+
} else if (wave >= 645.0 && wave <= 780.0) {
246+
r = 1.0;
247+
}
248+
249+
double s = 1.0;
250+
if (wave > 700.0)
251+
s = 0.3 + 0.7 * (780.0 - wave) / (780.0 - 700.0);
252+
else if (wave < 420.0)
253+
s = 0.3 + 0.7 * (wave - 380.0) / (420.0 - 380.0);
254+
255+
r = pow(r * s, 0.8);
256+
g = pow(g * s, 0.8);
257+
b = pow(b * s, 0.8);
258+
return qRgb(int(r * 255), int(g * 255), int(b * 255));
259+
}

examples/mandelbrot/mandelbrotwidget.h

Lines changed: 10 additions & 3 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -4,7 +4,7 @@
4
** All rights reserved.
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
6
**
7-
** This file is part of the examples of the Qt Toolkit.
7+
** Modified 2010 by HostileFork to use http://hostilefork.com/thinker-qt/
8
**
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
9
** $QT_BEGIN_LICENSE:LGPL$
10
** No Commercial Usage
10
** No Commercial Usage
@@ -37,6 +37,7 @@
37

37

38
#include <QPixmap>
38
#include <QPixmap>
39
#include <QWidget>
39
#include <QWidget>
40+
#include "thinkerqt/thinkerqt.h"
40

41

41
#include "renderthread.h"
42
#include "renderthread.h"
42

43

@@ -46,6 +47,7 @@ class MandelbrotWidget : public QWidget
46

47

47
public:
48
public:
48
MandelbrotWidget(QWidget *parent = 0);
49
MandelbrotWidget(QWidget *parent = 0);
50+
~MandelbrotWidget();
49

51

50
protected:
52
protected:
51
void paintEvent(QPaintEvent *event);
53
void paintEvent(QPaintEvent *event);
@@ -57,20 +59,25 @@ class MandelbrotWidget : public QWidget
57
void mouseReleaseEvent(QMouseEvent *event);
59
void mouseReleaseEvent(QMouseEvent *event);
58

60

59
private slots:
61
private slots:
60-
void updatePixmap(const QImage &image, double scaleFactor);
62+
void updatePixmap(); /* makes snapshot to get image & scaleFactor */
61

63

62
private:
64
private:
63
void zoom(double zoomFactor);
65
void zoom(double zoomFactor);
64
void scroll(int deltaX, int deltaY);
66
void scroll(int deltaX, int deltaY);
67+
uint rgbFromWaveLength(double wave);
68+
69+
RenderThinker::PresentWatcher watcher;
70+
void resetThinker(double centerX, double centerY, double scaleFactor,
71+
QSize resultSize);
65

72

66-
RenderThread thread;
67
QPixmap pixmap;
73
QPixmap pixmap;
68
QPoint pixmapOffset;
74
QPoint pixmapOffset;
69
QPoint lastDragPos;
75
QPoint lastDragPos;
70
double centerX;
76
double centerX;
71
double centerY;
77
double centerY;
72
double pixmapScale;
78
double pixmapScale;
73
double curScale;
79
double curScale;
80+
Colormap colormap;
74
};
81
};
75

82

76
#endif
83
#endif

examples/mandelbrot/renderthread.cpp

Lines changed: 15 additions & 94 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -4,7 +4,7 @@
4
** All rights reserved.
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
6
**
7-
** This file is part of the examples of the Qt Toolkit.
7+
** Modified 2010 by HostileFork to use http://hostilefork.com/thinker-qt/
8
**
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
9
** $QT_BEGIN_LICENSE:LGPL$
10
** No Commercial Usage
10
** No Commercial Usage
@@ -38,54 +38,18 @@
38

38

39
#include "renderthread.h"
39
#include "renderthread.h"
40

40

41-
RenderThread::RenderThread(QObject *parent)
41+
RenderThinker::RenderThinker(double centerX, double centerY, double scaleFactor,
42-
: QThread(parent)
42+
QSize resultSize, const Colormap& colormap)
43+
: centerX (centerX),
44+
centerY (centerY),
45+
scaleFactor (scaleFactor),
46+
resultSize (resultSize),
47+
colormap (colormap)
43
{
48
{
44-
restart = false;
45-
abort = false;
46-
47-
for (int i = 0; i < ColormapSize; ++i)
48-
colormap[i] = rgbFromWaveLength(380.0 + (i * 400.0 / ColormapSize));
49-
}
50-
51-
RenderThread::~RenderThread()
52-
{
53-
mutex.lock();
54-
abort = true;
55-
condition.wakeOne();
56-
mutex.unlock();
57-
58-
wait();
59
}
49
}
60

50

61-
void RenderThread::render(double centerX, double centerY, double scaleFactor,
51+
void RenderThinker::start()
62-
QSize resultSize)
63
{
52
{
64-
QMutexLocker locker(&mutex);
65-
66-
this->centerX = centerX;
67-
this->centerY = centerY;
68-
this->scaleFactor = scaleFactor;
69-
this->resultSize = resultSize;
70-
71-
if (!isRunning()) {
72-
start(LowPriority);
73-
} else {
74-
restart = true;
75-
condition.wakeOne();
76-
}
77-
}
78-
79-
void RenderThread::run()
80-
{
81-
forever {
82-
mutex.lock();
83-
QSize resultSize = this->resultSize;
84-
double scaleFactor = this->scaleFactor;
85-
double centerX = this->centerX;
86-
double centerY = this->centerY;
87-
mutex.unlock();
88-
89
int halfWidth = resultSize.width() / 2;
53
int halfWidth = resultSize.width() / 2;
90
int halfHeight = resultSize.height() / 2;
54
int halfHeight = resultSize.height() / 2;
91
QImage image(resultSize, QImage::Format_RGB32);
55
QImage image(resultSize, QImage::Format_RGB32);
@@ -98,9 +62,7 @@ void RenderThread::run()
98
bool allBlack = true;
62
bool allBlack = true;
99

63

100
for (int y = -halfHeight; y < halfHeight; ++y) {
64
for (int y = -halfHeight; y < halfHeight; ++y) {
101-
if (restart)
65+
if (wasPauseRequested())
102-
break;
103-
if (abort)
104
return;
66
return;
105

67

106
uint *scanLine =
68
uint *scanLine =
@@ -139,53 +101,12 @@ void RenderThread::run()
139
if (allBlack && pass == 0) {
101
if (allBlack && pass == 0) {
140
pass = 4;
102
pass = 4;
141
} else {
103
} else {
142-
if (!restart)
104+
lockForWrite();
143-
emit renderedImage(image, scaleFactor);
105+
writable().image = image;
106+
writable().scaleFactor = scaleFactor;
107+
unlock();
144
++pass;
108
++pass;
145
}
109
}
146
}
110
}
147-
111+
emit done();
148-
mutex.lock();
149-
if (!restart)
150-
condition.wait(&mutex);
151-
restart = false;
152-
mutex.unlock();
153-
}
154
}
112
}
155-
156-
uint RenderThread::rgbFromWaveLength(double wave)
157-
{
158-
double r = 0.0;
159-
double g = 0.0;
160-
double b = 0.0;
161-
162-
if (wave >= 380.0 && wave <= 440.0) {
163-
r = -1.0 * (wave - 440.0) / (440.0 - 380.0);
164-
b = 1.0;
165-
} else if (wave >= 440.0 && wave <= 490.0) {
166-
g = (wave - 440.0) / (490.0 - 440.0);
167-
b = 1.0;
168-
} else if (wave >= 490.0 && wave <= 510.0) {
169-
g = 1.0;
170-
b = -1.0 * (wave - 510.0) / (510.0 - 490.0);
171-
} else if (wave >= 510.0 && wave <= 580.0) {
172-
r = (wave - 510.0) / (580.0 - 510.0);
173-
g = 1.0;
174-
} else if (wave >= 580.0 && wave <= 645.0) {
175-
r = 1.0;
176-
g = -1.0 * (wave - 645.0) / (645.0 - 580.0);
177-
} else if (wave >= 645.0 && wave <= 780.0) {
178-
r = 1.0;
179-
}
180-
181-
double s = 1.0;
182-
if (wave > 700.0)
183-
s = 0.3 + 0.7 * (780.0 - wave) / (780.0 - 700.0);
184-
else if (wave < 420.0)
185-
s = 0.3 + 0.7 * (wave - 380.0) / (420.0 - 380.0);
186-
187-
r = pow(r * s, 0.8);
188-
g = pow(g * s, 0.8);
189-
b = pow(b * s, 0.8);
190-
return qRgb(int(r * 255), int(g * 255), int(b * 255));
191-
}

0 commit comments

Comments
 (0)