blob: a676895a5695eaa8392c89ae0f3c43059e81cae7 [file] [log] [blame]
{{+bindTo:partials.standard_nacl_article}}
<section id="a-saga-of-fire-and-water-codelab">
<span id="cds2014-cpp"></span><h1 id="a-saga-of-fire-and-water-codelab"><span id="cds2014-cpp"></span>A Saga of Fire and Water - Codelab</h1>
<h2 id="introduction">Introduction</h2>
<p>Learn the basics of using PPAPI to do 2D graphics from
a C++ program running in Native Client.
Modify our sample to turn fire into water.
Develop inside Google Chrome, using our NaCl Development Environment
Chrome App.
While this codelab currently targets conventional Native Client using our
GCC + GlibC based toolchain, the techniques involved are generally
applicable.</p>
<dl class="docutils">
<dt>Requirements:</dt>
<dd><ul class="first last small-gap">
<li>An x86 (sorry no arm) Desktop / Laptop
Windows, Mac, Linux, or ChromeOS browser
<br/><span id="cpp_compat" style="color: #cccc00"
>Checking browser compatibility...</span><br/>
<i id="cpp_compat2"></i>
<script>
var tag = document.getElementById('cpp_compat');
var tag2 = document.getElementById('cpp_compat2');
if (!('application/x-nacl' in navigator.mimeTypes)) {
tag.innerHTML =
'This codelab does not appear to be supported by your browser.';
tag.style.color = '#cc0000';
tag2.innerHTML =
'You do not appear to be running a browser such as ' +
'Google Chrome which supports Native Client ' +
'or you have disabled Native Client.';
} else if (navigator.userAgent.search(' arm') >= 0) {
tag.innerHTML =
'This codelab does not appear to be supported by your browser.';
tag.style.color = '#cc0000';
tag2.innerHTML =
'You appear to be running on an ARM based CPU. ' +
'While Native Client does support ARM, ' +
"our developer environment's GCC + GlibC based toolchain " +
'does not, at this time. Sorry.';
} else {
tag.innerHTML = 'This codelab appears to be supported by your browser.';
tag.style.color = '#00cc00';
}
</script></li>
<li>A fast broadband connection (500MB download)</li>
<li>Can read and write C++</li>
</ul>
</dd>
</dl>
<h2 id="setup">Setup</h2>
<p>For this codelab, you will need to install the our
Beta NaCl Dev Environment App in your web browser.</p>
<a href="https://chrome.google.com/webstore/detail/nacl-development-environm/aljpgkjeipgnmdpikaajmnepbcfkglfa"
target="_blank">Click here to install the environment.</a><p>You will need to click &#8220;Install&#8221; to add the NaCl Dev Environment
to your browser.</p>
<p>NOTE: This environment will leave a substantial (800MB) payload in your
browser. See the cleanup section below to learn how to recover this space.</p>
<p>Once the installation is complete, run the app.</p>
<p>On the first run, it will download several packages.
Once download is complete, you should see a bash prompt:</p>
<pre class="prettyprint">
bash.nmf-4.3$
</pre>
<h3 id="our-web-based-tools">Our Web-based Tools</h3>
<p>These development tools are a <a class="reference external" href="nacldev">work in progress</a>.
At this point, they are a learning tool and demonstration of NaCl&#8217;s
flexibility, but are not the recommended tools for a production application.
In the future, that may change, but for the moment,
to develop a substantial application for Native Client /
Portable Native Client,
we recommend you use the
<a class="reference external" href="/native-client/sdk/download">Native Client SDK</a>.</p>
<b><font color="#880000">
NOTE: The NaCl Development Environment is not yet stable.
Ideally, user data is preserved, but currently it can be lost during updates
or sporadically. We're working to resolve this.
</font></b><h3 id="navigating-in-the-dev-environment">Navigating in the Dev Environment</h3>
<p>The NaCl Dev Environment behaves like a mini-UNIX system.
You start-up in bash command prompt.
Standard UNIX commands like cd, ls, mkdir, rm, rmdir, etc.
can be used to navigate and modify the Dev Environment&#8217;s
virtual filesystem.</p>
<p>There are 3 locations mounted by the environment:</p>
<blockquote>
<div><ul class="small-gap">
<li>/tmp mounts the HTML5 Filesystem temporary storage area.</li>
<li>/mnt/html5 mounts the HTML5 Filesystem persistent storage area.</li>
<li>Your home directory ~/, located in /home/user,
mounts a portion of the HTML5 Filsystem persistent storage area
that corresponds to the /mnt/html5/home directory.</li>
</ul>
</div></blockquote>
<h3 id="clipboard">Clipboard</h3>
<p>Many of the steps in this tutorial will be easier to copy and paste
into the Dev Environment.
To copy and paste in the Dev Environment App,
you will need to use the keyboard.</p>
<p>On your platform use:</p>
<blockquote>
<div><ul class="small-gap">
<li><span id="copy_key">Loading...</span>
<script>
var tag = document.getElementById('copy_key');
if (navigator.appVersion.indexOf('Mac') >= 0) {
tag.innerHTML = '&#8984;-C';
} else {
tag.innerHTML = 'Ctrl-Shift-C';
}
</script> to Copy</li>
<li><span id="paste_key">Loading...</span>
<script>
var tag = document.getElementById('paste_key');
if (navigator.appVersion.indexOf('Mac') >= 0) {
tag.innerHTML = '&#8984;-V';
} else {
tag.innerHTML = 'Ctrl-Shift-V';
}
</script> to Paste</li>
</ul>
</div></blockquote>
<h4 id="editing">Editing</h4>
<p>To follow along in this codelab, you&#8217;ll need to use a text editor to modify
various files in our development environment.
There are currently two editor options, nano or vim.
We have an Emacs port, but it is not yet available in the Dev Environment
(coming soon).
If you&#8217;re unsure what to pick, nano is simpler to start with and has on-screen
help.</p>
<ul class="small-gap">
<li><p class="first">You can open <strong>nano</strong> like this:</p>
<pre class="prettyprint">
$ nano &lt;filename&gt;
</pre>
<p>Here&#8217;s an online <a class="reference external" href="http://mintaka.sdsu.edu/reu/nano.html">nano tutorial</a>.</p>
</li>
<li><p class="first">You can open <strong>vim</strong> like this:</p>
<pre class="prettyprint">
$ vim &lt;filename&gt;
</pre>
<p>Here&#8217;s an online <a class="reference external" href="http://www.openvim.com/tutorial.html">vim tutorial</a>.</p>
</li>
</ul>
<h3 id="git-setup">Git Setup</h3>
<p>This tutorial also uses a revision control program called
<a class="reference external" href="http://en.wikipedia.org/wiki/Git_(software)">git</a>.
In order to commit to a git repository,
you need to set up your identity.</p>
<p>Run these commands (with your info) to setup your <cite>~/.gitconfig</cite>
for use:</p>
<pre class="prettyprint">
git config --global user.name &quot;John Doe&quot;
git config --global user.email johndoe&#64;example.com
</pre>
<h2 id="get-the-code">Get the Code!</h2>
<p>Rather than start from nothing, for this codelab we&#8217;ve provided
you with a zip file containing a starting point.</p>
<p>Download the codelab:</p>
<pre class="prettyprint">
curl http://nacltools.storage.googleapis.com/cds2014/cds2014_cpp.zip -O
</pre>
<p>Unzip it:</p>
<pre class="prettyprint">
unzip cds2014_cpp.zip
</pre>
<p>Go into the codelab directory:</p>
<pre class="prettyprint">
cd cds2014_cpp
</pre>
<p>Create a new local git repo:</p>
<pre class="prettyprint">
git init
</pre>
<p>Add everything:</p>
<pre class="prettyprint">
git add .
</pre>
<p>Commit it:</p>
<pre class="prettyprint">
git commit -am &quot;initial&quot;
</pre>
<p>While working, you can see what you&#8217;ve changed by running:</p>
<pre class="prettyprint">
git diff
</pre>
<h2 id="fire-is-cool-let-s-burn-some-stuff">Fire is cool, let&#8217;s burn some stuff...</h2>
<p>Indulging your inner child, lets make some virtual fire!
Use the following shockingly intuitive incantation:</p>
<pre class="prettyprint">
make fire
</pre>
<p>You should now see a small popup window, smoldering away.
If you click, you can make more fire!
I think that&#8217;s pretty cool, but then I selected
the institution of higher learning I attended based
on the integral role fire played in its campus life.</p>
<h2 id="water">Water</h2>
<p>Remarkably, not everyone enjoys the primal illusion of fire.</p>
<p>Your task in this codelab is to transform the rising fire
effect you see before you into a beautiful, tranquil waterfall.
This will require digging into some C++ code.</p>
<p>Before you begin, you&#8217;ll want to copy our fire program to a new name,
since you might decide later that you like fire better, I know I do:</p>
<pre class="prettyprint">
cp fire.cc water.cc
git add water.cc
git commit -am &quot;adding water&quot;
</pre>
<p>For this codelab, you&#8217;ll only need to change <cite>water.cc</cite>.</p>
<p>The task of turning fire into water involves two key challenges:</p>
<blockquote>
<div><ul class="small-gap">
<li>Alter the red-yellow palette of fire into a blue-green one.</li>
<li>Reverse upward rising flame into downward falling water.</li>
<li>Seed the waterfall from the top instead of the bottom.</li>
</ul>
</div></blockquote>
<p>At this point you&#8217;ll want to open up <cite>water.cc</cite> in the editor you
picked earlier.</p>
<h3 id="i-see-a-red-door-and-i-want-it-painted-blue">I see a red door and I want it painted... blue</h3>
<p>While PPAPI&#8217;s 2D graphics API uses multi-component RGB pixels,
our flame effect is actually monochrome. A single intensity
value is used in the flame simulation. This is then converted
to color based on a multi-color gradient.
To alter the color-scheme, locate this palette, and exchange
the red component (first) with the blue one (third).</p>
<p>Hint: Focus your energies on the CreatePalette function.</p>
<p>You can test you changes at any time with:</p>
<pre class="prettyprint">
make water
</pre>
<h3 id="what-goes-up">What goes up...</h3>
<p>Now there&#8217;s the small matter of gravity.
While smoke, and well flame, rises, we want our water to go down.</p>
<p>The simulation of fire loops over each pixel,
bottom row to top row,
diffusing &#8220;fire stuff&#8221; behind the sweep.
You&#8217;ll want to reverse this.</p>
<p>Hint: You&#8217;ll need to change the y loop direction in the UpdateFlames function.</p>
<h3 id="up-high-down-low">Up high, down low</h3>
<p>While you can now use the mouse to inject a trickle of water.
The small line of blue at the bottom isn&#8217;t much of a waterfall.
Move it to the top to complete the effect.</p>
<p>Hint: You&#8217;ll want to change the area that the UpdateCoals function mutates.</p>
<h2 id="what-you-ve-learned">What you&#8217;ve learned</h2>
<p>In addition to learning a new appreciation for fire, you&#8217;ve also made water...
And while dusting off your C/C++ image manipulation skills,
you&#8217;ve discovered how easy it is to modify, build,
and run a NaCl application that uses PPAPI.</p>
<p>2D graphics is fun, but now you&#8217;re ready to check out the wealth of
other
<a class="reference external" href="https://src.chromium.org/viewvc/chrome/trunk/src/ppapi/cpp/">PPAPI interfaces available</a>.</p>
<p>While our in-browser environment is rapidly evolving
to become a complete development solution,
for the broadest range of development options, check out the
<a class="reference external" href="https://developer.chrome.com/native-client/cpp-api">NaCl SDK</a>.</p>
<p>Send us comments and feedback on the <a class="reference external" href="https://groups.google.com/forum/#!forum/native-client-discuss">native-client-discuss</a> mailing list,
or ask questions using Stack Overflow&#8217;s <a class="reference external" href="https://stackoverflow.com/questions/tagged/google-nativeclient">google-nativeclient</a> tag.</p>
<p>I hope this codelab has lit a fire in you to go out there,
and bring an awesome C/C++ application to NaCl or PNaCl today!</p>
<h2 id="cleanup">Cleanup</h2>
<p>The Chrome Dev Environment App installs &gt;800MB into
HTML5 Filesystem storage on your device.
To recover this storage, uninstall the app from the
<a href="https://chrome.google.com/webstore"
target="_blank">Chrome Web Store</a>.</p>
</section>
{{/partials.standard_nacl_article}}