summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorRhys Weatherley <rhys.weatherley@nokia.com>2010-02-15 08:22:46 +1000
committerRhys Weatherley <rhys.weatherley@nokia.com>2010-02-15 09:23:15 +1000
commitbfaac138e3278b1d9ab998ce68ee7f48b8723b84 (patch)
tree5f35d7b67f5fe136c614bf5715dea29ad17ac462 /examples
parent7406cd34b6b2ef17b2d6c232779b9e7750599197 (diff)
Add a Mandelbrot viewer example for the OpenCL library.
Diffstat (limited to 'examples')
-rw-r--r--examples/opencl/mandelbrot/image.cpp98
-rw-r--r--examples/opencl/mandelbrot/image.h87
-rw-r--r--examples/opencl/mandelbrot/imagecl.cpp147
-rw-r--r--examples/opencl/mandelbrot/imagecl.h68
-rw-r--r--examples/opencl/mandelbrot/imagenative.cpp147
-rw-r--r--examples/opencl/mandelbrot/imagenative.h64
-rw-r--r--examples/opencl/mandelbrot/main.cpp52
-rw-r--r--examples/opencl/mandelbrot/mandelbrot.cl100
-rw-r--r--examples/opencl/mandelbrot/mandelbrot.pro25
-rw-r--r--examples/opencl/mandelbrot/mandelbrot.qrc5
-rw-r--r--examples/opencl/mandelbrot/palette.cpp156
-rw-r--r--examples/opencl/mandelbrot/palette.h90
-rw-r--r--examples/opencl/mandelbrot/view.cpp101
-rw-r--r--examples/opencl/mandelbrot/view.h70
-rw-r--r--examples/opencl/opencl.pro2
15 files changed, 1211 insertions, 1 deletions
diff --git a/examples/opencl/mandelbrot/image.cpp b/examples/opencl/mandelbrot/image.cpp
new file mode 100644
index 0000000..9483f30
--- /dev/null
+++ b/examples/opencl/mandelbrot/image.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "image.h"
+#include "imagenative.h"
+#include "imagecl.h"
+#include "palette.h"
+#include <QtCore/qdatetime.h>
+#include <QtCore/qdebug.h>
+
+Image::Image(int width, int height)
+ : img(width, height, QImage::Format_RGB32)
+ , regionChanged(true)
+ , lastIterations(-1)
+{
+ setRegion(-0.7f, 0.0f, 3.0769f);
+}
+
+Image::~Image()
+{
+}
+
+// Set a region based on its center and diameter in the x direction.
+void Image::setRegion(qreal centerx, qreal centery, qreal diameterx)
+{
+ qreal diametery = diameterx * img.height() / img.width();
+ rgn = QRectF(centerx - diameterx * 0.5f,
+ centery - diametery * 0.5f,
+ diameterx, diametery);
+ regionChanged = true;
+}
+
+Image *Image::createImage(int width, int height)
+{
+ if (ImageCL::hasOpenCL())
+ return new ImageCL(width, height);
+ else
+ return new ImageNative(width, height);
+}
+
+void Image::generate(int maxIterations, const Palette& palette)
+{
+ Q_ASSERT(maxIterations <= 65535);
+
+ // If the parameters have changed, then regenerate the index data.
+ if (regionChanged || maxIterations != lastIterations) {
+ QTime time;
+ time.start();
+ generateIterationData(maxIterations, rgn);
+ regionChanged = false;
+ lastIterations = maxIterations;
+ qDebug() << "Mandelbrot:" << rgn
+ << "iterations =" << maxIterations
+ << "elapsed =" << time.elapsed() << "ms";
+ }
+
+ // Colorize the index data to create the final image.
+ QVector<QRgb> colors = palette.createTable(maxIterations);
+ generateImage(&img, maxIterations, colors.constData());
+}
diff --git a/examples/opencl/mandelbrot/image.h b/examples/opencl/mandelbrot/image.h
new file mode 100644
index 0000000..546c9bc
--- /dev/null
+++ b/examples/opencl/mandelbrot/image.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include <QtGui/qimage.h>
+#include <QtCore/qmetatype.h>
+
+class Palette;
+
+class Image
+{
+public:
+ Image(int width, int height);
+ virtual ~Image();
+
+ // QMetaType::Float for 32-bit IEEE precision.
+ // QMetaType::Double for 64-bit IEEE precision.
+ // QMetaType::User for arbitrary precision.
+ virtual QMetaType::Type precision() const = 0;
+
+ QImage image() const { return img; }
+
+ QRectF region() const { return rgn; }
+ void setRegion(const QRectF& value)
+ { rgn = value; regionChanged = true; }
+ void setRegion(qreal centerx, qreal centery, qreal diameterx);
+
+ void forceUpdate() { regionChanged = true; }
+
+ void generate(int maxIterations, const Palette& palette);
+
+ static Image *createImage(int width, int height);
+
+protected:
+ virtual void generateIterationData
+ (int maxIterations, const QRectF& region) = 0;
+ virtual void generateImage
+ (QImage *image, int maxIterations, const QRgb *colors) = 0;
+
+private:
+ QImage img;
+ QRectF rgn;
+ bool regionChanged;
+ int lastIterations;
+};
+
+#endif
diff --git a/examples/opencl/mandelbrot/imagecl.cpp b/examples/opencl/mandelbrot/imagecl.cpp
new file mode 100644
index 0000000..b55981f
--- /dev/null
+++ b/examples/opencl/mandelbrot/imagecl.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "imagecl.h"
+#include <QtCore/qvarlengtharray.h>
+#include <QtGui/qcolor.h>
+
+class ImageCLContext
+{
+public:
+ ImageCLContext();
+ ~ImageCLContext();
+
+ QCLContext *context;
+ QCLProgram program;
+ QCLKernel mandelbrot;
+ QCLKernel colorize;
+};
+
+ImageCLContext::ImageCLContext()
+{
+ context = new QCLContext();
+ if (!context->create())
+ return;
+
+ program = context->buildProgramFromSourceFile
+ (QLatin1String(":/mandelbrot.cl"));
+ mandelbrot = program.createKernel("mandelbrot");
+ colorize = program.createKernel("colorize");
+}
+
+ImageCLContext::~ImageCLContext()
+{
+ delete context;
+}
+
+Q_GLOBAL_STATIC(ImageCLContext, image_context)
+
+ImageCL::ImageCL(int width, int height)
+ : Image(width, height)
+ , wid(width), ht(height)
+{
+ // Create an OpenCL buffer to hold the raw iteration count data.
+ // The buffer lives on the OpenCL device and does not need to
+ // be accessed by the host.
+ ImageCLContext *ctx = image_context();
+ data = ctx->context->createBufferDevice
+ (width * height * sizeof(uint), QCLBuffer::ReadWrite);
+}
+
+ImageCL::~ImageCL()
+{
+}
+
+QMetaType::Type ImageCL::precision() const
+{
+ return QMetaType::Float;
+}
+
+bool ImageCL::hasOpenCL()
+{
+ ImageCLContext *ctx = image_context();
+ return ctx->context->isCreated();
+}
+
+void ImageCL::generateIterationData
+ (int maxIterations, const QRectF& region)
+{
+ ImageCLContext *ctx = image_context();
+ QCLKernel mandelbrot = ctx->mandelbrot;
+
+ mandelbrot.setGlobalWorkSize(QCLWorkSize(wid, ht));
+ QCLEvent event = mandelbrot
+ (data, float(region.x()), float(region.y()),
+ float(region.width()), float(region.height()),
+ wid, ht, maxIterations);
+ event.wait();
+}
+
+void ImageCL::generateImage
+ (QImage *image, int maxIterations, const QRgb *colors)
+{
+ ImageCLContext *ctx = image_context();
+ QCLKernel colorize = ctx->colorize;
+
+ // Upload the color table into a buffer in the device.
+ QCLBuffer colorBuffer = ctx->context->createBufferDevice
+ (maxIterations * sizeof(float) * 4, QCLBuffer::ReadOnly);
+ QVarLengthArray<float> floatColors;
+ for (int index = 0; index < maxIterations; ++index) {
+ QColor color(colors[index]);
+ floatColors.append(float(color.redF()));
+ floatColors.append(float(color.greenF()));
+ floatColors.append(float(color.blueF()));
+ floatColors.append(float(color.alphaF()));
+ }
+ colorBuffer.write(0, floatColors.constData(),
+ maxIterations * sizeof(float) * 4);
+
+ // Map the image so that both the device and the host can access it.
+ QCLImage2D imageBuffer = ctx->context->createImage2DHost
+ (image, QCLBuffer::WriteOnly);
+
+ // Execute the "colorize" kernel.
+ colorize.setGlobalWorkSize(QCLWorkSize(wid, ht));
+ QCLEvent event = colorize
+ (data, imageBuffer, colorBuffer, wid, maxIterations);
+ event.wait();
+}
diff --git a/examples/opencl/mandelbrot/imagecl.h b/examples/opencl/mandelbrot/imagecl.h
new file mode 100644
index 0000000..78adf1e
--- /dev/null
+++ b/examples/opencl/mandelbrot/imagecl.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef IMAGECL_H
+#define IMAGECL_H
+
+#include "image.h"
+#include "qclcontext.h"
+
+class ImageCL : public Image
+{
+public:
+ ImageCL(int width, int height);
+ virtual ~ImageCL();
+
+ virtual QMetaType::Type precision() const;
+
+ static bool hasOpenCL();
+
+protected:
+ int wid, ht;
+ QCLBuffer data;
+
+ void generateIterationData
+ (int maxIterations, const QRectF& region);
+ void generateImage
+ (QImage *image, int maxIterations, const QRgb *colors);
+};
+
+#endif
diff --git a/examples/opencl/mandelbrot/imagenative.cpp b/examples/opencl/mandelbrot/imagenative.cpp
new file mode 100644
index 0000000..524d695
--- /dev/null
+++ b/examples/opencl/mandelbrot/imagenative.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "imagenative.h"
+#include <QtCore/qmath.h>
+
+// Define the floating-point precision to use for calculations.
+//typedef double mreal;
+typedef float mreal;
+
+ImageNative::ImageNative(int width, int height)
+ : Image(width, height)
+ , data(width, height, QImage::Format_RGB32)
+{
+}
+
+ImageNative::~ImageNative()
+{
+}
+
+// QMetaType::Float for 32-bit IEEE precision.
+// QMetaType::Double for 64-bit IEEE precision.
+// QMetaType::User for arbitrary precision.
+QMetaType::Type ImageNative::precision() const
+{
+ if (sizeof(mreal) == sizeof(float))
+ return QMetaType::Float;
+ else
+ return QMetaType::Double;
+}
+
+// Algorithm from: http://en.wikipedia.org/wiki/Mandelbrot_set
+// This generates uint values for each pixel. The top 16 bits
+// contain the iteration count, and the bottom 16 bits contains
+// an interpolation value for creating gradients between colors.
+void ImageNative::generateIterationData
+ (int maxIterations, const QRectF& region)
+{
+ int width = data.width();
+ int height = data.height();
+ mreal xstep = region.width() / width;
+ mreal ystep = region.height() / height;
+ mreal yin = region.y();
+ uint *line = reinterpret_cast<uint *>(data.bits());
+ int stride = data.bytesPerLine() / sizeof(uint);
+ line += stride * (height - 1); // flip y axis so y = 1 is at top.
+ mreal loglogb = log(log(2.0));
+ mreal invlog2 = 1.0 / log(2.0);
+ for (int ypos = 0; ypos < height; ++ypos, yin += ystep) {
+ mreal xin = region.x();
+ for (int xpos = 0; xpos < width; ++xpos, xin += xstep) {
+ // Find the color to use with the "escape time" algorithm.
+ int iteration = 0;
+ mreal x = 0;
+ mreal y = 0;
+ while (iteration < maxIterations) {
+ mreal x2 = x * x;
+ mreal y2 = y * y;
+ if ((x2 + y2) > (2.0f * 2.0f))
+ break;
+ mreal xtemp = x2 - y2 + xin;
+ y = 2 * x * y + yin;
+ x = xtemp;
+ ++iteration;
+ }
+ if (iteration < (maxIterations - 1)) {
+ // Use the Normalized Iteration Count Algorithm
+ // to compute an interpolation value between two
+ // adjacent colors for a continuous tone image.
+ // From: http://math.unipa.it/~grim/Jbarrallo.PDF
+ mreal v = (loglogb - log(log(sqrt(x * x + y * y)))) * invlog2;
+ int fraction = int(v * 65535.0f);
+ line[xpos] = (iteration << 16) + fraction;
+ } else {
+ line[xpos] = (iteration << 16);
+ }
+ }
+ line -= stride;
+ }
+}
+
+void ImageNative::generateImage
+ (QImage *image, int maxIterations, const QRgb *colors)
+{
+ QRgb *dst = reinterpret_cast<uint *>(image->bits());
+ const uint *src = reinterpret_cast<uint *>(data.bits());
+ uint count = image->width() * image->height();
+ while (count-- > 0) {
+ int iteration = (src[0] >> 16);
+ if (iteration < (maxIterations - 1)) {
+ qreal v = (src[0] & 0xFFFF) / 65535.0f;
+ QRgb color1 = colors[iteration];
+ QRgb color2 = colors[iteration + 1];
+ int red = int((qRed(color2) - qRed(color1)) * v) +
+ qRed(color1);
+ int green = int((qGreen(color2) - qGreen(color1)) * v) +
+ qGreen(color1);
+ int blue = int((qBlue(color2) - qBlue(color1)) * v) +
+ qBlue(color1);
+ dst[0] = qRgb(red, green, blue);
+ } else if (iteration < maxIterations) {
+ dst[0] = colors[iteration];
+ } else {
+ dst[0] = qRgb(0, 0, 0);
+ }
+ ++src;
+ ++dst;
+ }
+}
diff --git a/examples/opencl/mandelbrot/imagenative.h b/examples/opencl/mandelbrot/imagenative.h
new file mode 100644
index 0000000..59dd3d4
--- /dev/null
+++ b/examples/opencl/mandelbrot/imagenative.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef IMAGENATIVE_H
+#define IMAGENATIVE_H
+
+#include "image.h"
+
+class ImageNative : public Image
+{
+public:
+ ImageNative(int width, int height);
+ virtual ~ImageNative();
+
+ virtual QMetaType::Type precision() const;
+
+protected:
+ QImage data;
+
+ void generateIterationData
+ (int maxIterations, const QRectF& region);
+ void generateImage
+ (QImage *image, int maxIterations, const QRgb *colors);
+};
+
+#endif
diff --git a/examples/opencl/mandelbrot/main.cpp b/examples/opencl/mandelbrot/main.cpp
new file mode 100644
index 0000000..fc557bd
--- /dev/null
+++ b/examples/opencl/mandelbrot/main.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QDebug>
+#include "view.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ View view;
+ view.show();
+ return app.exec();
+}
diff --git a/examples/opencl/mandelbrot/mandelbrot.cl b/examples/opencl/mandelbrot/mandelbrot.cl
new file mode 100644
index 0000000..4c43b17
--- /dev/null
+++ b/examples/opencl/mandelbrot/mandelbrot.cl
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+__kernel void mandelbrot(__global __write_only int *data,
+ const float regionx, const float regiony,
+ const float regionwidth, const float regionheight,
+ const int pixelwidth, const int pixelheight,
+ const int maxIterations)
+{
+ int xpixel = get_global_id(0);
+ int ypixel = get_global_id(1);
+ float xin = regionx + xpixel * regionwidth / pixelwidth;
+ float yin = regiony + ypixel * regionheight / pixelheight;
+ int iteration = 0;
+ float x = 0;
+ float y = 0;
+ while (iteration < maxIterations) {
+ float x2 = x * x;
+ float y2 = y * y;
+ if ((x2 + y2) > 4.0)
+ break;
+ float xtemp = x2 - y2 + xin;
+ y = 2 * x * y + yin;
+ x = xtemp;
+ ++iteration;
+ }
+ int pos = ypixel * pixelwidth + xpixel;
+ if (iteration < (maxIterations - 1)) {
+ // Use the Normalized Iteration Count Algorithm
+ // to compute an interpolation value between two
+ // adjacent colors for a continuous tone image.
+ // From: http://math.unipa.it/~grim/Jbarrallo.PDF
+ const float loglogb = log(log(2.0f));
+ const float invlog2 = 1.0f / log(2.0f);
+ float v = (loglogb - log(log(sqrt(x * x + y * y)))) * invlog2;
+ int fraction = (int)(v * 65535.0f);
+ data[pos] = (iteration << 16) + fraction;
+ } else {
+ data[pos] = (iteration << 16);
+ }
+}
+
+__kernel void colorize(__global __read_only int *data,
+ __write_only image2d_t image,
+ __global __read_only float4 *colors,
+ const int pixelwidth,
+ const int maxIterations)
+{
+ int xpixel = get_global_id(0);
+ int ypixel = get_global_id(1);
+ int pos = ypixel * pixelwidth + xpixel;
+ int iteration = (data[pos] >> 16);
+ if (iteration < (maxIterations - 1)) {
+ float v = (data[pos] & 0xFFFF) / 65535.0f;
+ float4 color = mix(colors[iteration], colors[iteration + 1], v);
+ write_imagef(image, (int2)(xpixel, ypixel), color);
+ } else if (iteration < maxIterations) {
+ write_imagef(image, (int2)(xpixel, ypixel), colors[iteration]);
+ } else {
+ write_imagef(image, (int2)(xpixel, ypixel), (float4)(0, 0, 0, 1));
+ }
+}
diff --git a/examples/opencl/mandelbrot/mandelbrot.pro b/examples/opencl/mandelbrot/mandelbrot.pro
new file mode 100644
index 0000000..91a0a52
--- /dev/null
+++ b/examples/opencl/mandelbrot/mandelbrot.pro
@@ -0,0 +1,25 @@
+######################################################################
+# Automatically generated by qmake (2.01a) Sat Feb 13 10:16:42 2010
+######################################################################
+
+TEMPLATE = app
+TARGET = mandelbrot
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += main.cpp \
+ palette.cpp \
+ image.cpp \
+ imagecl.cpp \
+ imagenative.cpp \
+ view.cpp
+HEADERS += palette.h \
+ image.h \
+ imagecl.h \
+ imagenative.h \
+ view.h
+RESOURCES += mandelbrot.qrc
+
+LIBS += -L../../../lib -L../../../bin
+include(../../../src/opencl/opencl_dep.pri)
diff --git a/examples/opencl/mandelbrot/mandelbrot.qrc b/examples/opencl/mandelbrot/mandelbrot.qrc
new file mode 100644
index 0000000..e9d7ab1
--- /dev/null
+++ b/examples/opencl/mandelbrot/mandelbrot.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>mandelbrot.cl</file>
+</qresource>
+</RCC>
diff --git a/examples/opencl/mandelbrot/palette.cpp b/examples/opencl/mandelbrot/palette.cpp
new file mode 100644
index 0000000..555f5ea
--- /dev/null
+++ b/examples/opencl/mandelbrot/palette.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "palette.h"
+
+Palette::Palette()
+ : type(QColor::Invalid), offset(0.0f)
+{
+ setStandardPalette(Fire);
+}
+
+Palette::~Palette()
+{
+}
+
+void Palette::setStandardPalette(StandardPalette palette)
+{
+ clear();
+ switch (palette) {
+ default: case Red:
+ addHsv(0.0f, 0.0f, 1.0f, 1.0f);
+ addHsv(1.0f, 1.0f, 1.0f, 1.0f);
+ break;
+ case Blue:
+ addHsv(0.0f, 0.65f, 1.0f, 0.5f);
+ addHsv(1.0f, 0.05f, 1.0f, 1.0f);
+ break;
+
+ // The following palettes are from xMandelbrotViewer.
+ // http://math.hws.edu/xJava/MB/
+ case EarthSky:
+ addRgb(0.0f, 1.0f, 1.0f, 1.0f);
+ addRgb(0.15f, 1.0f, 0.8f, 0.0f);
+ addRgb(0.33f, 0.53f, 0.12f, 0.075f);
+ addRgb(0.67f, 0.0f, 0.0f, 0.6f);
+ addRgb(0.85f, 0.0f, 0.4f, 1.0f);
+ addRgb(1.0f, 1.0f, 1.0f, 1.0f);
+ setOffset(0.85f);
+ break;
+ case HotCold:
+ addRgb(0.0f, 1.0f, 1.0f, 1.0f);
+ addRgb(0.16f, 0.0f, 0.4f, 1.0f);
+ addRgb(0.5f, 0.2f, 0.2f, 0.2f);
+ addRgb(0.84f, 1.0f, 0.0f, 0.8f);
+ addRgb(1.0f, 1.0f, 1.0f, 1.0f);
+ break;
+ case Fire:
+ addRgb(0.0f, 0.0f, 0.0f, 0.0f);
+ addRgb(0.17f, 1.0f, 0.0f, 0.0f);
+ addRgb(0.83f, 1.0f, 1.0f, 0.0f);
+ addRgb(1.0f, 1.0f, 1.0f, 1.0f);
+ break;
+ }
+}
+
+void Palette::clear()
+{
+ type = QColor::Invalid;
+ offset = 0.0f;
+ ranges.clear();
+}
+
+void Palette::addRgb(qreal start, qreal r, qreal g, qreal b)
+{
+ type = QColor::Rgb;
+ Range range;
+ range.start = start;
+ range.r = r;
+ range.g = g;
+ range.b = b;
+ ranges.append(range);
+}
+
+void Palette::addHsv(qreal start, qreal h, qreal s, qreal v)
+{
+ type = QColor::Hsv;
+ Range range;
+ range.start = start;
+ range.h = h;
+ range.s = s;
+ range.v = v;
+ ranges.append(range);
+}
+
+QVector<QRgb> Palette::createTable(int size) const
+{
+ Q_ASSERT(ranges.size() >= 2);
+ Q_ASSERT(ranges[ranges.size() - 1].start == 1.0f);
+ QVector<QRgb> colors;
+ colors.resize(size);
+ int ioffset = int(offset * size);
+ for (int index = 0; index < size; ++index) {
+ qreal amt = qreal((index + ioffset) % size) / (size - 1);
+ int posn = 1;
+ while (ranges[posn].start < 1.0f && ranges[posn].start < amt)
+ ++posn;
+ amt = (amt - ranges[posn - 1].start) /
+ (ranges[posn].start - ranges[posn - 1].start);
+ if (type == QColor::Rgb) {
+ qreal r = ranges[posn - 1].r +
+ (ranges[posn].r - ranges[posn - 1].r) * amt;
+ qreal g = ranges[posn - 1].g +
+ (ranges[posn].g - ranges[posn - 1].g) * amt;
+ qreal b = ranges[posn - 1].b +
+ (ranges[posn].b - ranges[posn - 1].b) * amt;
+ colors[index] = QColor::fromRgbF(r, g, b).rgb();
+ } else {
+ qreal h = ranges[posn - 1].h +
+ (ranges[posn].h - ranges[posn - 1].h) * amt;
+ qreal s = ranges[posn - 1].s +
+ (ranges[posn].s - ranges[posn - 1].s) * amt;
+ qreal v = ranges[posn - 1].v +
+ (ranges[posn].v - ranges[posn - 1].v) * amt;
+ colors[index] = QColor::fromHsvF(h, s, v).rgb();
+ }
+ }
+ return colors;
+}
diff --git a/examples/opencl/mandelbrot/palette.h b/examples/opencl/mandelbrot/palette.h
new file mode 100644
index 0000000..dc19a16
--- /dev/null
+++ b/examples/opencl/mandelbrot/palette.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PALETTE_H
+#define PALETTE_H
+
+#include <QtCore/qvector.h>
+#include <QtGui/qcolor.h>
+
+class Palette
+{
+public:
+ Palette();
+ ~Palette();
+
+ enum StandardPalette
+ {
+ Red,
+ Blue,
+ EarthSky,
+ HotCold,
+ Fire
+ };
+
+ void setStandardPalette(StandardPalette palette);
+
+ void clear();
+ void addRgb(qreal start, qreal r, qreal g, qreal b);
+ void addHsv(qreal start, qreal h, qreal s, qreal v);
+ void setOffset(qreal value) { offset = value; }
+
+ QVector<QRgb> createTable(int size) const;
+
+private:
+ struct Range
+ {
+ qreal start;
+ union {
+ struct {
+ qreal r, g, b;
+ };
+ struct {
+ qreal h, s, v;
+ };
+ };
+ };
+ QColor::Spec type;
+ qreal offset;
+ QVector<Range> ranges;
+};
+
+#endif
diff --git a/examples/opencl/mandelbrot/view.cpp b/examples/opencl/mandelbrot/view.cpp
new file mode 100644
index 0000000..71559e2
--- /dev/null
+++ b/examples/opencl/mandelbrot/view.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "view.h"
+#include "image.h"
+#include "palette.h"
+#include <QtGui/qpainter.h>
+#include <QtCore/qtimer.h>
+
+View::View(QWidget *parent)
+ : QWidget(parent)
+{
+ setMinimumSize(768, 512);
+ setMaximumSize(768, 512);
+
+ palette = new Palette();
+ palette->setStandardPalette(Palette::Blue);
+ offset = 0.0f;
+ step = 0.05f;
+
+ image = Image::createImage(768, 512);
+ image->generate(200, *palette);
+
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(animate()));
+ timer->start(50);
+}
+
+View::~View()
+{
+ delete palette;
+ delete image;
+}
+
+void View::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ QImage img = image->image();
+ painter.drawImage((width() - img.width()) / 2,
+ (height() - img.height()) / 2,
+ img);
+}
+
+void View::animate()
+{
+ if (step > 0) {
+ offset += step;
+ if (offset >= 1.0f) {
+ offset = 1.0f;
+ step = -step;
+ }
+ } else {
+ offset += step;
+ if (offset <= 0.0f) {
+ offset = 0.0f;
+ step = -step;
+ }
+ }
+ palette->setOffset(offset);
+ //image->forceUpdate();
+ image->generate(200, *palette);
+ update();
+}
diff --git a/examples/opencl/mandelbrot/view.h b/examples/opencl/mandelbrot/view.h
new file mode 100644
index 0000000..cbf453b
--- /dev/null
+++ b/examples/opencl/mandelbrot/view.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIEW_H
+#define VIEW_H
+
+#include <QtGui/qwidget.h>
+
+class Image;
+class Palette;
+
+class View : public QWidget
+{
+ Q_OBJECT
+public:
+ View(QWidget *parent = 0);
+ ~View();
+
+private slots:
+ void animate();
+
+protected:
+ void paintEvent(QPaintEvent *);
+
+private:
+ Image *image;
+ Palette *palette;
+ qreal offset;
+ qreal step;
+};
+
+#endif
diff --git a/examples/opencl/opencl.pro b/examples/opencl/opencl.pro
index 0be1dc9..557c348 100644
--- a/examples/opencl/opencl.pro
+++ b/examples/opencl/opencl.pro
@@ -1,2 +1,2 @@
TEMPLATE = subdirs
-SUBDIRS = vectoradd
+SUBDIRS = vectoradd mandelbrot