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
23 #include <boost/compute/command_queue.hpp>
24 #include <boost/compute/kernel.hpp>
25 #include <boost/compute/program.hpp>
26 #include <boost/compute/system.hpp>
27 #include <boost/compute/interop/opengl.hpp>
28 #include <boost/compute/utility/dim.hpp>
29 #include <boost/compute/utility/source.hpp>
32 namespace compute
= boost::compute
;
35 const char source
[] = BOOST_COMPUTE_STRINGIZE_SOURCE(
46 return (float4
)(0, 0, 0, 255);
48 return (float4
)(max
-x
*i
, max
-y
*i
, max
-z
*i
, max
) / 255.f
;
51 __kernel
void mandelbrot(__write_only image2d_t image
)
53 const uint x_coord
= get_global_id(0);
54 const uint y_coord
= get_global_id(1);
55 const uint width
= get_global_size(0);
56 const uint height
= get_global_size(1);
58 float x_origin
= ((float) x_coord
/ width
) * 3.25f
- 2.0f
;
59 float y_origin
= ((float) y_coord
/ height
) * 2.5f
- 1.25f
;
65 while(x
*x
+ y
*y
<= 4.f
&& i
< 256){
66 float tmp
= x
*x
- y
*y
+ x_origin
;
72 int2 coord
= { x_coord
, y_coord
};
73 write_imagef(image
, coord
, color(i
));
77 class MandelbrotWidget
: public QGLWidget
82 MandelbrotWidget(QWidget
*parent
= 0);
86 void resizeGL(int width
, int height
);
88 void keyPressEvent(QKeyEvent
* event
);
91 compute::context context_
;
92 compute::command_queue queue_
;
93 compute::program program_
;
95 compute::opengl_texture cl_texture_
;
98 MandelbrotWidget::MandelbrotWidget(QWidget
*parent
)
104 MandelbrotWidget::~MandelbrotWidget()
108 void MandelbrotWidget::initializeGL()
111 glDisable(GL_LIGHTING
);
113 // create the OpenGL/OpenCL shared context
114 context_
= compute::opengl_create_shared_context();
117 compute::device gpu
= context_
.get_device();
118 std::cout
<< "device: " << gpu
.name() << std::endl
;
120 // setup command queue
121 queue_
= compute::command_queue(context_
, gpu
);
123 // build mandelbrot program
124 program_
= compute::program::create_with_source(source
, context_
);
128 void MandelbrotWidget::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 MandelbrotWidget::paintGL()
169 glMatrixMode(GL_PROJECTION
);
171 glOrtho(0.0, w
, 0.0, h
, -1.0, 1.0);
172 glMatrixMode(GL_MODELVIEW
);
175 // setup the mandelbrot kernel
176 compute::kernel
kernel(program_
, "mandelbrot");
177 kernel
.set_arg(0, 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 mandelbrot kernel
183 queue_
.enqueue_nd_range_kernel(
184 kernel
, dim(0, 0), dim(width(), height()), dim(1, 1)
187 // release the opengl texture so it can be used by opengl
188 compute::opengl_enqueue_release_gl_objects(1, &cl_texture_
.get(), queue_
);
190 // ensure opencl is finished before rendering in opengl
193 // draw a single quad with the mandelbrot image texture
194 glEnable(GL_TEXTURE_2D
);
195 glBindTexture(GL_TEXTURE_2D
, gl_texture_
);
198 glTexCoord2f(0, 0); glVertex2f(0, 0);
199 glTexCoord2f(0, 1); glVertex2f(0, h
);
200 glTexCoord2f(1, 1); glVertex2f(w
, h
);
201 glTexCoord2f(1, 0); glVertex2f(w
, 0);
205 void MandelbrotWidget::keyPressEvent(QKeyEvent
* event
)
207 if(event
->key() == Qt::Key_Escape
) {
212 // the mandelbrot example shows how to create a mandelbrot image in
213 // OpenCL and render the image as a texture in OpenGL
214 int main(int argc
, char *argv
[])
216 QApplication
app(argc
, argv
);
218 MandelbrotWidget widget
;
224 #include "mandelbrot.moc"