<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.9.2 (http://www.squarespace.com/) on Wed, 10 Mar 2010 17:48:07 GMT--><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rss="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:cc="http://web.resource.org/cc/"><rss:channel rdf:about="http://www.iancbullard.com/journal/"><rss:title>Ian Bullard's Blog</rss:title><rss:link>http://www.iancbullard.com/journal/</rss:link><rss:description>A Game Developer's Thoughts on Things</rss:description><dc:language>en-US</dc:language><dc:date>2010-03-10T17:48:07Z</dc:date><admin:generatorAgent rdf:resource="http://www.squarespace.com/">Squarespace Site Server v5.9.2 (http://www.squarespace.com/)</admin:generatorAgent><rss:items><rdf:Seq><rdf:li rdf:resource="http://www.iancbullard.com/journal/2009/9/15/jennifer-bullard-speaks-at-agdc.html"/><rdf:li rdf:resource="http://www.iancbullard.com/journal/2009/7/10/cliche-alert-not-dead.html"/><rdf:li rdf:resource="http://www.iancbullard.com/journal/2009/6/17/opengl-es-sprite-engine-work-in-progress.html"/><rdf:li rdf:resource="http://www.iancbullard.com/journal/2009/6/12/math-library-release.html"/><rdf:li rdf:resource="http://www.iancbullard.com/journal/2009/5/27/link-pages-ported-new-iphone-links-added.html"/><rdf:li rdf:resource="http://www.iancbullard.com/journal/2009/4/30/switch-to-squarespace-almost-complete.html"/><rdf:li rdf:resource="http://www.iancbullard.com/journal/2009/4/28/why-you-should-never-use-rand.html"/><rdf:li rdf:resource="http://www.iancbullard.com/journal/2009/3/27/moving-the-blog-to-squarespace.html"/></rdf:Seq></rss:items></rss:channel><rss:item rdf:about="http://www.iancbullard.com/journal/2009/9/15/jennifer-bullard-speaks-at-agdc.html"><rss:title>Jennifer Bullard speaks at AGDC</rss:title><rss:link>http://www.iancbullard.com/journal/2009/9/15/jennifer-bullard-speaks-at-agdc.html</rss:link><dc:creator>Ian Bullard</dc:creator><dc:date>2009-09-15T20:37:06Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p><a href="http://www.gamasutra.com/php-bin/news_index.php?story=25259">Shameless promotion of my wife</a>.</p>
<p>&nbsp;</p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.iancbullard.com/journal/2009/7/10/cliche-alert-not-dead.html"><rss:title>Cliché Alert! Not Dead!</rss:title><rss:link>http://www.iancbullard.com/journal/2009/7/10/cliche-alert-not-dead.html</rss:link><dc:creator>Ian Bullard</dc:creator><dc:date>2009-07-10T23:53:05Z</dc:date><dc:subject>Administration Administration</dc:subject><content:encoded><![CDATA[<p>No, really. &nbsp;I have content for you guys, it needs proofreading and cleaning up but I do. &nbsp;However I'm selling my house and buying a new one so my spare time is taken up by packing, paperwork, cleaning and paperwork. &nbsp;I'll try to post while all of this is going on but the reality is I'll be randomly available for random amounts of time for the next two months. &nbsp;</p>
<p>Please don't think this website is dead, it's just in a life transition. &nbsp;Just so you know what's coming up:</p>
<p>&nbsp;</p>
<ul>
<li>How to create a common interface between OpenGL ES 1.1 and 2.0</li>
<li>Sprite rendering in OpenGL ES</li>
<li>Free camera source code</li>
</ul>
<p>&nbsp;</p>
<p>Stick around, be patient.</p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.iancbullard.com/journal/2009/6/17/opengl-es-sprite-engine-work-in-progress.html"><rss:title>OpenGL ES Sprite Engine Work in Progress</rss:title><rss:link>http://www.iancbullard.com/journal/2009/6/17/opengl-es-sprite-engine-work-in-progress.html</rss:link><dc:creator>Ian Bullard</dc:creator><dc:date>2009-06-18T03:54:08Z</dc:date><dc:subject>2D Sprites GameProgramming MathLib OpenGL</dc:subject><content:encoded><![CDATA[<p>I've been working on an OpenGL ES project for a presentation to <a href="http://www.cocoacoder.org/">CocoaCoder.org</a> to help people in the group understand OpenGL better and to get better performance. &nbsp;My frustrations with the presentation led me to <a href="http://www.iancbullard.com/files/source-files/mathlib.zip">release my math library</a> so people can spend time learning OpenGL instead of writing matrix math functions. &nbsp;The project has ended up being a very simple sprite engine that supports OGL ES 1.1 and 2.0. &nbsp;</p>
<p>The <a href="http://www.iancbullard.com/files/source-files/CocoaCoder_OpenGLES.zip">CocoaCoder_OpenGLES</a> project isn't a bunch of code I'm particularly proud of but it is a good example of 2D sprite rendering. &nbsp;It's also a good example of using shaders on the iPhone, although I have only been able to test it against the simulator and not an iPhone 3GS. &nbsp;</p>
<p>Check the project out, play with it and give me any feedback you have. &nbsp;I'm going to continue working on the project over the next couple of months and use it in future blog posts.</p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.iancbullard.com/journal/2009/6/12/math-library-release.html"><rss:title>Math Library Release</rss:title><rss:link>http://www.iancbullard.com/journal/2009/6/12/math-library-release.html</rss:link><dc:creator>Ian Bullard</dc:creator><dc:date>2009-06-13T02:31:58Z</dc:date><dc:subject>GameProgramming OpenGL MathLib</dc:subject><content:encoded><![CDATA[<p>I've been working on OpenGL ES tutorials for a while and I always hit the same wall: a lack of vector and matrix support. For DirectX there's D3DXVECTOR4 and D3DXMATRIX which make it much easier to get started. For OpenGL you have some support via the matrix stack and glOrthof/glRotatef/etc. but OpenGL ES 2.0 takes even that away from you.</p>
<p>Several years ago I wrote a math library that included everything from sine and cosine to transformations. It's overkill for simple 3D mathematics and a lot of it is organized in preparation to create a ray tracer. MathLib is what I use for all of my own OpenGL rendering, though, and does a good enough job for most cases.</p>
<p>To give back to the community and save myself some sanity moving forward I've decided to release the MathLib part of my code library under the MIT license. <a href="http://www.iancbullard.com/files/source-files/mathlib.zip">Download it</a>, check it out, and try it out. I'll release source code that shows how it's used with OpenGL ES shortly.</p>
<p>[EDIT: here's a quick example on how to use the library's transformations with OpenGL]</p>
<blockquote>
<p><span><span> </span></span>glMatrixMode<span>(</span>GL_PROJECTION<span>);</span></p>
<p><span> </span>Transform4f ortho(Transform4f::Orthographic(-<span>1.0f</span>, <span>1.0f</span>, -<span>1.5f</span>, <span>1.5f</span>, -<span>1.0f</span>, <span>1.0f</span>));</p>
<p><span> </span>Matrix4x4f mat(ortho.GetTransform());</p>
<p><span> </span></p>
<p><span><span> </span></span>glLoadMatrixf<span>((</span><span>float</span><span>*)mat);</span></p>
<p><span><span> </span></span>glMatrixMode<span>(</span><span>GL_MODELVIEW</span><span>);</span></p>
<p><span> </span>Transform4f rot(Transform4f::RotateZ(rotation * <span>0.0174532925f</span>));</p>
<p><span> </span>mat = rot.GetTransform();</p>
<p><span> </span></p>
<p><span><span> </span></span>glLoadMatrixf<span>((</span><span>float</span><span>*)mat);</span></p>
<p>&nbsp;</p>
</blockquote>]]></content:encoded></rss:item><rss:item rdf:about="http://www.iancbullard.com/journal/2009/5/27/link-pages-ported-new-iphone-links-added.html"><rss:title>Link pages ported, new iPhone links added</rss:title><rss:link>http://www.iancbullard.com/journal/2009/5/27/link-pages-ported-new-iphone-links-added.html</rss:link><dc:creator>Ian Bullard</dc:creator><dc:date>2009-05-27T02:04:57Z</dc:date><dc:subject>Administration Administration GameProgramming GameProgramming</dc:subject><content:encoded><![CDATA[<p>I've managed to come back and do the last of the work needed to switch to SquareSpace. &nbsp;Some personal things came up and delayed my work on this for a while but now I'm back. &nbsp;</p>
<p>The link pages are new moved over and cleaned up where appropriate. &nbsp;I've also added a new page with iPhone development resources. &nbsp;</p>
<p>Next: &nbsp;Finalize switch from the old website and start posting about OpenGL ES sprites on the iPhone. &nbsp;</p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.iancbullard.com/journal/2009/4/30/switch-to-squarespace-almost-complete.html"><rss:title>Switch to SquareSpace Almost Complete</rss:title><rss:link>http://www.iancbullard.com/journal/2009/4/30/switch-to-squarespace-almost-complete.html</rss:link><dc:creator>Ian Bullard</dc:creator><dc:date>2009-04-30T01:16:52Z</dc:date><dc:subject>Administration</dc:subject><content:encoded><![CDATA[<p>I've copied all of the useful information from the old web site to this one, now I'm waiting for DNS changes and then I have to close down the old web site with forwarding files. &nbsp;</p>
<p>End of week, then I can get back to doing something useful.</p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.iancbullard.com/journal/2009/4/28/why-you-should-never-use-rand.html"><rss:title>Why you should never use rand()</rss:title><rss:link>http://www.iancbullard.com/journal/2009/4/28/why-you-should-never-use-rand.html</rss:link><dc:creator>Ian Bullard</dc:creator><dc:date>2009-04-28T00:45:02Z</dc:date><dc:subject>Articles GameProgramming GameProgramming</dc:subject><content:encoded><![CDATA[<p><strong><span style="text-decoration: underline;">Note</span></strong>: This article was originally on my old web site and there was a follow up article that replied to some feedback and cleaned up the source code. I've abandoned that web site and decided to merge the two articles into this one.</p>
<p><strong><span style="font-size: 120%;">Never use rand()!</span></strong><br /><br />By the end of this article I will convince you to never use rand() or random() again. Instead you&rsquo;ll implement your own version or download an existing implementation of a better random number generator.<strong><br /><br /><span style="font-size: 120%;">Why I even thought about implementing rand() myself</span></strong><br /><br />I started writing my own game engine sometime in 2002. There had been attempts before then, but this was the first real push to create my own cross-platform 3D game engine from scratch. At the time I was working on fighting games for the Playstation 2 and Xbox with a game engine that was originally written in C for the Playstation.<br /><br />Being an engineer on a console title is an experience I highly recommend because you end up doing things you normally wouldn&rsquo;t think of doing for other games. Many established companies have libraries of code that implement what PC and Mac programmers take for granted in the operating system. For instance, when the Xbox first came out I had to write a memory manager for it because there wasn&rsquo;t one. Other companies I worked for later had entire STL implementations of their own and special implementations of standard C&rsquo;s math library.<br /><br />When it came time to write my own game engine, I assumed I should do the same. Seven years later, I don&rsquo;t recommend independent developers do this because it&rsquo;s impossible to ship a game that way when you&rsquo;re working alone. If you&rsquo;re just programming at home for fun and knowledge I do recommend it, I learned some valuable lessons from that experience. The first thing I learned about is random number generators.<br /><br /><strong><span style="font-size: 120%;">What is rand()?</span></strong><br /><br />Standard C&rsquo;s rand() is an implementation of a&nbsp;<a rel="self" href="http://en.wikipedia.org/wiki/Pseudorandom_number_generator">pseudorandom number generator</a>&nbsp;(PRNG). In short, a PRNG takes a starting seed number and generates a series of numbers that appear to be random. For rand(), you use srand() to seed the random number generator (usually with a current time value) then use rand() to get the &ldquo;random&rdquo; numbers. The C standard doesn&rsquo;t dictate the algorithm used, it just says that it returns a random number in the range of [0, RAND_MAX].<br /><br /><strong><span style="font-size: 120%;">What alternatives are there?</span></strong><br /><br />Before I tell you why rand() shouldn&rsquo;t be used I&rsquo;d like to introduce you to a couple of alternatives. PRNGs have different strengths, algorithms used for statistical modeling need PRNGs that are as close to random as possible. Cryptography need to be not only random but also resistant to cryptography attacks. Games need randomness but speed is also important, sometimes more important than how random the algorithm is.<br /><br />There are many PRNGs available but I&rsquo;ve settled on three for use in my engine:</p>
<ul class="disc">
<li>The&nbsp;<a rel="self" href="http://en.wikipedia.org/wiki/Mersenne_twister">Mersenne Twister</a>&nbsp;algorithm is used in statistical simulations and is highly recommended. It is the PRNG I&rsquo;d use when speed isn&rsquo;t that important.</li>
<li><a rel="self" href="http://burtleburtle.net/bob/rand/isaacafa.html">ISAAC</a>&nbsp;is a cryptographically strong PRNG. On my Intel Mac Pro it&rsquo;s just as fast as Mersenne but on other platforms it&rsquo;s much slower.</li>
<li>GameRand is a random number generator based off an &ldquo;<a rel="self" href="http://www.flipcode.com/archives/07-15-2002.shtml">Image of the Day</a>&rdquo; on Flipcode.com (now dead but an archive is available) posted by Stephan Schaem. I changed his assembly language to C++ for my implementation. It&rsquo;s not a really good PRNG for randomness but it&rsquo;s incredibly fast.</li>
</ul>
<p><br /><strong><span style="font-size: 120%;">The tests</span></strong><br /><br /><span style="text-decoration: underline;">Speed</span><br /><br />For speed tests I generated 50 million random numbers and reported the number of seconds it took. I ran each speed test five times and took the average. I&rsquo;ve added BSD&rsquo;s random() to this test for comparison as well for those folks working on the Mac.<br /><br />Here&rsquo;s the results on my Mac Pro with two 2.8 GHz quad-core Intel Xeon processors:<br /><br /><em>rand()&nbsp;</em>= 5.47 seconds<br /><em>random()&nbsp;</em>= 3.02 seconds<br /><em>Mersenne&nbsp;</em>= 4.92 seconds<br /><em>ISAAC&nbsp;</em>= 4.92 seconds<br /><em>GameRand&nbsp;</em>= 0.72 seconds<br /><br />As you can see, rand() is the slowest of the bunch. Mersenne Twister and ISAAC come in a close second and GameRand is by far the fastest. When I first compiled these results I was confused because I thought Mersenne was faster than ISAAC. When I dug up the results on my previous Mac Pro with two 1.8 GHz G5 processors it was more like how I remembered it (I don&rsquo;t have random() timings for the G5 but I&rsquo;d expect it to be in between Mersenne and GameRand):<br /><br /><em>rand()&nbsp;</em>= 9.94 seconds<br /><em>Mersenne&nbsp;</em>= 7.66 seconds<br /><em>ISAAC&nbsp;</em>= 13.2 seconds<br /><em>GameRand&nbsp;</em>= 1.69 seconds<br /><br />On the G5 ISAAC is 60% slower than Mersenne. This shows you should never make performance assumptions when changing to a new CPU architecture.</p>
<p>Here's the iPod Touch timings, I haven&rsquo;t ported my crypto code to the iPhone yet so ISAAC isn&rsquo;t include:</p>
<p><em>rand()</em> = 19.22 seconds<br /><em>random()</em> = 7.83 seconds<br /><em>GameRand</em> = 0.29 seconds<br /><em>Mersenne</em> = 6.47 seconds<br /><br />No surprises here, it follows the pattern we saw in the previous tests.<br /><br /><span style="text-decoration: underline;">Quality</span><br /><br />The quality of a PRNG can be measured by existing tests. I&rsquo;ve chosen the DieHard random number generator test. For each of the algorithms I listed above I created a file with 5 million values and ran it through the test. Here&rsquo;s what the test application says about the results:</p>
<blockquote>
<p>Most of the tests in DIEHARD return a p-value, which should be uniform on [0,1) if the input file contains truly independent random bits. Those p-values are obtained by p=1-F(X), where F is the assumed distribution of the sample random variable X---often normal. But that assumed F is often just an asymptotic approximation, for which the fit will be worst in the tails. Thus you should not be surprised with occasional p-values near 0 or 1, such .0012 or .9983. When a bit stream really FAILS BIG, you will get p`s of 0 or 1 to six or more places. By all means, do not, as a Statistician might, think that a p &lt; .025 or p&gt; .975 means that the RNG has "failed the test at the .05 level". Such p`s happen among the hundreds that DIEHARD produces, even with good RNGs. So keep in mind that "p happens"</p>
</blockquote>
<p><br />For the sake of this article I&rsquo;m going to stick to what the author of DieHard suggests, if a p is a 0 or a 1 to six places or more it fails. There are a lot of tests (229) so I&rsquo;m not going to list the results of every one, instead I&rsquo;ll give you the percent of tests passed:<br /><br /><em>rand()&nbsp;</em>= 74% (59 fails)<br /><em>random()&nbsp;</em>= 72% (64 fails)<br /><em>Mersenne&nbsp;</em>= 100% (0 fails)<br /><em>ISAAC&nbsp;</em>= 100% (0 fails)<br /><em>GameRand&nbsp;</em>= 85% (33 fails)<br /><br />As you can see, rand() is almost the worst PRNG of the bunch. It&rsquo;s also the slowest, slower than even ISAAC on Intel Xeon processors. GameRand fails some of the tests but it&rsquo;s incredibly fast. Depending on your architecture or target use, both Mersenne and ISAAC are quality PRNGs.</p>
<p><strong>Clarifications</strong><br /><br />1) In most cases the speed of your PRNG is a non-issue. The randomness of it is an issue especially in games. Players can notice the difference between rand() and Mersenne Twister in games where you show them the number results (like in role-playing games).<br /><br />2) If speed does become an issue it&rsquo;s nice to be able to fall back on a known solution. For instance generating terrain requires a lot of random numbers.<br /><br />3) Yeah, in the end my time spent researching PRNGs was probably not well spent. It was my time though, and I&rsquo;m O.K. with that.<br /><br />Most of the criticisms of this original article came from the performance aspects but ignored that both rand() and random() have results that fail DieHard tests. C++0x is&nbsp;<a rel="self" href="http://en.wikipedia.org/wiki/Technical_Report_1#Random_Number_Generation">replacing rand()</a>&nbsp;with multiple generator types, including Mersenne Twister. Why? Because rand() isn&rsquo;t random.</p>
<p><br /><br /><strong><span style="font-size: 120%;">Summary</span></strong><br /><br />Don&rsquo;t use rand() or random(), they&rsquo;re slow and not that random. As you&rsquo;ll see below, GameRand is so simple you can memorize it and is significantly faster and more random than both rand() and random(). If you need a really good PRNG, use Mersenne Twister.<br /><br /><span style="text-decoration: underline;">Just say no to rand()!</span><br /><br /><br /><strong><span style="font-size: 120%;">Source Code for GameRand</span></strong><br /><br />I've uploaded three implementations of GameRand:</p>
<p>C: <a href="http://www.iancbullard.com/files/source-files/gamerand.c">gamerand.c</a></p>
<p>C++: <a href="http://www.iancbullard.com/files/source-files/GameRand.hpp">GameRand.hpp</a></p>
<p>Robert Gr&aelig;sdal sent me a JavaScript version: <a href="http://www.iancbullard.com/files/source-files/gamerand.js">gamerand.js</a></p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.iancbullard.com/journal/2009/3/27/moving-the-blog-to-squarespace.html"><rss:title>Moving the blog to SquareSpace</rss:title><rss:link>http://www.iancbullard.com/journal/2009/3/27/moving-the-blog-to-squarespace.html</rss:link><dc:creator>Ian Bullard</dc:creator><dc:date>2009-03-27T14:55:09Z</dc:date><dc:subject>Administration Administration</dc:subject><content:encoded><![CDATA[<p>I used RapidWeaver to create my website initially and for blog posting. &nbsp;It's a slick program and did more than enough for my basic needs. &nbsp;Well, everything but keep blog posts. &nbsp;RapidWeaver has lost several blog posts and I've had to roll back the source data several times to retrieve lost information.</p>
<p>Small bugs are to be expected in software but data loss is a critical bug. &nbsp;I've lost eight blogs posts across two versions of the software, to me that is completely unacceptable. &nbsp;</p>
<p>I'm dropping RapidWeaver and moving to SquareSpace, please be patient while the switch is made.</p>]]></content:encoded></rss:item></rdf:RDF>