<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>enj</title>
	
	<link>http://enja.org</link>
	<description>casin' the joint since '85</description>
	<lastBuildDate>Tue, 31 Aug 2010 21:00:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/enjaorg" /><feedburner:info uri="enjaorg" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Adventures in OpenCL Part 2: Particles with OpenGL</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/RI3jFG-6gZo/</link>
		<comments>http://enja.org/2010/08/27/adventures-in-opencl-part-2-particles-with-opengl/#comments</comments>
		<pubDate>Sat, 28 Aug 2010 02:04:19 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[advcl]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[opencl]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://enja.org/?p=278</guid>
		<description><![CDATA[This tutorial series is aimed at developers trying to learn OpenCL from the bottom up, with a focus on practicality. This installment introduces OpenCL context sharing with OpenGL. We make a simple particle system to demonstrate this feature. One of &#8230; <a href="http://enja.org/2010/08/27/adventures-in-opencl-part-2-particles-with-opengl/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div id="attachment_287" class="wp-caption alignright" style="width: 310px"><a href="http://enja.org/wp-content/uploads/2010/08/Screen-shot-2010-08-27-at-10.05.32-PM.png"><img class="size-medium wp-image-287 " title="20k particles advcl: part2" src="http://enja.org/wp-content/uploads/2010/08/Screen-shot-2010-08-27-at-10.05.32-PM-300x233.png" alt="" width="300" height="233" /></a><p class="wp-caption-text">20,000 particles being shared by OpenGL and OpenCL</p></div>
<p>This tutorial series is aimed at developers trying to learn <a href="http://www.khronos.org/opencl">OpenCL</a> from the bottom up, with a focus on practicality. This installment introduces OpenCL context sharing with OpenGL. We make a simple particle system to demonstrate this feature. One of the most important aspects of this feature is the time we can save by doing rendering and calculations on the same memory in the GPU, this means we don&#8217;t need to copy data back and forth!</p>
<p>You may want to <a href="http://github.com/enjalot/adventures_in_opencl/tree/master/part2/">grab the code</a> and compile it to see it in action. As usual I recommend having a copy of the <a href="http://www.khronos.org/registry/cl/">OpenCL specification</a> handy.</p>
<p>In this tutorial I use the C++ bindings with less explanation, so see <a href="http://enja.org/2010/07/20/adventures-in-opencl-part-1-5-cpp-bindings/">Part 1.5</a> for a more in-depth explanation or <a href="http://enja.org/2010/07/13/adventures-in-opencl-part-1-getting-started/">Part 1</a> to get started with C bindings. As before this code has been tested by me on NVIDIA hardware on my Macbook Pro and on an Ubuntu workstation, ATI and Windows users are encouraged to try it out and let me know if you have any problems so I can update the tutorial.</p>
<h2>Sharing is Caring!</h2>
<p>Lets see what we need to do to get OpenCL and OpenGL sharing their context. The first thing we need is an OpenGL context! For this tutorial I use GLUT to create a window that we can draw in, and GLEW for OpenGL extensions (at least on linux). This means you will need to have those headers and libraries installed on your system. Once you have those you can try building:</p>
<pre class="brush: bash;">cd part2
mkdir build
cd build
cmake ..
make
</pre>
<h2>The Source Code Files</h2>
<p>Let&#8217;s go over the source files again, even though they are the same as the last tutorial we add more functionality in a couple of them, so it will be good to quickly go over the changes.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/main.cpp">main.cpp</a><br />
This is where we test out our CL class. We setup a GLUT window and OpenGL context. Then we instantiate our CL class, prepare a simple particle system and initialize it. At the end of the file are several helper functions for manipulating the OpenGL view with the mouse and keyboard.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/cll.h">cll.h</a><br />
The main header file for our CL class definition, also handles including the OpenCL libraries. I&#8217;ve downloaded the header files from the <a href="http://khronos.org/registry/cl">Khronos website</a> to avoid having to search the computer for a particular SDK. Note that I&#8217;ve had to make a slight change to cl.hpp for Mac users because of a bug in the implementation, which I will cover later.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/cll.cpp">cll.cpp</a><br />
The core implementation of our CL class, including functions for initializing the OpenCL context from OpenGL, loading and building an OpenCL program.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/part2.cpp">part2.cpp</a><br />
Implementation of the functions that setup and run the OpenCL kernel. This is where we actually see OpenCL in action.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/part2.cl">part2.cl</a><br />
The actual OpenCL code to be executed. Right now it&#8217;s a simple particle system that models gravity.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/util.h">util.h</a> and <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/util.cpp">util.cpp</a><br />
Utility functions that make things like creating VBOs or printing out OpenCL error messages easier</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/CMakeLists.txt">CMakeLists.txt</a><br />
The configuration and build script used to build the project. This makes it easier to be portable, and building our code as a library makes it easier to contribute to other projects.</p>
<h2>The Source Code Contents</h2>
<p>So our <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/main.cpp">main.cpp</a> is a bit messier than before, this is mostly just setting up the OpenGL stuff. You may already have some OpenGL context to plug your OpenCL stuff into, in which case you just want to make sure you are using Vertex Buffer Objects (<a href="http://www.songho.ca/opengl/gl_vbo.html">VBOs</a>) that OpenCL can use to create its buffers.<br />
I will just point out some interesting bits that are important to OpenCL, starting with the number of particles and a pointer to our CL class:</p>
<pre class="brush: cpp;">
#define NUM_PARTICLES 10000
CL* example;
</pre>
<p>and later we instantiate it like:</p>
<pre class="brush: cpp;"> example = new CL();</pre>
<p>We do this so that we can access the object from the GLUT loop, specifically in the appRender function which is called by GLUT to update the display. Before we can talk about rendering though, we need to load some data! Take a look at the for loop where we populate three vectors of <span class="simple_code">Vec4</span> which is just a typedef for 4 floats; x, y, z, w, declared in <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/cll.h">cll.h</a>. We then pass these to our class which will push the data to the GPU.</p>
<pre class="brush: cpp;">
example-&gt;loadData(pos, vel, color);
example-&gt;popCorn();
</pre>
<p>Lastly in main.cpp let&#8217;s take a look at the <span class="simple_code">void appRender()</span> function, where the first thing we do is update the particle system:</p>
<pre class="brush: cpp;">example-&gt;runKernel();</pre>
<p>This is followed by the rendering code, which is standard OpenGL for drawing points from a VBO. I learned this from <a href="http://www.songho.ca/opengl/gl_vbo.html">here</a>.</p>
<p>Now let&#8217;s took at some changes to <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/cll.cpp">cll.cpp</a>.<br />
It is easier to just click the link and view the whole source file, since the code is too long for a snippet here, but the major addition is the way we ceate the context. Each operating system uses different extensions to accomplish the same thing, the code mostly comes from the NVIDIA GPU SDK examples, but I modified it to use the C++ bindings. In doing so I found an inconsistency in Apple&#8217;s implementation and had to add an extra constructor to the Context class in <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/opencl10/CL/cl.hpp">cl.hpp</a> (around line 1448) to compensate.</p>
<p>We see the most OpenCL action in <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/part2.cpp">part2.cpp</a> which also demonstrates creating a CL buffer from a GL buffer. First we create the GL buffer as a VBO</p>
<pre class="brush: cpp;">p_vbo = createVBO(&amp;pos[0], array_size, GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW);</pre>
<p>The nice thing about <span class="simple_code&quot;">std::vector</span>s is that they store their elements in a tightly packed array so we can just pass the address of the first element. Next we store our vbos in another vector as <span class="simple_code">cl::BufferGL</span> objects:</p>
<pre class="brush: cpp;">cl_vbos.push_back(cl::BufferGL(context, CL_MEM_READ_WRITE, p_vbo, &amp;err));</pre>
<p>We don&#8217;t need to push any data to them like we do our pure OpenCL buffers because they just reference the data that is already in the VBO!</p>
<p>Our popCorn function just loads the kernel like before, and sets its arguments. Finally in the runKernel function we have to do a couple extra things to work with our VBOs, namely</p>
<pre class="brush: cpp;">err = queue.enqueueAcquireGLObjects(&amp;cl_vbos, NULL, &amp;event);</pre>
<p>and</p>
<pre class="brush: cpp;">err = queue.enqueueReleaseGLObjects(&amp;cl_vbos, NULL, &amp;event);</pre>
<p>Which acquires the buffers before we execute the kernel, and then releases them when we are done. This way we can safely work on the data without interfering with OpenGL or it interfering with our OpenCL.</p>
<p>The last thing to talk about is the cl code itself, but I&#8217;ve heavily commented the code so it will be easier to just go <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part2/part2.cl">read the file</a> :)</p>
<p>I hope this tutorial helps, please let me know if I&#8217;m mistaken anywhere so I can correct it for others reading! I&#8217;m learning a lot about <a href="http://enja.org/2010/08/06/particles-in-bge-update-collisions/">particle systems</a> for my master&#8217;s thesis at the <a href="http://www.facebook.com/FSUSciComp">Florida State University Department of Scientific Computing</a>!</p>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/RI3jFG-6gZo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/08/27/adventures-in-opencl-part-2-particles-with-opengl/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://enja.org/2010/08/27/adventures-in-opencl-part-2-particles-with-opengl/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=adventures-in-opencl-part-2-particles-with-opengl</feedburner:origLink></item>
		<item>
		<title>Particles in BGE Update: Collisions</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/UDJXW7lIdIo/</link>
		<comments>http://enja.org/2010/08/06/particles-in-bge-update-collisions/#comments</comments>
		<pubDate>Sat, 07 Aug 2010 00:10:27 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://enja.org/?p=272</guid>
		<description><![CDATA[We have collisions! Check out the video to see how it looks This is a preview of collisions working in our OpenCL Particle System addition to the Blender Game Engine. We can collide against triangle meshes of objects that are &#8230; <a href="http://enja.org/2010/08/06/particles-in-bge-update-collisions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We have collisions!<br />
Check out the <a href="http://www.youtube.com/watch?v=YvQFgY4kY68">video</a> to see how it looks<br />
<object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/YvQFgY4kY68&amp;hl=en_US&amp;fs=1?hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/YvQFgY4kY68&amp;hl=en_US&amp;fs=1?hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object></p>
<p>This is a preview of collisions working in our OpenCL Particle System addition to the Blender Game Engine. We can collide against triangle meshes of objects that are marked as colliders. The particle system and the objects can be manipulated through the logic bricks in real-time. The particles are also now rendered using global coordinates so that moving and rotating the emitter does not move the whole system.</p>
<p>On a Macbook Pro we can collide 1000 particles against 1000 triangles in a scene at about 50fps, with another advancement using bounding boxes to optimize that my <a href="http://www.facebook.com/FSUSciComp">DSC</a> advisor Gordon wrote we should see about a 5x speedup. I just need to implement it into Blender! Also if one uses a lot less triangles (or carefully chooses the meshes you want to collide against) you can maintain 60fps. For now I&#8217;m showing &#8220;worst case&#8221; performance until we tune it and add more options to compare it to (bounding box, bounding sphere).  On the GTX 480 (Fermi architecture) running on Ubuntu we can do 65k particles against the same 1000 triangles at 60fps. The fps doesn&#8217;t dip below 60 until about 100k particles.</p>
<p>Now that we see it working, I have a lot of cleaning up and benchmarking to do. Stay tuned for a more complete writeup!</p>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/UDJXW7lIdIo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/08/06/particles-in-bge-update-collisions/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://enja.org/2010/08/06/particles-in-bge-update-collisions/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=particles-in-bge-update-collisions</feedburner:origLink></item>
		<item>
		<title>Particles in BGE Update: GLSL, more options</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/u3rHla63F-0/</link>
		<comments>http://enja.org/2010/07/22/particles-in-bge-update-glsl-more-options/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 15:29:45 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[blender]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[opencl]]></category>

		<guid isPermaLink="false">http://enja.org/?p=262</guid>
		<description><![CDATA[So I&#8217;ve been making some headway with my OpenCL Particle Systems in the Blender Game Engine. I now have the option to render the particles with GLSL (Hi moguri, I&#8217;m going to need more help!), and I have improved my &#8230; <a href="http://enja.org/2010/07/22/particles-in-bge-update-glsl-more-options/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve been making some headway with my <a href="http://khronos.org/registry/cl">OpenCL</a> Particle Systems in the <a href="http://www.blender.org/">Blender Game Engine</a>. I now have the option to render the particles with GLSL (Hi <a href="http://mogurijin.wordpress.com/">moguri</a>, I&#8217;m going to need more help!), and I have improved my modifier to give UI access to several parameters, including which system of the few I&#8217;ve implemented you want to use.<br />
Check out the <a href="http://www.youtube.com/watch?v=kXi70eaClnQ">youtube screencast</a>:</p>
<p><object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/kXi70eaClnQ&amp;hl=en_US&amp;fs=1?hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/kXi70eaClnQ&amp;hl=en_US&amp;fs=1?hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>
<p>I also preview my initial attempts at using images (textures) with the particle system. My example is pretty crude, I just load in an image with OpenCV (there are other ways, but I want to <a href="http://mathnathan.com/2010/07/13/2opencv/">learn OpenCV</a> too) and generate particles in a grid with the color of each particle set to the pixel values of the image. The next step is to use actual OpenGL textures and then of course interface with Blender materials.</p>
<p>I still have lots of work ahead of me, I want to make interaction with the system only affect generators (this means dealing with world coordinates instead of local for manipulation and rendering), collision is high up on the list of things to do, and now that I have GLSL working I need to learn how to use it to make some cool and efficient effects! In addition I&#8217;m starting to learn <a href="http://en.wikipedia.org/wiki/Smoothed_particle_hydrodynamics">SPH</a> which I&#8217;m really looking forward to!</p>
<p>I want to shout out to the <a href="http://www.facebook.com/FSUSciComp">Department of Scientific Computing</a> for supporting this research, and check out our <a href="http://fsugd.blogspot.com/">Intro to Game Design</a> course we are offering again this fall!</p>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/u3rHla63F-0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/07/22/particles-in-bge-update-glsl-more-options/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://enja.org/2010/07/22/particles-in-bge-update-glsl-more-options/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=particles-in-bge-update-glsl-more-options</feedburner:origLink></item>
		<item>
		<title>Adventures in OpenCL: Part 1.5, C++ Bindings</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/KHCAxL20ARg/</link>
		<comments>http://enja.org/2010/07/20/adventures-in-opencl-part-1-5-cpp-bindings/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 04:02:12 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[advcl]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[opencl]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://enja.org/?p=248</guid>
		<description><![CDATA[This tutorial series is aimed at developers trying to learn OpenCL from the bottom up, with a focus on practicality. This part is a reworking of my first tutorial using the OpenCL C++ Bindings. Learning by example works best for &#8230; <a href="http://enja.org/2010/07/20/adventures-in-opencl-part-1-5-cpp-bindings/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This tutorial series is aimed at developers trying to learn <a href="http://www.khronos.org/opencl">OpenCL</a> from the bottom up, with a focus on practicality. This part is a reworking of my <a href="http://enja.org/2010/07/13/adventures-in-opencl-part-1-getting-started/">first tutorial</a> using the OpenCL C++ Bindings. Learning by example works best for me so make sure to <a href="http://github.com/enjalot/adventures_in_opencl">get the code</a>! It can only help you to have a copy of the <a href="http://www.khronos.org/registry/cl/">OpenCL specification handy</a>, and it doesn&#8217;t hurt (too bad) to read it!</p>
<p>My code works for me on my Macbook Pro (with Geforce 9400M) running Snow Leopard with the <a href="http://developer.nvidia.com/object/cuda_3_1_downloads.html">NVIDIA GPU SDK</a> as well as on the Ubuntu 10.4 workstations (with GTX 480 or Geforce 8800GTX). Unfortunately I haven&#8217;t spent any time developing on Windows so for now my tutorials will be UNIX centric (I would LOVE any help in setting up a windows environment, I&#8217;ll need to eventually for my <a href="http://enja.org/2010/05/20/blender-and-opencl-the-journey-begins/">Blender project</a>). Also the code should build against the ATI Stream SDK and run on the runtime, you can assume I&#8217;m complying with OpenCL 1.0 (1.1 may be covered in the more advanced topics, and I&#8217;ll point it out). Please let me know if you have build problems or device issues! Throughout the tutorial I will refer to device and GPU interchangeably, OpenCL can run on CPUs already and is targeting many other devices, but for now I&#8217;m assuming a <a href="http://gpgpu.org/">GPGPU</a> bias.</p>
<h2>Let&#8217;s get started!</h2>
<p>You&#8217;ll need to have installed:</p>
<p><a href="http://developer.nvidia.com/object/cuda_3_1_downloads.html">NVIDIA</a> or <a href="http://developer.amd.com/gpu/atistreamsdk/pages/default.aspx">ATI</a> GPU SDK and OpenCL enabled drivers<br />
(Ubuntu ATI users might like <a href="http://mathnathan.com/2010/08/30/opencl/">extra guidance</a>)<br />
<a href="http://www.cmake.org/cmake/resources/software.html"> CMake</a> (<a href="http://mathnathan.com/2010/07/11/getting-started-with-cmake/">introduction</a> and <a href="http://www.elpauer.org/stuff/learning_cmake.pdf">in-depth tutorial [pdf]</a>)<br />
and it helps to have <a href="http://git-scm.com/">Git</a> (<a href="http://mathnathan.com/2010/07/09/git/">introduction</a> and <a href="http://progit.org/book/">nice book</a>)</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl">Download the code</a> and for the rest of the tutorial I will refer to the directory it&#8217;s in as <span class="simple_code">advcl</span></p>
<p>In the advcl directory you should have the following directories:</p>
<pre>part1.5/     //the source code files for this tutorial
cmake/       //CMake scripts that help locate necessary libraries
opencl10/    //OpenCL 1.0 header files (downloaded from <a href="http://www.khronos.org/registry/cl/">Khronos.org</a>)
opencl11/    //OpenCL 1.1 header files (downloaded from <a href="http://www.khronos.org/registry/cl/">Khronos.org</a>)
</pre>
<p>First we will build the code to make sure it works, I like to do an &#8220;out of source&#8221; build like so:</p>
<pre class="brush: bash;">cd part1.5
mkdir build
cd build
cmake ..
make
</pre>
<p>This will generate all of the build files, the Makefile, the library and executable in the build directory which avoids cluttering up your source code directory. You can run the example like so:</p>
<pre class="brush: bash;">./part1.x</pre>
<h2>The Source Code Files </h2>
<p>Let&#8217;s first have a broad overview of each of the source files and then we can dive in and look at what the code is doing. I&#8217;ve the code up to be a library with a CL class that can be instantiated and utilized anywhere. For this tutorial it is not very generalized so that it&#8217;s easier to see what&#8217;s going on behind the scenes. In future tutorials we will refactor and make our library more powerful!</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1.5/main.cpp">main.cpp</a><br />
This is where we test out our CL class. We instantiate it, give it an opencl program to compile and run, then execute the kernel.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1.5/cll.h">cll.h</a><br />
The main header file for our CL class definition, also handles including the OpenCL libraries. I&#8217;ve downloaded the header files from the <a href="http://khronos.org/registry/cl">Khronos website</a> to avoid having to search the computer for a particular SDK.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1.5/cll.cpp">cll.cpp</a><br />
The core implementation of our CL class, including functions for initializing the OpenCL context, loading and building an OpenCL program.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1.5/part1.cpp">part1.cpp</a><br />
Implementation of the functions that setup and run the OpenCL kernel. This is where we actually see OpenCL in action. </p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1.5/part1.cl">part1.cl</a><br />
The actual OpenCL code to be executed. Right now it&#8217;s a simple kernel that adds two arrays and stores the result in a third.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1.5/util.h">util.h</a> and <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1.5/util.cpp">util.cpp</a><br />
Utility functions that make things like reading files or printing out OpenCL error messages easier</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1.5/CMakeLists.txt">CMakeLists.txt</a><br />
The configuration and build script used to build the project. This makes it easier to be portable, and building our code as a library makes it easier to contribute to other projects.</p>
<h2>The Source Code Contents</h2>
<p>Let&#8217;s follow the execution of the main function to see what order things need to be done in. Of course we need to include our library&#8217;s definitions:</p>
<pre class="brush: cpp;">#include &quot;cll.h&quot;</pre>
<p>This includes the OpenCL headers as well as defines our CL class. If you look there you will see a few public member objects of type <span class="simple_code">cl::Buffer</span> which will point to arrays on our device. The private <span class="simple_code">cl::*</span> member objects are key OpenCL objects which we will use in the constructor to setup OpenCL for execution.<br />
The constructor is defined in cll.cpp where it does a few things: sets the platform, sets the device to use, creates the OpenCL context and a command queue. Let&#8217;s see how its done:</p>
<pre class="brush: cpp;">    std::vector&lt;cl::Platform&gt; platforms;
    cl::Platform::get(&amp;platforms);
    printf(&quot;cl::Platform::get(): %s\n&quot;, oclErrorString(err));</pre>
<p>This is the first example of the nice cl wrapper class specified in the C++ bindings where we get the device Platforms. As you can see it is much cleaner than <a href="http://enja.org/2010/07/13/adventures-in-opencl-part-1-getting-started/">the previous code</a>. The 3rd line is something you will see peppered throughout the code, <span class="simple_code">oclErrorString(err)</span> is a useful helper function I lifted from the NVIDIA SDK that gives you a little more info about what went wrong if you have a problem. You can get some more explanation of the different error types if you go to the khronos specification for the function that errored, for example <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clGetDeviceIDs.html">clGetDeviceIDs</a> (a quick google search for the function name generally returns the khronos page first).</p>
<p>After we set the platform (for now we just select the first platform in the list), we use it to create a context. For this tutorial we choose the GPU to be the device. This could of course become more sophisticated with multiple graphics cards or other devices, and in another tutorial we will discuss checking for device capabilities.</p>
<pre class="brush: cpp;">
    cl_context_properties properties[] =
        { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0};
    context = cl::Context(CL_DEVICE_TYPE_GPU, properties);
    devices = context.getInfo&lt;CL_CONTEXT_DEVICES&gt;();
</pre>
<p>and the last action of the constructor is to create the command queue</p>
<pre class="brush: cpp;">
    deviceUsed = 0;
    try{
        queue = cl::CommandQueue(context, devices[deviceUsed], 0, &amp;err);
    }
    catch (cl::Error er) {
        printf(&quot;ERROR: %s(%d)\n&quot;, er.what(), er.err());
    }
</pre>
<p>Here you see some use of exceptions provided by <a href="http://www.khronos.org/registry/cl/api/1.1/cl.hpp">cl.hpp</a>, note it is necessary to set</p>
<pre class="brush: cpp;">#define __CL_ENABLE_EXCEPTIONS</pre>
<p> as I did at the top of cll.h.</p>
<p>Once the constructor is finished, we want to load our OpenCL program, so in main.cpp we do:</p>
<pre class="brush: cpp;">
#include &quot;part1.cl&quot;
example.loadProgram(&quot;part1.cl&quot;);</pre>
<p>You may wonder why we have an include here, I find it a nice way to bundle our OpenCL source with our library using a neat little <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1.5/part1.cl">macro trick</a>.<br />
<span class="simple_code">loadProgram</span> is defined in cll.cpp:</p>
<pre class="brush: cpp;">
    int pl;
    cl::Program::Sources source(1,
        std::make_pair(kernel_source,pl));
    program = cl::Program(context, source);</pre>
<p>Once the program is created, it must also be compiled. It also helps to have some compiler output incase we have syntax errors (never!).</p>
<pre class="brush: cpp;">
    err = program.build(devices);
    printf(&quot;program.build: %s\n&quot;, oclErrorString(err));
    if(err != CL_SUCCESS){
        std::cout &lt;&lt; &quot;Build Status: &quot; &lt;&lt; program.getBuildInfo&lt;CL_PROGRAM_BUILD_STATUS&gt;(devices[0]) &lt;&lt; std::endl;
        std::cout &lt;&lt; &quot;Build Options:\t&quot; &lt;&lt; program.getBuildInfo&lt;CL_PROGRAM_BUILD_OPTIONS&gt;(devices[0]) &lt;&lt; std::endl;
        std::cout &lt;&lt; &quot;Build Log:\t &quot; &lt;&lt; program.getBuildInfo&lt;CL_PROGRAM_BUILD_LOG&gt;(devices[0]) &lt;&lt; std::endl;
    }
</pre>
<p>Once the program is loaded and built we are ready to pass the data to our device and do some computing! Let&#8217;s take a quick look at our simple kernel in part1.cl so we have an idea of what we are trying to do:</p>
<pre class="brush: cpp;">__kernel void part1(__global float* a, __global float* b, __global float* c)
{
    unsigned int i = get_global_id(0);
    c[i] = a[i] + b[i];
}</pre>
<p>Since I&#8217;m still forming my understanding of OpenCL I&#8217;ll avoid explaining the details (you and me both gotta read the spec! or check out some of NVIDIA&#8217;s nice webinars). This serves as a practical starting point for you to write your own kernels, so lets see what I&#8217;m doing here.<br />
I define my kernel as <span class="simple_code">part1</span> and it takes in three paramaters. The <span class="simple_code">__global</span> keyword says what kind of device memory our input is stored in, and besides that we should already be familiar with passing arrays to functions as a pointer.</p>
<p>One way to think of the kernel is as a replacement for a for loop (you can do much cooler things, but we gotta start somewhere). We get the index in the for loop from the get_global_id built in function, and then we do our operation on the arrays at that index. We let OpenCL split up the arrays into work-units  and it will try to do as many of them as possible in parallel.</p>
<p>So how do we give OpenCL our arrays and tell it to do the work? That&#8217;s all in <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/part1.cpp">part1.cpp</a><br />
We setup our kernel with the <span class="simple_code">popCorn</span> function (hehe)<br />
First we go ahead and call it (with error checking)</p>
<pre class="brush: cpp;">
    try{
        kernel = cl::Kernel(program, &quot;part1&quot;, &amp;err);
    }
    catch (cl::Error er) {
        printf(&quot;ERROR: %s(%d)\n&quot;, er.what(), er.err());
    }
</pre>
<p>Notice that the string we pass in is the name of the kernel as we defined it in the .cl file.<br />
Then we setup the arrays we want to work on, I created a trivial example as you can see in the file. The important part is creating the OpenCL array buffers and pushing the data to the device:</p>
<pre class="brush: cpp;">
    size_t array_size = sizeof(float) * num;
    //our input arrays
    cl_a = cl::Buffer(context, CL_MEM_READ_ONLY, array_size, NULL, &amp;err);
    cl_b = cl::Buffer(context, CL_MEM_READ_ONLY, array_size, NULL, &amp;err);
    //our output arrayw
    cl_c = cl::Buffer(context, CL_MEM_WRITE_ONLY, array_size, NULL, &amp;err);
</pre>
<p>Note that our input are defined as read buffers, and our output is a write, there is also CL_MEM_READ_WRITE, and these are suggestions to the device on how you will use the buffers so it can optimize for performance.<br />
Pushing the data is the same for each one:</p>
<pre class="brush: cpp;">err = queue.enqueueWriteBuffer(cl_a, CL_TRUE, 0, array_size, a, NULL, &amp;event);</pre>
<p>Then we tell the kernel which buffers correspond to which arguments</p>
<pre class="brush: cpp;">
    err = kernel.setArg(0, cl_a);
    err = kernel.setArg(1, cl_b);
    err = kernel.setArg(2, cl_c);
</pre>
<p>You can also pass in other types of arguments, but we should see that in the next installment.<br />
We introduce</p>
<pre class="brush: cpp;">queue.finish();</pre>
<p>Which makes sure that all commands in the queue are done executing before the program continues. This will be more important in later tutorials where we run our kernel in a loop as fast as possible.<br />
For now we just run it once in the <span class="simple_code">runKernel()</span> function:</p>
<pre class="brush: cpp;">err = queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(num), cl::NullRange, NULL, &amp;event);</pre>
<p>The <span class="simple_code">cl::NDRange(num)</span> is the global workgroup size, and is one-dimensional like our arrays.<br />
Finally, we read from our device memory to see if the c array got updated the way we expected!</p>
<pre class="brush: cpp;">float *c_done;
err = queue.enqueueReadBuffer(cl_c, CL_TRUE, 0, sizeof(float) * num, c_done, NULL, &amp;event);</pre>
<p>now we can simply print out the contents of the c_done array!</p>
<pre class="brush: cpp;">for(int i=0; i &lt; num; i++)
{
    printf(&quot;c_done[%d] = %g\n&quot;, i, c_done[i]);
}</pre>
<p>Hopefully the code and this walk-through give you a good starting point to learn more. Expect more tutorials, with the next one involving the OpenCL Profiler and determining device information, followed by OpenCL/OpenGL context sharing.<br />
I definitely appreciate any feedback!</p>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/KHCAxL20ARg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/07/20/adventures-in-opencl-part-1-5-cpp-bindings/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://enja.org/2010/07/20/adventures-in-opencl-part-1-5-cpp-bindings/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=adventures-in-opencl-part-1-5-cpp-bindings</feedburner:origLink></item>
		<item>
		<title>Adventures in OpenCL: Part 1, Getting Started</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/E7lCXCJgc2M/</link>
		<comments>http://enja.org/2010/07/13/adventures-in-opencl-part-1-getting-started/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 08:31:38 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[advcl]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[opencl]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://enja.org/?p=218</guid>
		<description><![CDATA[This tutorial series is aimed at developers trying to learn OpenCL from the bottom up, with a focus on practicality (i.e. I&#8217;m still learning, I&#8217;m sharing what I&#8217;ve found to work). Learning by example works best for me so make &#8230; <a href="http://enja.org/2010/07/13/adventures-in-opencl-part-1-getting-started/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This tutorial series is aimed at developers trying to learn <a href="http://www.khronos.org/opencl">OpenCL</a> from the bottom up, with a focus on practicality (i.e. I&#8217;m still learning, I&#8217;m sharing what I&#8217;ve found to work). Learning by example works best for me so make sure to <a href="http://github.com/enjalot/adventures_in_opencl">get the code</a>! It can only help you to have a copy of the <a href="http://www.khronos.org/registry/cl/">OpenCL specification handy</a>, and it doesn&#8217;t hurt (too bad) to read it!</p>
<p>NOTE: If you are interested in using the C++ Bindings, I recommend you check out my <a href="http://enja.org/2010/07/20/adventures-in-opencl-part-1-5-cpp-bindings/">revision of this tutorial</a>.</p>
<p>My code works for me on my Macbook Pro (with Geforce 9400M) running Snow Leopard with the <a href="http://developer.nvidia.com/object/cuda_3_1_downloads.html">NVIDIA GPU SDK</a> as well as on the Ubuntu 10.4 workstations (with GTX 480 or Geforce 8800GTX). Unfortunately I haven&#8217;t spent any time developing on Windows so for now my tutorials will be UNIX centric (I would LOVE any help in setting up a windows environment, I&#8217;ll need to eventually for my <a href="http://enja.org/2010/05/20/blender-and-opencl-the-journey-begins/">Blender project</a>). Also the code should build against the ATI Stream SDK and run on the runtime, you can assume I&#8217;m complying with OpenCL 1.0 (1.1 may be covered in the more advanced topics, and I&#8217;ll point it out). Please let me know if you have build problems or device issues! Throughout the tutorial I will refer to device and GPU interchangeably, OpenCL can run on CPUs already and is targeting many other devices, but for now I&#8217;m assuming a <a href="http://gpgpu.org/">GPGPU</a> bias.</p>
<h2>Let&#8217;s get started!</h2>
<p>You&#8217;ll need to have installed:</p>
<p><a href="http://developer.nvidia.com/object/cuda_3_1_downloads.html">NVIDIA</a> or <a href="http://developer.amd.com/gpu/atistreamsdk/pages/default.aspx">ATI</a> GPU SDK and OpenCL enabled drivers<br />
<span style="font-size: 15.6px;">(Ubuntu ATI users might like <a href="http://mathnathan.com/2010/08/30/opencl/">extra guidance</a>)</span><br />
<a href="http://www.cmake.org/cmake/resources/software.html"> CMake</a> (<a href="http://mathnathan.com/2010/07/11/getting-started-with-cmake/">introduction</a> and <a href="http://www.elpauer.org/stuff/learning_cmake.pdf">in-depth tutorial [pdf]</a>)<br />
and it helps to have <a href="http://git-scm.com/">Git</a> (<a href="http://mathnathan.com/2010/07/09/git/">introduction</a> and <a href="http://progit.org/book/">nice book</a>)</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl">Download the code</a> and for the rest of the tutorial I will refer to the directory it&#8217;s in as <span class="simple_code">advcl</span></p>
<p>In the advcl directory you should have the following directories:</p>
<pre>part1/       //the source code files for this tutorial
part1.5/     //the source code for the part1.5 (C++ bindings)
cmake/       //CMake scripts that help locate necessary libraries
opencl10/    //OpenCL 1.0 header files (downloaded from <a href="http://www.khronos.org/registry/cl/">Khronos.org</a>)
opencl11/    //OpenCL 1.1 header files (downloaded from <a href="http://www.khronos.org/registry/cl/">Khronos.org</a>)</pre>
<p>First we will build the code to make sure it works, I like to do an &#8220;out of source&#8221; build like so:</p>
<pre class="brush: bash;">cd part1
mkdir build
cd build
cmake ..
make
</pre>
<p>This will generate all of the build files, the Makefile, the library and executable in the build directory which avoids cluttering up your source code directory. You can run the example like so:</p>
<pre class="brush: bash;">./part1.x</pre>
<h2>The Source Code Files</h2>
<p>Let&#8217;s first have a broad overview of each of the source files and then we can dive in and look at what the code is doing. I&#8217;ve the code up to be a library with a CL class that can be instantiated and utilized anywhere. For this tutorial it is not very generalized so that it&#8217;s easier to see what&#8217;s going on behind the scenes. In future tutorials we will refactor and make our library more powerful!</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/main.cpp">main.cpp</a><br />
This is where we test out our CL class. We instantiate it, give it an opencl program to compile and run, then execute the kernel.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/cll.h">cll.h</a><br />
The main header file for our CL class definition, also handles including the OpenCL libraries on both Linux and Mac.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/cll.cpp">cll.cpp</a><br />
The core implementation of our CL class, including functions for initializing the OpenCL context, loading and building an OpenCL program and cleaning up the GPU memory we used.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/part1.cpp">part1.cpp</a><br />
Implementation of the functions that setup and run the OpenCL kernel. This is where we actually see OpenCL in action.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/part1.cl">part1.cl</a><br />
The actual OpenCL code to be executed. Right now it&#8217;s a simple kernel that adds two arrays and stores the result in a third.</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/util.h">util.h</a> and <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/util.cpp">util.cpp</a><br />
Utility functions that make things like reading files or printing out OpenCL error messages easier</p>
<p><a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/CMakeLists.txt">CMakeLists.txt</a><br />
The configuration and build script used to build the project. This makes it easier to be portable, and building our code as a library makes it easier to contribute to other projects.</p>
<h2>The Source Code Contents</h2>
<p>Let&#8217;s follow the execution of the main function to see what order things need to be done in. Of course we need to include our library&#8217;s definitions:</p>
<pre class="brush: cpp;">#include &quot;cll.h&quot;</pre>
<p>This includes the OpenCL headers as well as defines our CL class. If you look there you will see a few public members of type <span class="simple_code">cl_mem</span> which will point to arrays on our device. The private <span class="simple_code">cl_*</span> members are handles to key OpenCL objects which we will use in the constructor to setup OpenCL for execution.<br />
The constructor is defined in cll.cpp where it does a few things: sets the platform, sets the device to use, creates the OpenCL context and a command queue. Let&#8217;s see how its done:</p>
<pre class="brush: cpp;">err = oclGetPlatformID(&amp;platform);
printf(&quot;oclGetPlatformID: %s\n&quot;, oclErrorString(err));</pre>
<p>The <span class="simple_code">oclGetPlatformID</span> function is a helper function defined in util.cpp I lifted from the NVIDIA SDK (I figure they won&#8217;t mind for educational purposes but it&#8217;s not under a free license so be careful!). This function looks for the NVIDIA platform and defaults to the first available one if its not found (&#8220;Apple&#8221; is the only platform on my Mac). The 2nd line is something you will see peppered throughout the code, <span class="simple_code">oclErrorString(err)</span> is another useful NVIDIA helper function that gives you a little more info about what went wrong if you have a problem. You can get some more explanation of the different error types if you go to the khronos specification for the function that errored, for example <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clGetDeviceIDs.html">clGetDeviceIDs</a> (a quick google search for the function name generally returns the khronos page first).</p>
<p>After we set the platform, we use it to select a device. In this code we get a list of the available devices but we end up just choosing the first in the list. This could of course become more sophisticated with multiple graphics cards, and in another tutorial we will discuss checking for device capabilities.</p>
<pre class="brush: cpp;">
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &amp;numDevices);
devices = new cl_device_id [numDevices];
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);
deviceUsed = 0;</pre>
<p>Note that we hardcoded the device type to be GPU, you can check the specification for the others but I&#8217;ll give you a hint that one of them starts with CL and ends with CPU ;)<br />
Now we can make an <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateContext.html">OpenCL context</a> using our device (the more advanced options like sharing an OpenGL context will come in a following tutorial):</p>
<pre class="brush: cpp;">context = clCreateContext(0, 1, &amp;devices[deviceUsed], NULL, NULL, &amp;err);</pre>
<p>and the last action of the constructor is to create the command queue</p>
<pre class="brush: cpp;">command_queue = clCreateCommandQueue(context, devices[deviceUsed], 0, &amp;err);</pre>
<p>Once the constructor is finished, we want to load our OpenCL program, so in main.cpp we call</p>
<pre class="brush: cpp;">example.loadProgram(&quot;part1.cl&quot;);</pre>
<p><span class="simple_code">loadProgram</span> is defined in cll.cpp, it simply reads in the .cl file as a string and passes the string to</p>
<pre class="brush: cpp;">program = clCreateProgramWithSource(context, 1, (const char **) &amp;cSourceCL, &amp;program_length, &amp;err);</pre>
<p>Here we load only one string of <span class="simple_code">program_length</span> characters, but you could do more at once.<br />
Once the program is created, it must also be compiled so we call the private function <span class="simple_code">buildExecutable</span> to do that. It has some nice error checking that will output the build log if you have syntax errors in your OpenCL code. I won&#8217;t detail it here but check out the <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/cll.cpp">bottom of the cll.cpp</a> file.</p>
<p>Once the program is loaded and built we are ready to pass the data to our device and do some computing! Let&#8217;s take a quick look at our simple kernel in part1.cl so we have an idea of what we are trying to do:</p>
<pre class="brush: cpp;">__kernel void part1(__global float* a, __global float* b, __global float* c)
{
    unsigned int i = get_global_id(0);
    c[i] = a[i] + b[i];
}</pre>
<p>Since I&#8217;m still forming my understanding of OpenCL I&#8217;ll avoid explaining the details (you and me both gotta read the spec! or check out some of NVIDIA&#8217;s nice webinars). This serves as a practical starting point for you to write your own kernels, so lets see what I&#8217;m doing here.<br />
I define my kernel as <span class="simple_code">part1</span> and it takes in three paramaters. The <span class="simple_code">__global</span> keyword says what kind of device memory our input is stored in, and besides that we should already be familiar with passing arrays to functions as a pointer.</p>
<p>One way to think of the kernel is as a replacement for a for loop (you can do much cooler things, but we gotta start somewhere). We get the index in the for loop from the get_global_id built in function, and then we do our operation on the arrays at that index. We let OpenCL split up the arrays into work-units  and it will try to do as many of them as possible in parallel.</p>
<p>So how do we give OpenCL our arrays and tell it to do the work? That&#8217;s all in <a href="http://github.com/enjalot/adventures_in_opencl/blob/master/part1/part1.cpp">part1.cpp</a><br />
We setup our kernel with the <span class="simple_code">popCorn</span> function (hehe)<br />
First we go ahead and call</p>
<pre class="brush: cpp;">kernel = clCreateKernel(program, &quot;part1&quot;, &amp;err);</pre>
<p>Then we setup the arrays we want to work on, I created a trivial example as you can see in the file. The important part is creating the OpenCL array buffers and pushing the data to the device:</p>
<pre class="brush: cpp;">//our input arrays
cl_a = clCreateBuffer(context, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR, sizeof(float) * num, a, &amp;err);
cl_b = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(float) * num, NULL, &amp;err);
//our output array
cl_c = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(float) * num, NULL, &amp;err);
</pre>
<p>Note that our input are defined as read buffers, and our output is a write, there is also CL_MEM_READ_WRITE, and these are suggestions to the device on how you will use the buffers so it can optimize for performance. For the a array the clCreateBuffer function copies the data from the CPU to the GPU for us. If you want to separate creating the buffer from pushing the data you can do the data push as a separate call:</p>
<pre class="brush: cpp;">err = clEnqueueWriteBuffer(command_queue, cl_b, CL_TRUE, 0, sizeof(float) * num, b, 0, NULL, &amp;event);</pre>
<p>Then we tell the kernel which buffers correspond to which arguments</p>
<pre class="brush: cpp;">err  = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *) &amp;cl_a);
err  = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *) &amp;cl_b);
err  = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *) &amp;cl_c);
</pre>
<p>You can also pass in other types of arguments, but we should see that in the next example.<br />
We introduce</p>
<pre class="brush: cpp;">clFinish(command_queue);</pre>
<p>Which makes sure that all commands in the queue are done executing before the program continues. This will be more important in later tutorials where we run our kernel in a loop as fast as possible.<br />
For now we just run it once in the <span class="simple_code">runKernel()</span> function:</p>
<pre class="brush: cpp;">err = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, workGroupSize, NULL, 0, NULL, &amp;event);</pre>
<p>The workGroupSize is defined to be the same size as our data arrays, and so it is 1 dimensional. This will be much more interesting with more complex kernels, but for now we just make them the same.<br />
Finally, we read from our device memory to see if the c array got updated the way we expected!</p>
<pre class="brush: cpp;">float *c_done;
err = clEnqueueReadBuffer(command_queue, cl_c, CL_TRUE, 0, sizeof(float) * num, c_done, 0, NULL, &amp;event);</pre>
<p>now we can simply print out the contents of the c_done array!</p>
<pre class="brush: cpp;">for(int i=0; i &lt; num; i++)
{
    printf(&quot;c_done[%d] = %g\n&quot;, i, c_done[i]);
}</pre>
<p>Hopefully the code and this walk-through give you a good starting point to learn more. Expect more tutorials, with the next one involving the OpenCL Profiler and determining device information, followed by OpenCL/OpenGL context sharing.<br />
I definitely appreciate any feedback!</p>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/E7lCXCJgc2M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/07/13/adventures-in-opencl-part-1-getting-started/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://enja.org/2010/07/13/adventures-in-opencl-part-1-getting-started/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=adventures-in-opencl-part-1-getting-started</feedburner:origLink></item>
		<item>
		<title>20 million particles in OpenCL on the GTX480</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/XiBl3uBaC_s/</link>
		<comments>http://enja.org/2010/07/09/20-million-particles-in-opencl-on-the-gtx480/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 06:11:57 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[blender]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[opencl]]></category>

		<guid isPermaLink="false">http://enja.org/?p=208</guid>
		<description><![CDATA[I&#8217;m trying to push the limits of interactive scientific visualization, so I gotta start somewhere! Ok, so 20 million particles running at ~40fps is not a bad start, but this is also using the simplest rendering possible (GL_POINTS of size &#8230; <a href="http://enja.org/2010/07/09/20-million-particles-in-opencl-on-the-gtx480/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m trying to push the limits of interactive <a href="http://sc.fsu.edu/vislab">scientific visualization</a>, so I gotta start somewhere! Ok, so 20 million particles running at ~40fps is not a bad start, but this is also using the simplest rendering possible (GL_POINTS of size 1, with no alpha blending or lighting).</p>
<p>I&#8217;m running <a href="http://github.com/enjalot/EnjaParticles">my code</a> on Ubuntu 10.04 on a Dell Precision T7500 with a <a href="http://www.nvidia.com/object/product_geforce_gtx_480_us.html">NVIDIA GTX480</a> (1.5GB GDDR5). The machine has 12GB of ram and 8 cores of CPU which don&#8217;t get used at all by this (besides to initialize the system and run the main loop of course). Check out <a href="http://www.youtube.com/watch?v=FnrC3_8bhQ0">the video</a> to see some pretty patterns and a large amount of particles!</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/FnrC3_8bhQ0&amp;hl=en_US&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="640" height="385" src="http://www.youtube.com/v/FnrC3_8bhQ0&amp;hl=en_US&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>A quick note for those waiting for these in Blender, currently I have it working but only with about 100k particles if I use a Mesh as the emitter (any more and Blender starts choking before I get in the game engine). I&#8217;m going to start looking at the existing particle interface (as well as the <a href="http://wiki.blender.org/index.php/User:Phonybone/Particle_systems_thoughts">redesign</a>) to start integrating tighter into Blender now that I&#8217;m getting comfortable with OpenCL/OpenGL.</p>
<p>Let&#8217;s talk some math and look at some numbers, if that doesn&#8217;t sound fun it&#8217;s ok to stop reading now ;)</p>
<p>So first let me admit that this OpenCL kernel is not doing that much work. I&#8217;m solving the <a href="http://en.wikipedia.org/wiki/Lorenz_attractor">Lorenz Attractor</a> ODEs with the <a href="http://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods">RK4</a> method for each particle. It&#8217;s all embarrassingly parallel and there is no interaction between them. Second, I tuned down the rendering so it&#8217;s doing as little as possible. This lets us get to the memory limit of the GTX480 at 20 million particles with my setup. Lets see why:</p>
<p>I use float4 arrays (OpenCL variables of 4 32bit floats in a row) for vertices, colors, generators and velocities. I use one float array to keep track of the life of each particle.</p>
<p>4 (arrays) x 20,000,000 (particles) x 4 (floats) x 4 (bytes) = 1,280,000,000 bytes</p>
<p>1 (array) x 20,000,000 (particles) x 1 (float) x 4 (bytes) = 80,000,000 bytes</p>
<p>So thats 1,360,000,000 bytes / 1024E3 = 1.267GB of memory on the graphics card!</p>
<p>Luckily I&#8217;m using OpenGL interop, so the vertices and color array are actually <a href="http://www.songho.ca/opengl/gl_vbo.html">VBOs</a> in OpenGL&#8217;s context and are modified in place. Since that&#8217;s the case we don&#8217;t transfer any of that memory back to the CPU, which would be a serious problem. It&#8217;s possible my kernel could be optimized more, but right now memory and rendering are the limiting factors. When I start implementing more interesting physics like collision detection and fluid dynamics this will be a bigger issue. I&#8217;m also planning to implement depth sorting using an index array VBO so I can render cool effects with proper alpha blending. This of course will also limit the number of particles possible, with my guess being that rendering will be the biggest culprit (not memory).</p>
<div id="attachment_212" class="wp-caption aligncenter" style="width: 650px"><a href="http://enja.org/wp-content/uploads/2010/07/1mill_lorentz.png"><img class="size-large wp-image-212" title="1 million particles" src="http://enja.org/wp-content/uploads/2010/07/1mill_lorentz-1024x622.png" alt="1 million particles" width="640" height="388" /></a><p class="wp-caption-text">1 million particles with alpha blending and pointsize=10</p></div>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/XiBl3uBaC_s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/07/09/20-million-particles-in-opencl-on-the-gtx480/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://enja.org/2010/07/09/20-million-particles-in-opencl-on-the-gtx480/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=20-million-particles-in-opencl-on-the-gtx480</feedburner:origLink></item>
		<item>
		<title>Blender Game Engine: Particles in the Mix</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/pAIF4dySufM/</link>
		<comments>http://enja.org/2010/06/30/blender-game-engine-particles-in-the-mix/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 03:46:43 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[blender]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[opencl]]></category>

		<guid isPermaLink="false">http://enja.org/?p=198</guid>
		<description><![CDATA[I think I can show you better than I can tell you check out the code This is the first major milestone in my journey! I&#8217;ve got a lot of work to do before this is in any usable condition &#8230; <a href="http://enja.org/2010/06/30/blender-game-engine-particles-in-the-mix/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I think I can show you better than I can tell you</p>
<p><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/lP6zfAVm7B0&amp;hl=en_US&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/lP6zfAVm7B0&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p>
<p><a href="http://github.com/enjalot/BGEnjaParticles">check out the code</a></p>
<p>This is the first major milestone in my <a href="http://enja.org/2010/05/20/blender-and-opencl-the-journey-begins/">journey</a>! I&#8217;ve got a lot of work to do before this is in any usable condition for artists, but none the less it feels good to see my OpenCL Particle System and interact with it through the Blender Game Engine. Right now I&#8217;ve linked to my <a href="http://github.com/enjalot/EnjaParticles">EnjaParticles</a> library from Blender, I create a system using a custom modifier (called Enja for now) on an object and if the modifier is present I divert rendering of that object to a custom function.</p>
<p>My next step is to get a better understanding of all the OpenGL magic going on because my colors and alpha blending are not behaving as expected. At the same time I&#8217;m thinking I&#8217;ll rewrite the particle system code inside the BGE and start looking at how the existing particle system works. I&#8217;m going to start with a small subset of the existing functionality, so please let me know if you&#8217;re dying to have a certain particle effect in the game engine so I can prioritize better, otherwise I&#8217;ll just do what looks the most fun.</p>
<p>I want to spend some more time thinking about handling the OpenCL context, perhaps loading it, building the programs and preparing the kernels when the game engine starts. Right now an entirely new context is created for each system which seems quite wasteful. I also need to clean up the build process, which should be helped by moving the code internal to blender, but making OpenCL available to the whole of blender might encourage other developers to try their hand at accelerating other areas.</p>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/pAIF4dySufM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/06/30/blender-game-engine-particles-in-the-mix/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://enja.org/2010/06/30/blender-game-engine-particles-in-the-mix/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=blender-game-engine-particles-in-the-mix</feedburner:origLink></item>
		<item>
		<title>Simple Particles with OpenCL and OpenGL</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/8g-bdTu8iBA/</link>
		<comments>http://enja.org/2010/06/26/simple-particles-with-opencl-and-opengl/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 17:44:55 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[blender]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[opencl]]></category>

		<guid isPermaLink="false">http://enja.org/?p=183</guid>
		<description><![CDATA[And so I reach another milestone in my journey to put OpenCL Particles in Blender! I&#8217;ve written my own (very) simple particle system from scratch in C++ using OpenGL and OpenCL, taking advantage of VBO interoperability. OpenCL and OpenGL interop &#8230; <a href="http://enja.org/2010/06/26/simple-particles-with-opencl-and-opengl/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>And so I reach another milestone in my journey to put <a href="http://enja.org/2010/05/20/blender-and-opencl-the-journey-begins/">OpenCL Particles in Blender</a>! I&#8217;ve written my own (very) simple particle system from scratch in C++ using OpenGL and OpenCL, taking advantage of <a href="http://www.songho.ca/opengl/gl_vbo.html">VBO</a> interoperability. OpenCL and OpenGL interop is all about keeping the processing on the GPU, so the array of vertices you are drawing from and the array of vertices you are moving around are actually pointers to the same spot in GPU memory. This saves lots of time, especially if you are manipulating millions of particles in real time and you don&#8217;t want to transfer megabytes of data back and forth each frame!</p>
<p><a href="http://github.com/enjalot/EnjaParticles">Check out the code</a></p>
<p>I based my work on the NVIDIA GPU SDK example oclSimpleGL, but I wanted to make my code a standalone library that could be popped into some other graphics context (namely Blender). I was able to nicely separate my code into relevant files: opencl.cpp for opencl functions, enja.cpp for all the particle stuff and main.cpp is responsible for the window/GLUT and rendering stuff. Instantiating an EnjaParticles class creates a system and populates two VBOs, one for vertices and one for colors as well as an OpenCL context and all the necessary OpenCL variables. All one has to do is call the update function and the OpenCL kernel is executed, automatically updating the vbos which can be rendered by OpenGL. Right now the constructor for the particle system only takes in an array for vertices (which I intend to get from a DerivedMesh object in Blender) and makes the VBO ids available so the rendering context can use them.</p>
<p>The code currently compiles and runs on both Ubuntu with NVIDIA drivers on a GTX480 (yeah baby!) and my Macbook Pro with NVIDIA GeForce 9400M (it shouldn&#8217;t be hard to port to windows but I don&#8217;t have time for that now). I use CMAKE so check out the README to make sure you configure your environment correctly (you need to set up a couple environment variables so it can find the right headers to include and libraries to link against). In the CMakeLists.txt file you can also turn GL_INTEROP on and off if you want to see the performance difference. This code also runs in the OpenCL Visual Profiler, which <a href="http://forums.nvidia.com/index.php?showtopic=107840">wasn&#8217;t the easiest thing</a> to get working. You need to be very careful not only with the OpenCL objects you instantiate, but ones that implicitly get created by calling cl functions! Once it works it&#8217;s very nice for seeing how your code is behaving on the GPU.</p>
<p>I&#8217;ve noticed that on my MacBook Pro the GL/CL interop is not behaving as expected, and I suspect that there is still memory being transfered. Without the opencl profiler I will have to do my own timings to get to the bottom of this. Adding to my suspicion is that there is no difference in performance for the oclSimpleGL example on my MBP.</p>
<p>It took me over a week to get this working like I expected to, I don&#8217;t intend it for it to take that long to get it into Blender. I really want to start working on interesting stuff like Rigid Body collision and python interaction, let alone more complex physics!</p>
<div id="attachment_185" class="wp-caption aligncenter" style="width: 426px"><a href="http://enja.org/wp-content/uploads/2010/06/particles_ubuntu_gtx480.png"><img class="size-full wp-image-185" title="particles_ubuntu_gtx480" src="http://enja.org/wp-content/uploads/2010/06/particles_ubuntu_gtx480.png" alt="screenshot of 1million particles" width="416" height="346" /></a><p class="wp-caption-text">1,000,000 particles strong!</p></div>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/8g-bdTu8iBA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/06/26/simple-particles-with-opencl-and-opengl/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://enja.org/2010/06/26/simple-particles-with-opencl-and-opengl/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=simple-particles-with-opencl-and-opengl</feedburner:origLink></item>
		<item>
		<title>Particles on my Android</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/0-yTyBT6JMM/</link>
		<comments>http://enja.org/2010/06/19/particles-on-my-android/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 19:32:36 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://enja.org/?p=177</guid>
		<description><![CDATA[Since I just got my first Android phone (an HTC Eris while I wait for my HTC Incredible to be shipped) and I read about the Android NDK as well as OpenGL ES support it seemed like a good idea to &#8230; <a href="http://enja.org/2010/06/19/particles-on-my-android/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Since I just got my first Android phone (an HTC Eris while I wait for my HTC Incredible to be shipped)</p>
<p><img class="alignright size-medium wp-image-178" title="simple particle fountain" src="http://enja.org/wp-content/uploads/2010/06/particles1-200x300.png" alt="" width="200" height="300" /> and I read about the <a href="http://developer.android.com/sdk/ndk/index.html">Android NDK</a> as well as OpenGL ES support it seemed like a good idea to write a simple particle system in C as practice for my <a href="http://enja.org/2010/05/20/blender-and-opencl-the-journey-begins/">Blender OpenCL Particle project</a>. For some reason I also find it plain <em>cool</em> to write in C on a phone with such a nice SDK and support system.</p>
<p>I&#8217;ve <a href="http://github.com/enjalot/EnjaParticles">uploaded my code</a> in hopes that others trying to get into C development with OpenGL may benefit from this example. I based the Java part off the san-angeles demo in the NDK and added more touch interaction, dragging rotates the scene and touching moves the emitter of the particles. The system is pretty simple right now and I still need to get more familiar with OpenGL. I&#8217;m looking forward to trying OpenGL ES 2.0 but I need to wait for my Incredible since the Eris doesn&#8217;t support it.</p>
<p>This was a fun exercise and it feels good to get some fairly low level control over my phone. I need to focus more on the OpenCL acceleration of particle system&#8217;s on bigger GPUs, but luckily almost all of the C code could be copy pasted into a GLUT project and run on a PC. There are some interesting differences that need to be considered like the <a href="http://apistudios.com/hosted/marzec/badlogic/wordpress/?p=71 ">lack of floating point support</a> in most Android hardware. As a hobby I&#8217;m going to explore more interesting effects on the phone, and for work I&#8217;m going to add timing/profiling and keep the code modular so I can measure performance on many different platforms (now including phones!).</p>
<p>Hmm&#8230; what if we ported the Blender Game Engine to Android with the NDK? I hear they have <a href="http://apistudios.com/hosted/marzec/badlogic/wordpress/?p=248">Bullet Physics</a> already&#8230; ok I&#8217;m getting ahead of myself!</p>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/0-yTyBT6JMM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/06/19/particles-on-my-android/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://enja.org/2010/06/19/particles-on-my-android/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=particles-on-my-android</feedburner:origLink></item>
		<item>
		<title>Blender: Creating a Custom Modifier</title>
		<link>http://feedproxy.google.com/~r/enjaorg/~3/QJ9ydl2tono/</link>
		<comments>http://enja.org/2010/05/24/blender-creating-a-custom-modifier/#comments</comments>
		<pubDate>Tue, 25 May 2010 01:52:06 +0000</pubDate>
		<dc:creator>enj</dc:creator>
				<category><![CDATA[blender]]></category>

		<guid isPermaLink="false">http://enja.org/?p=153</guid>
		<description><![CDATA[On my quest to create an OpenCL enabled Particle System I realized that I need a way for the Blender Game Engine to know when to render an object as a particles as opposed to a regular mesh. A straight &#8230; <a href="http://enja.org/2010/05/24/blender-creating-a-custom-modifier/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">On my quest to create an <a href="http://enja.org/2010/05/20/blender-and-opencl-the-journey-begins/">OpenCL enabled Particle System</a> I realized that I need a way for the Blender Game Engine to know when to render an object as a particles as opposed to a regular mesh. A straight forward way to achieve this (with other benefits) would be to create a Particle modifier that can be added to an object which the game engine can then check for. I&#8217;d like to thank <a href="http://mogurijin.wordpress.com/">Moguri</a> for this idea!</p>
<p style="text-align: justify;">So I set out today to make a custom modifier that does nothing but printf its existence! I figured this out by copying the SoftBody modifier and scouring the source code for all references to it. I called my modifier Enja, so just replace any instance of Enja in this post with your own chosen name.</p>
<p style="text-align: justify;">First we want to create our main modifier code file (all paths start in the source folder)</p>
<p style="text-align: justify;"><strong>blender/modifiers/intern/MOD_enja.c</strong></p>
<pre style="text-align: justify;">cp blender/modifiers/intern/MOD_softbody.c blender/modifiers/intern/MOD_enja.c</pre>
<p style="text-align: justify;">In here you will add functionality, initialize default values and of course replace all instances of SoftBody with Enja. You can see my code <a href="http://github.com/enjalot/BGEnjaParticles/blob/master/source/blender/modifiers/intern/MOD_enja.c">MOD_enja.c<br />
</a></p>
<p style="text-align: justify;">The rest of the instructions are just modifying files (if you are confused about where things go, just look at Softbody!<a href="http://people.sc.fsu.edu/~idj03/blender/custom_modifier/MOD_enja.c"> </a></p>
<p style="text-align: justify;"><a href="http://people.sc.fsu.edu/~idj03/blender/custom_modifier/MOD_enja.c"></a> At line 184 of <strong>blender/modifiers/intern/MOD_util.c</strong></p>
<blockquote>
<pre style="text-align: justify;">	INIT_TYPE(Enja);</pre>
</blockquote>
<p>At line 70 of <strong>blender/modifiers/MOD_modifiertypes.h</strong></p>
<blockquote>
<pre style="text-align: justify;">extern ModifierTypeInfo modifierType_Enja;</pre>
</blockquote>
<p>At line 564 of: <strong>blender/makesrna/RNA_access.h</strong></p>
<blockquote>
<pre style="text-align: justify;">extern StructRNA RNA_EnjaModifier;</pre>
</blockquote>
<p style="text-align: justify;">At line 303 of: <strong>blender/blenkernel/BKE_modifier.h</strong></p>
<blockquote>
<pre>int modifiers_isEnjaEnabled(struct Object *ob);</pre>
</blockquote>
<p>We need to edit b<strong>lender/makesdna/DNA_modifier_types.h</strong> in several places:</p>
<p style="text-align: justify;">on line 69, just after eModifierType_Screw and before NUM_MODIFIER_TYPES add</p>
<blockquote>
<pre>eModifierType_Enja,</pre>
</blockquote>
<p style="text-align: justify;">on line 441, after the SoftbodyModifierData struct, add</p>
<blockquote>
<pre>typedef struct EnjaModifierData {
    ModifierData modifier;
    int system;
} EnjaModifierData;</pre>
</blockquote>
<div>on line 85 of <strong>blender/makesrna/intern/rna_modifier.c </strong>(before the {0,NULL,0,NULL,NULL} entry:</div>
<div>
<pre>{eModifierType_Enja, "ENJA", ICON_MOD_SOFT, "Enja", ""},</pre>
</div>
<div>line 2210:</div>
<div>
<pre>static void rna_def_modifier_enja(BlenderRNA *brna)
{

    StructRNA *srna;
    PropertyRNA *prop;

    srna= RNA_def_struct(brna, "EnjaModifier", "Modifier");
    RNA_def_struct_ui_text(srna, "Enja Modifier", "Add a particle system");
    RNA_def_struct_sdna(srna, "EnjaModifierData");
    RNA_def_struct_ui_icon(srna, ICON_MOD_SOFT);

    prop= RNA_def_property(srna, "system", PROP_INT, PROP_NONE);
    RNA_def_property_int_sdna(prop, NULL, "system");
    // we should use an enum but this is hacked together for now
    // this range is to allow the user to select a different system
    RNA_def_property_ui_range(prop, 0, 2, 1, 0);
    RNA_def_property_ui_text(prop, "Systems", "Available particle systems");
    RNA_def_property_update(prop, 0, "rna_Modifier_update");

}</pre>
</div>
<div>line 2337:</div>
<div>
<div>
<pre>rna_def_modifier_enja(brna);</pre>
</div>
</div>
<div>To add the modifier to our UI we need to edit one more file: <strong>../release/scripts/ui/properties_data_modifier.py</strong> around line 624</div>
<blockquote>
<pre>def ENJA(self, layout, ob, md, wide_ui):
    layout.label(text="System:")
    layout.prop(md, "system")
    layout.label(text="0: lorentz 1: gravity")</pre>
</blockquote>
<div>This should build and give you a modifier under the Simulate header that does nothing but print out a message when you add it. My next step is to check for this modifier in the Game Engine and of course, start adding some functionality! I wish I could explain more about what each of these lines do, but I&#8217;m still trying to understand the RNA/DNA system and the Blender way of doing things.</div>
<img src="http://feeds.feedburner.com/~r/enjaorg/~4/QJ9ydl2tono" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://enja.org/2010/05/24/blender-creating-a-custom-modifier/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://enja.org/2010/05/24/blender-creating-a-custom-modifier/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=blender-creating-a-custom-modifier</feedburner:origLink></item>
	</channel>
</rss>
