1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
15 #if QT_VERSION >= 0x050000
22 #include <boost/program_options.hpp>
25 #include <boost/compute/command_queue.hpp>
26 #include <boost/compute/kernel.hpp>
27 #include <boost/compute/program.hpp>
28 #include <boost/compute/system.hpp>
29 #include <boost/compute/image/image2d.hpp>
30 #include <boost/compute/image/image_sampler.hpp>
31 #include <boost/compute/interop/qt.hpp>
32 #include <boost/compute/interop/opengl.hpp>
33 #include <boost/compute/utility/source.hpp>
36 namespace compute
= boost::compute
;
37 namespace po
= boost::program_options
;
40 const char source
[] = BOOST_COMPUTE_STRINGIZE_SOURCE(
41 __kernel
void resize_image(__read_only image2d_t input
,
42 const sampler_t sampler
,
43 __write_only image2d_t output
)
45 const uint x
= get_global_id(0);
46 const uint y
= get_global_id(1);
48 const float w
= get_image_width(output
);
49 const float h
= get_image_height(output
);
51 float2 coord
= { ((float) x
/ w
) * get_image_width(input
),
52 ((float) y
/ h
) * get_image_height(input
) };
54 float4 pixel
= read_imagef(input
, sampler
, coord
);
55 write_imagef(output
, (int2
)(x
, h
- y
- 1), pixel
);
59 class ImageWidget
: public QGLWidget
64 ImageWidget(QString fileName
, QWidget
*parent
= 0);
68 void resizeGL(int width
, int height
);
73 compute::context context_
;
74 compute::command_queue queue_
;
75 compute::program program_
;
76 compute::image2d image_
;
77 compute::image_sampler sampler_
;
79 compute::opengl_texture cl_texture_
;
82 ImageWidget::ImageWidget(QString fileName
, QWidget
*parent
)
89 ImageWidget::~ImageWidget()
93 void ImageWidget::initializeGL()
96 glDisable(GL_LIGHTING
);
98 // create the OpenGL/OpenCL shared context
99 context_
= compute::opengl_create_shared_context();
102 compute::device gpu
= context_
.get_device();
103 std::cout
<< "device: " << gpu
.name() << std::endl
;
105 // setup command queue
106 queue_
= compute::command_queue(context_
, gpu
);
108 // allocate image on the device
109 compute::image_format format
=
110 compute::qt_qimage_format_to_image_format(qt_image_
.format());
112 image_
= compute::image2d(
113 context_
, qt_image_
.width(), qt_image_
.height(), format
, CL_MEM_READ_ONLY
116 // transfer image to the device
117 compute::qt_copy_qimage_to_image2d(qt_image_
, image_
, queue_
);
119 // setup image sampler (use CL_FILTER_NEAREST to disable linear interpolation)
120 sampler_
= compute::image_sampler(
121 context_
, false, CL_ADDRESS_NONE
, CL_FILTER_LINEAR
124 // build resize program
125 program_
= compute::program::build_with_source(source
, context_
);
128 void ImageWidget::resizeGL(int width
, int height
)
130 #if QT_VERSION >= 0x050000
131 // scale height/width based on device pixel ratio
132 width
/= windowHandle()->devicePixelRatio();
133 height
/= windowHandle()->devicePixelRatio();
137 glViewport(0, 0, width
, height
);
139 // delete old texture
141 glDeleteTextures(1, &gl_texture_
);
145 // generate new texture
146 glGenTextures(1, &gl_texture_
);
147 glBindTexture(GL_TEXTURE_2D
, gl_texture_
);
148 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
149 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
150 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
151 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
153 GL_TEXTURE_2D
, 0, GL_RGBA
, width
, height
, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, 0
156 // create opencl object for the texture
157 cl_texture_
= compute::opengl_texture(
158 context_
, GL_TEXTURE_2D
, 0, gl_texture_
, CL_MEM_WRITE_ONLY
162 void ImageWidget::paintGL()
167 glMatrixMode(GL_PROJECTION
);
169 glOrtho(0.0, w
, 0.0, h
, -1.0, 1.0);
170 glMatrixMode(GL_MODELVIEW
);
173 // setup the resize kernel
174 compute::kernel
kernel(program_
, "resize_image");
175 kernel
.set_arg(0, image_
);
176 kernel
.set_arg(1, sampler_
);
177 kernel
.set_arg(2, cl_texture_
);
179 // acquire the opengl texture so it can be used in opencl
180 compute::opengl_enqueue_acquire_gl_objects(1, &cl_texture_
.get(), queue_
);
182 // execute the resize kernel
183 const size_t global_work_offset
[] = { 0, 0 };
184 const size_t global_work_size
[] = { size_t(width()), size_t(height()) };
186 queue_
.enqueue_nd_range_kernel(
187 kernel
, 2, global_work_offset
, global_work_size
, 0
190 // release the opengl texture so it can be used by opengl
191 compute::opengl_enqueue_release_gl_objects(1, &cl_texture_
.get(), queue_
);
193 // ensure opencl is finished before rendering in opengl
196 // draw a single quad with the resized image texture
197 glEnable(GL_TEXTURE_2D
);
198 glBindTexture(GL_TEXTURE_2D
, gl_texture_
);
201 glTexCoord2f(0, 0); glVertex2f(0, 0);
202 glTexCoord2f(0, 1); glVertex2f(0, h
);
203 glTexCoord2f(1, 1); glVertex2f(w
, h
);
204 glTexCoord2f(1, 0); glVertex2f(w
, 0);
208 // the resize image example demonstrates how to interactively resize a
209 // 2D image and display it using OpenGL. a image sampler is used to perform
210 // hardware-accelerated linear interpolation for the resized image.
211 int main(int argc
, char *argv
[])
213 // setup command line arguments
214 po::options_description
options("options");
215 options
.add_options()
216 ("help", "show usage instructions")
217 ("file", po::value
<std::string
>(), "image file name (e.g. /path/to/image.png)")
219 po::positional_options_description positional_options
;
220 positional_options
.add("file", 1);
222 // parse command line
223 po::variables_map vm
;
225 po::command_line_parser(argc
, argv
)
227 .positional(positional_options
)
233 // check for file argument
234 if(vm
.count("help") || !vm
.count("file")){
235 std::cout
<< options
<< std::endl
;
240 std::string file_name
= vm
["file"].as
<std::string
>();
242 // setup qt application
243 QApplication
app(argc
, argv
);
245 // setup image widget
246 ImageWidget
widget(QString::fromStdString(file_name
));
249 // run qt application
253 #include "resize_image.moc"