diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2010-03-01 10:11:33 +1000 |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2010-03-01 10:20:14 +1000 |
commit | 307d72bf60398b9b0b7e4ca70cbdb793676652bc (patch) | |
tree | cc6a0a1af163969346d5908aaa981d0110f2b69f /examples | |
parent | 0b40ff3363f64ef359b579431ecd426f60c01d9e (diff) |
Image drawing example.
Diffstat (limited to 'examples')
-rw-r--r-- | examples/opencl/imagedrawing/beavis.jpg | bin | 0 -> 22219 bytes | |||
-rw-r--r-- | examples/opencl/imagedrawing/bg1.jpg | bin | 0 -> 23771 bytes | |||
-rw-r--r-- | examples/opencl/imagedrawing/flower.jpg | bin | 0 -> 49616 bytes | |||
-rw-r--r-- | examples/opencl/imagedrawing/imagedrawing.cl | 77 | ||||
-rw-r--r-- | examples/opencl/imagedrawing/imagedrawing.pro | 13 | ||||
-rw-r--r-- | examples/opencl/imagedrawing/imagedrawing.qrc | 9 | ||||
-rw-r--r-- | examples/opencl/imagedrawing/imagewidget.cpp | 172 | ||||
-rw-r--r-- | examples/opencl/imagedrawing/imagewidget.h | 81 | ||||
-rw-r--r-- | examples/opencl/imagedrawing/main.cpp | 51 | ||||
-rw-r--r-- | examples/opencl/imagedrawing/qtlogo.png | bin | 0 -> 4570 bytes | |||
-rw-r--r-- | examples/opencl/opencl.pro | 2 |
11 files changed, 404 insertions, 1 deletions
diff --git a/examples/opencl/imagedrawing/beavis.jpg b/examples/opencl/imagedrawing/beavis.jpg Binary files differnew file mode 100644 index 0000000..5fa32e4 --- /dev/null +++ b/examples/opencl/imagedrawing/beavis.jpg diff --git a/examples/opencl/imagedrawing/bg1.jpg b/examples/opencl/imagedrawing/bg1.jpg Binary files differnew file mode 100644 index 0000000..dfc7cee --- /dev/null +++ b/examples/opencl/imagedrawing/bg1.jpg diff --git a/examples/opencl/imagedrawing/flower.jpg b/examples/opencl/imagedrawing/flower.jpg Binary files differnew file mode 100644 index 0000000..f8e022c --- /dev/null +++ b/examples/opencl/imagedrawing/flower.jpg diff --git a/examples/opencl/imagedrawing/imagedrawing.cl b/examples/opencl/imagedrawing/imagedrawing.cl new file mode 100644 index 0000000..8cf859d --- /dev/null +++ b/examples/opencl/imagedrawing/imagedrawing.cl @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** 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 fillRectWithColor + (__write_only image2d_t dstImage, + int offsetX, int offsetY, int limitX, int limitY, + float4 color) +{ + int x = get_global_id(0) + offsetX; + int y = get_global_id(1) + offsetY; + if (x < limitX && y < limitY) + write_imagef(dstImage, (int2)(x, y), color); +} + +const sampler_t lsamp = CLK_ADDRESS_CLAMP_TO_EDGE | + CLK_FILTER_LINEAR; +const sampler_t nsamp = CLK_ADDRESS_CLAMP_TO_EDGE | + CLK_FILTER_NEAREST; + +__kernel void drawImage + (__write_only image2d_t dstImage, + __read_only image2d_t dst2Image, + __read_only image2d_t srcImage, + int dstx, int dsty, int dstw, int dsth, + float4 src, float opacity) +{ + int2 dstPos = (int2)(get_global_id(0) + dstx, + get_global_id(1) + dsty); + float2 srcPos = (float2)(get_global_id(0) * src.z / dstw + src.x, + get_global_id(1) * src.w / dsth + src.y); + if (dstPos.x < dstx || dstPos.x >= (dstx + dstw) || + dstPos.y < dsty || dstPos.y >= (dsty + dsth)) + return; // Undrawn extra pixel due to 8x8 round up. + float4 scolor = read_imagef(srcImage, lsamp, srcPos); + float4 dcolor = read_imagef(dst2Image, nsamp, dstPos); + // Destination is assumed to be RGB, source may be RGBA. + dcolor = (float4)(dcolor.xyz * (1.0f - scolor.w * opacity) + scolor.xyz * scolor.w * opacity, 1.0f); + write_imagef(dstImage, dstPos, clamp(dcolor, 0.0f, 1.0f)); +} diff --git a/examples/opencl/imagedrawing/imagedrawing.pro b/examples/opencl/imagedrawing/imagedrawing.pro new file mode 100644 index 0000000..7b38e19 --- /dev/null +++ b/examples/opencl/imagedrawing/imagedrawing.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = imagedrawing +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp \ + imagewidget.cpp +HEADERS += imagewidget.h +RESOURCES += imagedrawing.qrc + +LIBS += -L../../../lib -L../../../bin +include(../../../src/opencl/opencl_dep.pri) diff --git a/examples/opencl/imagedrawing/imagedrawing.qrc b/examples/opencl/imagedrawing/imagedrawing.qrc new file mode 100644 index 0000000..7ebade6 --- /dev/null +++ b/examples/opencl/imagedrawing/imagedrawing.qrc @@ -0,0 +1,9 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>imagedrawing.cl</file> + <file>beavis.jpg</file> + <file>bg1.jpg</file> + <file>flower.jpg</file> + <file>qtlogo.png</file> +</qresource> +</RCC> diff --git a/examples/opencl/imagedrawing/imagewidget.cpp b/examples/opencl/imagedrawing/imagewidget.cpp new file mode 100644 index 0000000..27b4344 --- /dev/null +++ b/examples/opencl/imagedrawing/imagewidget.cpp @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** 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 "imagewidget.h" +#include <QtGui/qpainter.h> +#include <QtGui/qvector4d.h> + +ImageWidget::ImageWidget(QWidget *parent) + : QWidget(parent) +{ + setAttribute(Qt::WA_OpaquePaintEvent); + + if (!context.create()) + qFatal("Could not create OpenCL context"); + + program = context.buildProgramFromSourceFile(QLatin1String(":/imagedrawing.cl")); + + fillRectWithColor = program.createKernel("fillRectWithColor"); + fillRectWithColor.setLocalWorkSize(8, 8); + + drawImageKernel = program.createKernel("drawImage"); + drawImageKernel.setLocalWorkSize(8, 8); + + flower = context.createImage2DCopy + (QImage(QLatin1String(":/flower.jpg")), QCL::ReadOnly); + bg1 = context.createImage2DCopy + (QImage(QLatin1String(":/bg1.jpg")), QCL::ReadOnly); + beavis = context.createImage2DCopy + (QImage(QLatin1String(":/beavis.jpg")), QCL::ReadOnly); + qtlogo = context.createImage2DCopy + (QImage(QLatin1String(":/qtlogo.png")), QCL::ReadOnly); +} + +ImageWidget::~ImageWidget() +{ +} + +void ImageWidget::paintEvent(QPaintEvent *) +{ + // Create a QCLImage2D object for the window surface. + QSize wsize = size(); + if (wsize != windowSize) + surfaceImage = QCLImage2D(); + if (surfaceImage.isNull()) { + windowSize = wsize; + surfaceImage = context.createImage2DDevice + (QImage::Format_RGB32, windowSize, QCL::ReadWrite); + } + + // Clear to the background color. + QColor bgcolor = palette().color(backgroundRole()); + fillRect(0, 0, wsize.width(), wsize.height(), bgcolor); + + // Draw the images. + drawImage(flower, 50, 50, 1.0f); + drawImage(beavis, 200, 100, 0.9f); + drawScaledImage(beavis, 550, 150, 250, 250, 0.9f); + drawImage(bg1, 0, 0, 0.7f); + drawImage(qtlogo, 200, 350, 1.0f); + + // Draw the window surface image to the actual window. + QPainter painter(this); + surfaceImage.drawImage(&painter, QPoint(0, 0)); +} + +void ImageWidget::fillRect(int x, int y, int width, int height, + const QColor& color) +{ + // Round up the global work size so we can process the + // rectangle in 8x8 local work size units. The kernel will + // ignore pixels that are outside the rectangle limits. + fillRectWithColor.setGlobalWorkSize((width + 7) & ~7, (height + 7) & ~7); + fillRectWithColor(surfaceImage, x, y, x + width, y + height, color); +} + +void ImageWidget::drawImage(const QCLImage2D& image, int x, int y, float opacity) +{ + QRect srcRect = QRect(0, 0, image.width(), image.height()); + QRect dstRect = QRect(x, y, srcRect.width(), srcRect.height()); + + // Clamp the draw to the surface extents. + QRect dstRect2 = dstRect.intersect + (QRect(0, 0, windowSize.width(), windowSize.height())); + srcRect.setLeft(srcRect.left() + dstRect2.left() - dstRect.left()); + srcRect.setTop(srcRect.top() + dstRect2.top() - dstRect.top()); + srcRect.setRight(srcRect.right() + dstRect2.right() - dstRect.right()); + srcRect.setBottom(srcRect.bottom() + dstRect2.bottom() - dstRect.bottom()); + dstRect = dstRect2; + if (srcRect.isEmpty() || dstRect.isEmpty()) + return; + + // Set the global work size to the destination size rounded up to 8. + drawImageKernel.setGlobalWorkSize + ((dstRect.width() + 7) & ~7, (dstRect.height() + 7) & ~7); + + // Draw the image. + QVector4D src(srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height()); + drawImageKernel + (surfaceImage, surfaceImage, image, + dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), + src, opacity); +} + +void ImageWidget::drawScaledImage + (const QCLImage2D& image, int x, int y, int width, int height, + float opacity) +{ + QRectF srcRect = QRectF(0, 0, image.width(), image.height()); + QRect dstRect = QRect(x, y, width, height); + + // Clamp the draw to the surface extents. + QRect dstRect2 = dstRect.intersect + (QRect(0, 0, windowSize.width(), windowSize.height())); + qreal scaleX = srcRect.width() / width; + qreal scaleY = srcRect.height() / height; + srcRect.setLeft(srcRect.left() + (dstRect2.left() - dstRect.left()) * scaleX); + srcRect.setTop(srcRect.top() + (dstRect2.top() - dstRect.top()) * scaleY); + srcRect.setRight(srcRect.right() + (dstRect2.right() - dstRect.right()) * scaleX); + srcRect.setBottom(srcRect.bottom() + (dstRect2.bottom() - dstRect.bottom()) * scaleY); + dstRect = dstRect2; + if (srcRect.isEmpty() || dstRect.isEmpty()) + return; + + // Set the global work size to the destination size rounded up to 8. + drawImageKernel.setGlobalWorkSize + ((dstRect.width() + 7) & ~7, (dstRect.height() + 7) & ~7); + + // Draw the image. + QVector4D src(srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height()); + drawImageKernel + (surfaceImage, surfaceImage, image, + dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), + src, opacity); +} diff --git a/examples/opencl/imagedrawing/imagewidget.h b/examples/opencl/imagedrawing/imagewidget.h new file mode 100644 index 0000000..65e355c --- /dev/null +++ b/examples/opencl/imagedrawing/imagewidget.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** 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 PATHWIDGET_H +#define PATHWIDGET_H + +#include <QWidget> +#include <QImage> +#include "qclcontext.h" + +class ImageWidget : public QWidget +{ + Q_OBJECT +public: + ImageWidget(QWidget *parent = 0); + ~ImageWidget(); + +protected: + void paintEvent(QPaintEvent *); + +private: + QCLContext context; + + QCLProgram program; + QCLKernel fillRectWithColor; + QCLKernel drawImageKernel; + + QCLImage2D flower; + QCLImage2D bg1; + QCLImage2D beavis; + QCLImage2D qtlogo; + + QSize windowSize; + QCLImage2D surfaceImage; + + void fillRect(int x, int y, int width, int height, const QColor& color); + void drawImage(const QCLImage2D& image, int x, int y, float opacity); + void drawScaledImage + (const QCLImage2D& image, int x, int y, int width, int height, + float opacity); +}; + +#endif diff --git a/examples/opencl/imagedrawing/main.cpp b/examples/opencl/imagedrawing/main.cpp new file mode 100644 index 0000000..1843255 --- /dev/null +++ b/examples/opencl/imagedrawing/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** 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 "imagewidget.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + ImageWidget w; + w.show(); + return app.exec(); +} diff --git a/examples/opencl/imagedrawing/qtlogo.png b/examples/opencl/imagedrawing/qtlogo.png Binary files differnew file mode 100644 index 0000000..153cb3f --- /dev/null +++ b/examples/opencl/imagedrawing/qtlogo.png diff --git a/examples/opencl/opencl.pro b/examples/opencl/opencl.pro index 558760f..401ef40 100644 --- a/examples/opencl/opencl.pro +++ b/examples/opencl/opencl.pro @@ -1,2 +1,2 @@ TEMPLATE = subdirs -SUBDIRS = vectoradd blur pathdrawing bezierpatch +SUBDIRS = vectoradd blur pathdrawing bezierpatch imagedrawing |