<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>#AltDevBlogADay &#187; Tomasz Dąbrowski</title>
	<atom:link href="http://www.altdevblogaday.com/author/tomasz-dabrowski/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.altdevblogaday.com</link>
	<description>Each day a little more #gamedev love</description>
	<lastBuildDate>Thu, 17 May 2012 03:06:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Simplicity Oriented Programming</title>
		<link>http://www.altdevblogaday.com/2011/07/16/simplicity-oriented-programming/</link>
		<comments>http://www.altdevblogaday.com/2011/07/16/simplicity-oriented-programming/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 04:00:01 +0000</pubDate>
		<dc:creator>Tomasz Dąbrowski</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://altdevblogaday.com/?p=11586</guid>
		<description><![CDATA[<p>After few years on <a href="http://warsztat.gd">Warsztat</a> (a Polish gamedev site) I&#8217;ve noticed an interesting phenomenon. Every now and then there are Compos (programming competitions) organized in two different flavours. Some compos are single-run events that last only few hours, others are long-term (several days/weeks). And as an extra catch, the former are usually restricted to basic APIs (SDL, OpenGL etc) while the latter are free-for-all (all sorts of engines, UDK/Unity allowed).</p>
<p><a href="http://www.altdevblogaday.com/2011/07/16/simplicity-oriented-programming/" class="more-link">Read more on Simplicity Oriented Programming&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>After few years on <a href="http://warsztat.gd">Warsztat</a> (a Polish gamedev site) I&#8217;ve noticed an interesting phenomenon. Every now and then there are Compos (programming competitions) organized in two different flavours. Some compos are single-run events that last only few hours, others are long-term (several days/weeks). And as an extra catch, the former are usually restricted to basic APIs (SDL, OpenGL etc) while the latter are free-for-all (all sorts of engines, UDK/Unity allowed).</p>
<p>Now, results are somewhat shocking. Much more people participate in short compos than the long ones. But the best part is that quality of games created is just the same, no matter if the games was made in 2 hours or 4 weeks. Why?</p>
<ol>
<li>Well, creating game in 4 weeks doesn&#8217;t usually mean neither 672 nor 224 working hours. In extreme cases 4 week compo is just a 2-hours compo, with 2 hours located at the very end of 4 weeks.</li>
<li>A lot of game value is an idea. Fact: you won&#8217;t come up with better idea in 4 weeks than in 10 minutes.</li>
<li>Development process for 2-hours game is very dense. And most of the time is spent on improving core features (because there are no others).</li>
<li>On the other hand, in long-term projects people start to focus on insignificant features. The moment you start improving abstract communication between task pools, adding GUI widgets so that you can make a built-in MP3 player or making splash screen data-oriented, your project is screwed to hell.</li>
</ol>
<p>And this is probably the most important lesson to remember. If you need to do something very quick, code will be horrific, but also short, simple and fixable. With no time constraints, code will get new levels of complication, features and bugs. Time spent on maintaining won&#8217;t justify the result.</p>
<p>In 4 weeks, you can make several iterations of speed-coding, each time improving core features of the game. If you start with future proofness in mind, writing code and fixing bugs will consume most of the time. Sure, in 4 weeks you can make a ton of assets/levels, but how good are they is core gameplay is not good enough?</p>
<p>Finally, one solid C(++) tip: when adding new features, start with the smallest of available guns:</p>
<ol>
<li>Global function &#8212; if you need to display score, don&#8217;t hesitate to add void DisplayScore() somewhere.  If your game is single-player, store score as a global variable. See? You have just saved 10 minutes of writing getters, setters and designing communication between modules. If your game is multi-player then you will need to store and display scores per-player. But there is no reason to be able to display arbitrary score of arbitrary player if your game is not yet multiplayer. Believe me, you&#8217;ll have bigger problems than displaying score with that.</li>
<li>If your functions share common code or require helper functions, group them somewhere, possibly in separate file. Remember about static functions and variables &#8212; contrary to &#8220;OO&#8221; static, file static is about visibility. But it&#8217;s cool, because you can have a file for all font-related operations and store internal data in static global variable. Helper functions can be static, and public ones go to one shared header (if you write simple code, compilation time is never your enemy).</li>
<li>Promote functions to classes only when it&#8217;s relevant and useful. Remember, classes means objects, objects mean relations and relations means complexity. Is your gameplay so cool that you have time for code complexity?</li>
<li>Any design patterns or other exotic stuff is the last resort if none of above is good enough. Personally? Never got there.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.altdevblogaday.com/2011/07/16/simplicity-oriented-programming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keep data close, part 1</title>
		<link>http://www.altdevblogaday.com/2011/05/17/keep-data-close-part-1/</link>
		<comments>http://www.altdevblogaday.com/2011/05/17/keep-data-close-part-1/#comments</comments>
		<pubDate>Tue, 17 May 2011 00:46:02 +0000</pubDate>
		<dc:creator>Tomasz Dąbrowski</dc:creator>
		
		<guid isPermaLink="false">http://altdevblogaday.org/?p=5987</guid>
		<description><![CDATA[<p>I would like to present a very cool technique, widely used in C libraries, yet almost completely forgotten in C++.</p>
<p>We have a String class. It is a reference-counted, immutable string. Typical data structures in C++ would look like:</p>
<p><a href="http://www.altdevblogaday.com/2011/05/17/keep-data-close-part-1/" class="more-link">Read more on Keep data close, part 1&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I would like to present a very cool technique, widely used in C libraries, yet almost completely forgotten in C++.</p>
<p>We have a String class. It is a reference-counted, immutable string. Typical data structures in C++ would look like:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> string
<span style="color: #008000;">&#123;</span>
  string_data <span style="color: #000040;">*</span> data<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">struct</span> string_data
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">int</span> refcount<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">int</span> length<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> data<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></div></div>

<p>So, string is merely a reference to actual string_data. Creating new string objects (<tt>string foo = "hello world"</tt>) looks like:</p>
<ol>
<li>string_constructor(const char *)
<li>allocate string_data
<li>string_data_constructor(const char *)
<li>allocate char[]
<li>copy data, set all other members
</ol>
<p>In memory, it would actually look like:</p>
<p><a href="http://altdevblogaday.com/wp-content/uploads/2011/05/po-i1.png"><img src="http://altdevblogaday.com/wp-content/uploads/2011/05/po-i1.png" alt="" width="639" height="155" class="alignnone size-full wp-image-5990" /></a></p>
<p>So, we have one stack allocation, two dynamic allocations and our data is in three different places in memory. But in C++ terms it seems impossible to improve it. However, we can go C way and change <tt>string_data</tt> definition:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> string_data
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">int</span> refcount<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">int</span> length<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">char</span> data<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></div></div>

<p>Array of one character? I must be crazy, right?</p>
<p>Most C++ courses are not very precise about pointers and arrays. Especially, what is the difference of following instructions?</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> string1 <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;hello world&quot;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> string2<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;hello, C++!&quot;</span><span style="color: #008080;">;</span></pre></div></div>

<p>And what is the difference of those?</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> foo<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;*<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">int</span> foo<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;[]<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span></pre></div></div>

<p>Unfortunately, in C++ world where really various things can be <i>static</i>, answers are different. In first case, string1 and string2 are something else. In second case, there is no difference &#8212; actually, that code won&#8217;t compile due to non-unique overload.</p>
<p>Maybe little investigation? Let&#8217;s print some data:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%p %p %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, string1, <span style="color: #000040;">&amp;</span>string1, string1<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%p %p %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, string2, <span style="color: #000040;">&amp;</span>string2, string2<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>What we do is printing expression as a pointer, address of this expression as a second pointer and null-terminated string pointed by expression. Results:</p>
<pre>0x08048650 0xbfddbfa4 hello world
0xbfddbf98 0xbfddbf98 hello, C++!</pre>
<p>Now you see magic behind it. 0xbf&#8230;&#8230; are stack addresses while 0&#215;08048650 comes from somewhere else (likely from static, read-only data section). So, while pointer types hold address inside, arrays points to themselves. And we can abuse it!</p>
<p>&#8220;Typical&#8221; C++ allocation of string_data would look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">string_data <span style="color: #000040;">*</span> foo <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> string_data<span style="color: #008080;">;</span></pre></div></div>

<p>It would allocate <tt>sizeof(string_data)</tt> bytes (9 + padding, probably 12). But in fact, we can allocate as much as we want! For example:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">string_data <span style="color: #000040;">*</span> q <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>string_data<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">2</span> <span style="color: #000040;">*</span> <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #0000dd;">12</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000dd;">new</span> <span style="color: #008000;">&#40;</span>q<span style="color: #008000;">&#41;</span> string_data<span style="color: #008080;">;</span></pre></div></div>

<p>In this case &#8212; 2 ints and 12 bytes of string data. After successful allocation we need to manually invoke constructor, using placement new. Similarly, regular <tt>delete q</tt> won&#8217;t work &#8212; following code will:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">q<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>~string_data<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000dd;">free</span><span style="color: #008000;">&#40;</span>q<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>Of course if data type is simple (built-in datatypes, relaxed POD, whatever) there is no need to call constructor and destructor (although those calls probably would be simply optimized away). And malloc/free can be replaced with custom allocation routines.</p>
<p>And after such allocation, we can use <tt>data</tt> like it was not a <tt>char[1]</tt> array but rather a <tt>char[as much as we have allocated]</tt> array! How does memory look like with this data structure?</p>
<p><a href="http://altdevblogaday.com/wp-content/uploads/2011/05/po-i2.png"><img src="http://altdevblogaday.com/wp-content/uploads/2011/05/po-i2.png" alt="" width="639" height="224" class="alignnone size-full wp-image-5994" /></a></p>
<p>And there are numerous benefits of such approach:</p>
<ul>
<li>one dynamic allocation less
<li>data is less scattered in memory
<li>we saved some memory (how much? size of the pointer + size of allocation metadata)
</ul>
<p>In the next part, I&#8217;ll show how we can save even more allocations/memory (but probably only on my <a href="http://dabroz.scythe.pl/">personal blog</a>, so subscribe if you&#8217;re interested).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.altdevblogaday.com/2011/05/17/keep-data-close-part-1/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Binary shaders &#8212; not that big of a deal</title>
		<link>http://www.altdevblogaday.com/2011/05/02/binary-shaders-not-that-big-of-a-deal/</link>
		<comments>http://www.altdevblogaday.com/2011/05/02/binary-shaders-not-that-big-of-a-deal/#comments</comments>
		<pubDate>Mon, 02 May 2011 23:10:13 +0000</pubDate>
		<dc:creator>Tomasz Dąbrowski</dc:creator>
		
		<guid isPermaLink="false">http://altdevblogaday.org/?p=5003</guid>
		<description><![CDATA[<p>People complain that OpenGL lacks some important features. One of them is using precompiled binary shaders. Recently OpenGL got an ability to reuse compiled shader &#8212; but you still have to deliver source version of your shaders.</p>
<p><a href="http://www.altdevblogaday.com/2011/05/02/binary-shaders-not-that-big-of-a-deal/" class="more-link">Read more on Binary shaders &#8212; not that big of a deal&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>People complain that OpenGL lacks some important features. One of them is using precompiled binary shaders. Recently OpenGL got an ability to reuse compiled shader &#8212; but you still have to deliver source version of your shaders.</p>
<p>But this isn&#8217;t really a problem. Why? Let&#8217;s compile this simple shader with Nvidia Cg using different profiles.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="glsl" style="font-family:monospace;"><span style="color: #333399; font-weight: bold;">in</span> <span style="color: #000066; font-weight: bold;">float</span> var<span style="color: #000066;">;</span>
float4 main<span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">:</span> COLOR
<span style="color: #000066;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #000066;">&#40;</span>var <span style="color: #000066;">&gt;</span> <span style="color: #0000ff;">0.5</span><span style="color: #000066;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">return</span> float4<span style="color: #000066;">&#40;</span><span style="color: #0000ff;">1</span> <span style="color: #000066;">-</span> var<span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">else</span>
    <span style="color: #000000; font-weight: bold;">return</span> float4<span style="color: #000066;">&#40;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #993333; font-weight: bold;">sin</span><span style="color: #000066;">&#40;</span>var<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000066;">&#125;</span></pre></td></tr></table></div>

<p>First, arbfp1 assembly (roughly SM 2.0 equivalent):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="asm" style="font-family:monospace;">#const <span style="color: #000000; font-weight: bold;">c</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span> = <span style="color: #0000ff;">0</span> <span style="color: #0000ff;">1</span> <span style="color: #0000ff;">0.5</span>
PARAM <span style="color: #000000; font-weight: bold;">c</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">1</span><span style="color: #009900; font-weight: bold;">&#93;</span> = <span style="color: #009900; font-weight: bold;">&#123;</span> <span style="color: #009900; font-weight: bold;">&#123;</span> <span style="color: #0000ff;">0</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0.5</span> <span style="color: #009900; font-weight: bold;">&#125;</span> <span style="color: #009900; font-weight: bold;">&#125;</span><span style="color: #666666; font-style: italic;">;</span>
TEMP R0<span style="color: #666666; font-style: italic;">;</span>
TEMP R1<span style="color: #666666; font-style: italic;">;</span>
TEMP R2<span style="color: #666666; font-style: italic;">;</span>
SLT R0<span style="color: #339933;">.</span>x<span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">c</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">.</span>z<span style="color: #339933;">,</span> fragment<span style="color: #339933;">.</span>texcoord<span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;">;</span>
<span style="color: #000000; font-weight: bold;">ABS</span> R0<span style="color: #339933;">.</span>x<span style="color: #339933;">,</span> R0<span style="color: #666666; font-style: italic;">;</span>
<span style="color: #00007f; font-weight: bold;">CMP</span> R2<span style="color: #339933;">.</span>x<span style="color: #339933;">,</span> <span style="color: #339933;">-</span>R0<span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">c</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">c</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">.</span>y<span style="color: #666666; font-style: italic;">;</span>
<span style="color: #00007f; font-weight: bold;">MOV</span> R1<span style="color: #339933;">.</span>xzw<span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">c</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">.</span>xyxy<span style="color: #666666; font-style: italic;">;</span>
<span style="color: #00007f; font-weight: bold;">MOV</span> R0<span style="color: #339933;">.</span>yzw<span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">c</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">.</span>xxxy<span style="color: #666666; font-style: italic;">;</span>
SIN R1<span style="color: #339933;">.</span>y<span style="color: #339933;">,</span> fragment<span style="color: #339933;">.</span>texcoord<span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">.</span>x<span style="color: #666666; font-style: italic;">;</span>
<span style="color: #00007f; font-weight: bold;">ADD</span> R0<span style="color: #339933;">.</span>x<span style="color: #339933;">,</span> <span style="color: #339933;">-</span>fragment<span style="color: #339933;">.</span>texcoord<span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">c</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">.</span>y<span style="color: #666666; font-style: italic;">;</span>
<span style="color: #00007f; font-weight: bold;">CMP</span> result<span style="color: #339933;">.</span>color<span style="color: #339933;">,</span> <span style="color: #339933;">-</span>R2<span style="color: #339933;">.</span>x<span style="color: #339933;">,</span> R1<span style="color: #339933;">,</span> R0<span style="color: #666666; font-style: italic;">;</span>
<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

<p>As ARB shader assembler has no branching, both paths are executed and correct version is selected at the end. Now gp4fp version (~SM 4.0):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="asm" style="font-family:monospace;">TEMP R0<span style="color: #666666; font-style: italic;">;</span>
TEMP RC<span style="color: #339933;">,</span> HC<span style="color: #666666; font-style: italic;">;</span>
OUTPUT result_color0 = result<span style="color: #339933;">.</span>color<span style="color: #666666; font-style: italic;">;</span>
SGT<span style="color: #339933;">.</span>F R0<span style="color: #339933;">.</span>x<span style="color: #339933;">,</span> fragment<span style="color: #339933;">.</span>attrib<span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#123;</span><span style="color: #0000ff;">0.5</span><span style="color: #009900; font-weight: bold;">&#125;</span><span style="color: #666666; font-style: italic;">;</span>
TRUNC<span style="color: #339933;">.</span>U<span style="color: #339933;">.</span>CC HC<span style="color: #339933;">.</span>x<span style="color: #339933;">,</span> R0<span style="color: #666666; font-style: italic;">;</span>
<span style="color: #000000; font-weight: bold;">IF</span>    <span style="color: #000000; font-weight: bold;">NE</span><span style="color: #339933;">.</span>x<span style="color: #666666; font-style: italic;">;</span>
  <span style="color: #00007f; font-weight: bold;">MOV</span><span style="color: #339933;">.</span>F result_color0<span style="color: #339933;">.</span>yzw<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#123;</span><span style="color: #0000ff;">0</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span><span style="color: #009900; font-weight: bold;">&#125;</span><span style="color: #339933;">.</span>xxxy<span style="color: #666666; font-style: italic;">;</span>
  <span style="color: #00007f; font-weight: bold;">ADD</span><span style="color: #339933;">.</span>F result_color0<span style="color: #339933;">.</span>x<span style="color: #339933;">,</span> <span style="color: #339933;">-</span>fragment<span style="color: #339933;">.</span>attrib<span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#123;</span><span style="color: #0000ff;">1</span><span style="color: #009900; font-weight: bold;">&#125;</span><span style="color: #666666; font-style: italic;">;</span>
<span style="color: #000000; font-weight: bold;">ELSE</span><span style="color: #666666; font-style: italic;">;</span>
  <span style="color: #00007f; font-weight: bold;">MOV</span><span style="color: #339933;">.</span>F result_color0<span style="color: #339933;">.</span>xzw<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#123;</span><span style="color: #0000ff;">0</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span><span style="color: #009900; font-weight: bold;">&#125;</span><span style="color: #339933;">.</span>xyxy<span style="color: #666666; font-style: italic;">;</span>
  SIN<span style="color: #339933;">.</span>F result_color0<span style="color: #339933;">.</span>y<span style="color: #339933;">,</span> fragment<span style="color: #339933;">.</span>attrib<span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">.</span>x<span style="color: #666666; font-style: italic;">;</span>
<span style="color: #000000; font-weight: bold;">ENDIF</span><span style="color: #666666; font-style: italic;">;</span>
<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

<p>This time assembly generated is very similar to original code. If you play with compiling shaders on different profiles, you&#8217;ll also notice that in newer profiles like gp4*p optimizations are not pushed so hard. So my point is that:</p>
<ol>
<li>newer shader assembly profiles are way more complex than old SM 2.0
<li>and feature quite complex control flow instructions (branches, loops etc)
<li>many optimizations are left to the driver
<li>all advanced GLSL features (like UBO) would have to be implemented in assembler
</ol>
<p>Basically, GLSL assembler would like much like optimized GLSL source code with control flow slightly modified and variables renamed to r0&#8230;rN. But you can do it yourself! :) I&#8217;ve seen a least one game that used GLSL pre-optimization (same shader codebase was used for desktop and mobile OpenGL ES versions). And I think that there are bigger issues to address by Khronos than precompiled shaders.</p>
<p>On the other hand, an ability to dump compiled shader and reuse it later is a real killer. Also, in current <i>deferred</i> days number of shaders permutations is way lower than it used to be&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.altdevblogaday.com/2011/05/02/binary-shaders-not-that-big-of-a-deal/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>At the right time!</title>
		<link>http://www.altdevblogaday.com/2011/04/17/at-the-right-time/</link>
		<comments>http://www.altdevblogaday.com/2011/04/17/at-the-right-time/#comments</comments>
		<pubDate>Sun, 17 Apr 2011 00:03:31 +0000</pubDate>
		<dc:creator>Tomasz Dąbrowski</dc:creator>
		
		<guid isPermaLink="false">http://altdevblogaday.org/?p=4197</guid>
		<description><![CDATA[<p>I think that the source of many problems is doing something at the wrong moment. C++ is quite flexible, but a lot of its features can be accessed only in very awkward way. For example there is a limited support of compile-time evaluation, but accessible only with abusive use of templates*. There is no built-in reflection/serialization system &#8212; but again, people use templates and other language features to simulate it. <em>Given enough macrodefinitions (and possibly Boost), everything is possible&#8230;</em></p>
<p><a href="http://www.altdevblogaday.com/2011/04/17/at-the-right-time/" class="more-link">Read more on At the right time!&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I think that the source of many problems is doing something at the wrong moment. C++ is quite flexible, but a lot of its features can be accessed only in very awkward way. For example there is a limited support of compile-time evaluation, but accessible only with abusive use of templates*. There is no built-in reflection/serialization system &#8212; but again, people use templates and other language features to simulate it. <em>Given enough macrodefinitions (and possibly Boost), everything is possible&#8230;</em></p>
<p>But this is so wrong. The key to success is using right tools at the right time. Just few ideas:</p>
<ol>
<li>If doing X in some language/tool is difficult, <em>outsource </em>it. Maybe other languages/tools are more suitable to do it.</li>
<li>If you can isolate X in separate module/application, do it. Unix is all about small task-oriented application communicating over simple interfaces &#8212; and after 40 years it&#8217;s still doing great!</li>
<li>Pre-processing and post-processing is not only about lighting and shading. They can be applied to any kind of data, including code.</li>
<li>Auto-generated code is cool (as long as you control its generation).</li>
<li>Have flexible build system. Be able to plug any kind of processing into it.</li>
<li>Keep things simple!</li>
</ol>
<p>And now, few stories and one longer example. When I started building my engine/pipeline in early 2009 I had many questions to be answered. One of them was game [engine] and editor communication. For some reason I decided to use C++ for all game code but C# for the editor**. I needed communication between those two &#8212; that includes sending some objects in both directions. C# features rich reflection/serialization support, but C++ is far more inferior about those. However, instead of using some template/#define trickery, I just made a simple application that generated both C++ and C# classes with all serialization needed from simple classes description in JSON-like language. Generated C++ code was extremely simple &#8212; no templates/macros/virtuals. Can I call it a win?</p>
<p>Once I was working on (non-gamedev) application that was using REST-like web services. How can you access web methods in your app? Some languages/frameworks (like C#/.NET) feature built-in support for those. For other toolsets the best solution could be similar to .NET &#8212; have a generator that creates code for all requests. And having custom generator is neat, because you&#8217;re not limited to one specific data/services descriptions (like WSDL/SOAP for .NET***).</p>
<p>Finally, live example. But first let me present a disclaimer: this is not a post about implementing properties in C++. Implementation is rough and may make your HDD and/or eyeballs explode. Thank you. </p>
<p>So it&#8217;s about properties. I mean C#-style properties. Imagine such code:</p>
<pre>class Square
{
private:
  float _edge;
public:
  @property float edge
  {
    get
    {
      return _edge;
    }
    set
    {
      _edge = value;
    }
  }

  @property float area
  {
    get
    {
      return _edge * _edge;
    }
    set
    {
      _edge = sqrtf(value);
    }
  }
};
void print(float edge, float area)
{
  printf("edge = %f, area = %f\n", edge, area);
}
int main()
{
  Square s;
  s.area = 25;
  print(s.edge, s.area);
  s.edge = 3;
  print(s.edge, s.area);
  return 0;
}</pre>
<p>to be valid C++. Well, using code pre-processing it&#8217;s possible. </p>
<p>Using this program: <a href="http://gist.github.com/923509">http://gist.github.com/923509</a> you can transform this &#8220;C++&#8221; into real C++: <a href="http://gist.github.com/923634">http://gist.github.com/923634</a></p>
<p>Results?</p>
<pre>edge = 5.000000, area = 25.000000
edge = 3.000000, area = 9.000000</pre>
<p>Final thoughts: using code generators/pre-processing you can avoid using many unnecessary C++ features like templates. Keep things simple. C++ is hell, you will never be able to fully parse it without complex tools. Just assume good faith of your users while creating code processing tools. And I hope that such code processing will be integrated in future language (<a href="http://metalua.luaforge.net/">Metalua</a> seems to be quite cool!).</p>
<p>Other files: <a href="http://gist.github.com/923500/">input C++</a>, <a href="http://gist.github.com/923510">makefile</a>.</p>
<div style="font-size:80%">* C++0x constexpr, metaprogramming being fun, whatever. This is not a post about C++ pros and cons. Keep the big picture.</p>
<p>** Now I know that it probably wasn&#8217;t the best decision. But writing 2009 code with 2011 mindset would be too great.</p>
<p>*** Disclaimer: I&#8217;m no .NET expert.</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.altdevblogaday.com/2011/04/17/at-the-right-time/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Vicious circle of generalization</title>
		<link>http://www.altdevblogaday.com/2011/04/01/vicious-circle-of-generalization/</link>
		<comments>http://www.altdevblogaday.com/2011/04/01/vicious-circle-of-generalization/#comments</comments>
		<pubDate>Fri, 01 Apr 2011 20:35:53 +0000</pubDate>
		<dc:creator>Tomasz Dąbrowski</dc:creator>
		
		<guid isPermaLink="false">http://altdevblogaday.org/?p=3014</guid>
		<description><![CDATA[<p>One of the biggest programming problems, related mostly (but not exclusively) to OOP is generalization. There are numerous running jokes on Twitter, like <em>foo</em> function that is 100% future-proof:<br />
<tt></tt></p>
<p><tt>template &#60;typename T, typename T1&#62; virtual T foo(T1 t, ...) = 0;</tt></p>
<p><a href="http://www.altdevblogaday.com/2011/04/01/vicious-circle-of-generalization/" class="more-link">Read more on Vicious circle of generalization&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>One of the biggest programming problems, related mostly (but not exclusively) to OOP is generalization. There are numerous running jokes on Twitter, like <em>foo</em> function that is 100% future-proof:<br />
<tt></tt></p>
<p><tt>template &lt;typename T, typename T1&gt; virtual T foo(T1 t, ...) = 0;</tt></p>
<p>There are many failful designs out there that suffer greatly from generalization. Fine example is a 3D renderer I&#8217;ve seen once. It was written by a pro-OOP guy, and it was heavily templated, STLed and smart pointed. There were many [C]Material classes and various [C]Meshes and everything was tightly design patterned. So I&#8217;ve asked the author to add simple vertex extrusion along its normal. He instantly refused, pointing that he would have to add many additional classes for extended materials, shaders and parameters. Objects properties  and internal tools would also require changes. He said it would take about 10 to 20 man-hours. I said <em>Wait, it&#8217;s one line in shader and one additional parameter &#8212; why would it take so long?</em> And he replied: <em>My engine is designed to be easily extended, so such modifications require a lot of work.</em></p>
<p>This can be described as vicious circle of generalization:</p>
<ol>
<li>We want the code to be as generalized as possible.</li>
<li>We design everything future-proof and extendible.</li>
<li>When a feature request arrives, <span style="text-decoration: line-through">we&#8217;re doomed</span> we need to change a lot of code.</li>
<li>Why?</li>
<li>Because everything was designed as generalized as possible.</li>
<li><tt>goto 1;</tt></li>
</ol>
<p>And visual version:</p>
<p><a href="http://altdevblogaday.com/wp-content/uploads/2011/04/altdev2.jpg"><img class="alignnone size-medium wp-image-3023" src="http://altdevblogaday.com/wp-content/uploads/2011/04/altdev2-300x276.jpg" alt="" width="300" height="276" /></a></p>
<p>So &#8212; at least in my opinion &#8212; reject toxic design patterns and KISS instead. Small functional changes should not require big code changes. And everytime you over-engineer something, another startup dies (and there aren&#8217;t many left after all singleton experiments).</p>
<p><span style="font-size: 80%"><em>Disclaimer: this post is related to <a href="http://warsztat.gd/files/articles/igk2011/IGK2011_Dabrowski_Sawicki_slides.pdf">IGK presentation</a> [PL only, unfortunately] about efficient C++ and DOD from Adam Sawicki and me.</em></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.altdevblogaday.com/2011/04/01/vicious-circle-of-generalization/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Simple continous integration</title>
		<link>http://www.altdevblogaday.com/2011/03/17/simple-continous-integration/</link>
		<comments>http://www.altdevblogaday.com/2011/03/17/simple-continous-integration/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 23:28:37 +0000</pubDate>
		<dc:creator>Tomasz Dąbrowski</dc:creator>
		
		<guid isPermaLink="false">http://altdevblogaday.org/?p=2065</guid>
		<description><![CDATA[<p>Continuous integration is fun. There is probably a million ready-to-use tools to do it, but they may be too expensive/complicated/crappy or you just spent last 10 years building engine in your garage and hate everyone not invented here (there). Either way, I&#8217;m with you.</p>
<p><a href="http://www.altdevblogaday.com/2011/03/17/simple-continous-integration/" class="more-link">Read more on Simple continous integration&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Continuous integration is fun. There is probably a million ready-to-use tools to do it, but they may be too expensive/complicated/crappy or you just spent last 10 years building engine in your garage and hate everyone not invented here (there). Either way, I&#8217;m with you.</p>
<p>CI toolkit we are about to make consists of 3 separate parts:</p>
<p><strong>1. The Notifier</strong></p>
<p>Somehow we need to know that there is a work to do. Most VCSes are pluggable, allowing custom hooks occur on certain events (for example commit/push). But personally I prefer scheduled checks instead (as post-commit hooks may be slow). So basically cron (or Windows Task Scheduler) is your friend here.</p>
<p><strong>2. The Builder</strong></p>
<p>You need an automated build system here. On Windows it&#8217;s quite easy, because Visual Studio&#8217;s solution files can be used directly (<tt>devenv.com YourProject.sln /rebuild Release</tt>). On Linux/OSX there are makefiles/autotools, but for me using bash+make is quite painful. After all, the thing that programmers do the best is programming &#8212; so I&#8217;ve just wrote simple scripts to find all sources and build them, using PHP as scripting language of choice. Also, using PHP for whole &#8220;build system&#8221; is more cross-platform &#8212; it&#8217;s usually easier to bundle PHP executables than force anyone to install Cygwin shell (however I can&#8217;t imagine using Windows without it).</p>
<p>After building process is complete just call some simple API (see #3). Informations you need to send (you can use CURL for this) include project ID, OS/build version, build status, build logs (especially when build failed) and any other information you find useful. If you have unit tests you can attach them to logs. It&#8217;s also uber-cool to have automated test process (i.e. run game and start playing replay/script), taking screenshots at certain moments. You can also upload zipped package of game bundle (nightly builds).</p>
<p><strong>3. The Server</strong></p>
<p>Server receives API calls from building scripts. Data can be stored in DB. You will also need few pages that user can see (list of projects, versions, last N builds, specific build log). No rocket science here &#8212; average housewife can do it with PHP &amp; MySQL in no time. E-mail notifications about failed builds sum up the effort. If you use some project management tool you can send notifications there as well. For example Assembla.com lets you create/update a ticket with a plain old e-mail.</p>
<p>BTW: build process can be moved server-side if you are able and willing to do it. But it&#8217;s usually easier to find cheap PHP+MySQL hosting than fully-equipped server with SSH access and build tools (GCC + friends) installed (let alone running the game to take some screenshots).</p>
<p>I&#8217;ve been using such system for my small cross-platform experiments. I do most dev on Windows (where I have Visual Studio) but I want to keep Linux/OSX versions alive and kicking. Small open-source teams can (and should!) try it as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.altdevblogaday.com/2011/03/17/simple-continous-integration/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Yet Another C++ Rant</title>
		<link>http://www.altdevblogaday.com/2011/03/03/yet-another-c-rant/</link>
		<comments>http://www.altdevblogaday.com/2011/03/03/yet-another-c-rant/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 01:17:32 +0000</pubDate>
		<dc:creator>Tomasz Dąbrowski</dc:creator>
		
		<guid isPermaLink="false">http://altdevblogaday.org/?p=1471</guid>
		<description><![CDATA[<p>I may be in no position to criticize any programming language, but hey &#8212; we were told to be bold and controversial so here I am with Yet Another C++ Rant.</p>
<p><a href="http://www.altdevblogaday.com/2011/03/03/yet-another-c-rant/" class="more-link">Read more on Yet Another C++ Rant&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I may be in no position to criticize any programming language, but hey &#8212; we were told to be bold and controversial so here I am with Yet Another C++ Rant.</p>
<p style="text-align: center"><a href="http://yosefk.com/c++fqa"><img class="aligncenter" style="border: 0pt none" src="http://yosefk.com/c++fqa/images/cat.png" border="0" alt="[Cat++, a superset of cat]" width="200" height="209" /></a></p>
<p>C++ is a terrible language. I&#8217;m pretty sure all of you already know <a href="http://yosefk.com/c++fqa">C++ Frequently Questioned Answers</a> &#8212; it&#8217;s a bible of C++ quirks, a must-read. C++ claims to be multi-paradigm; procedural, object-oriented and generic. But it fails on all levels &#8212; I mean, have you ever tried to implement delegates in C++ without external libs? Or STL containers, they should be so superior to C# generics due to compile time evaluation, but have you ever seen assembly generated? And I&#8217;m pretty sure that the whole metaprogramming idea inspired many folks to build a CPU inside Minecraft.</p>
<p>But to be fair: a lot of good software was build and shipped with C++ (or <em>not entirely crippled by C++ </em>as FQA would state). So perhaps people may find use of various C++ features, depending on personal taste. But the real problem with C++ features is an <em>amount</em> of them. There are tonnes and tonnes of those features, some widely known and some remaining in the dark, waiting for years to shoot your foot off. And C++0X is only going to make things worse. I greatly admire people behind C++ compilers. Those guys are real heroes. But I&#8217;d love them to improve optimizations, not some bizzare and/or creepy features that are likely to explode when used together. If I didn&#8217;t care about performance, I would not use C++ anyway, right? But the sad fact is that a lot of C++ features prevent optimizations in direct (e.g. side effects you don&#8217;t care about) of indirect (because compilers are getting extremely complex) ways.</p>
<p>And you can&#8217;t expect people to know all those tiny little features of C++. It can be expressed like this:</p>
<p style="padding-left: 30px">(∀ x ∈ C++ programmers) (∃ ε &gt;  0) x is the only one who knows some bizarre C++ feature around radius ε</p>
<p>And so, to keep people sane and deliver some software, most companies that still use C++ put a lot of restrictions, mostly &#8220;don&#8217;t use &#8230;&#8221; (exceptions, RTTI, non-container templates, whatever you hate). In extreme cases, only &#8220;C with classes&#8221; is left. Not that it&#8217;s bad, it&#8217;s something I use personally (BTW: usage of C++ features can be perhaps measured in ratio of Release/Debug performance &#8212; and I know some games in which Cornell box level is just a little too much for debug build). But the compiler doesn&#8217;t know that we disrespect that &#8220;bad part&#8221; of C++ and still have to do its job.</p>
<p>Any alternatives to C++? It&#8217;s not easy. The sad fact is that most languages have compiler/library/IDE issues. D haven&#8217;t ever gained attention, C# is not crossplatform and Java is &lt;insert your favourite joke here&gt;. At the moment there is no easy replacement or at least I don&#8217;t see one.</p>
<p>But I keep my fingers crossed for LLVM. LLVM is a complete compiler infrastructure, but the most interesting part is backend: optimizations and generation of machine code (either static or JIT). Our job is &#8220;just&#8221; to make a front-end for our language, which is quite simple for simple languages (especially using tools like Flex/Bison). But why limit yourself to one language? I can think of following scenario:</p>
<ul>
<li>&#8220;main&#8221; language, similar to &#8220;C with classes and whatever we <em>really </em>need&#8221; used for most engine/game code</li>
<li>&#8220;computational&#8221; language, similar to shaders (see my previous post here)</li>
<li>&#8220;gameplay&#8221; language, similar to Lua</li>
</ul>
<p>The greatest benefit I see is that using uniform infrastructure we could glue those pieces of code without additional layers of wrappers (like in typical C++&amp;Lua code). Another win is uniform debugging using one tool only (LLVM IR may contain standardized debugging information). And of course another huge advantage is an ability to fine-tune each language to specific needs:</p>
<ul>
<li>&#8220;computational&#8221; language doesn&#8217;t need to have classes</li>
<li>but must have robust vector/matrix support</li>
<li>&#8220;no side effects&#8221; functions and compile-time optimizations using this</li>
<li>SSE/Altivec  is mandatory</li>
<li>GPU/SPU support would be cool, too (although some folks would be very unhappy not having to manually adjust SPU assembly)</li>
</ul>
<p>On the other hand:</p>
<ul>
<li>&#8220;gameplay&#8221; language could implement a number of Lua-like features</li>
<li>like functions as first-class citizens</li>
<li>maybe also coroutines</li>
<li>garbage collected, duck typed? a lot of options here</li>
</ul>
<p>But wouldn&#8217;t maintaining three different languages be harder than just one? Well&#8230; if you need a language suitable for any job with a bunch of features, I can&#8217;t help noticing that there is one already, yet I think you already know that I don&#8217;t like C++ very much. And wouldn&#8217;t maintaining any number of custom languages be harder than just shutting up and continuing to use C++? Honestly, I don&#8217;t know. While C++ is horrible as a language, it has excellent IDE/debugger/libraries/etc support. This would be very tricky to fight and you probably won&#8217;t get far without some kind of C/C++ compatibility in &#8220;main&#8221; language. However, I&#8217;d still give it a shot.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.altdevblogaday.com/2011/03/03/yet-another-c-rant/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Just-in-time Data Transformations</title>
		<link>http://www.altdevblogaday.com/2011/02/15/just-in-time-data-transformations/</link>
		<comments>http://www.altdevblogaday.com/2011/02/15/just-in-time-data-transformations/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 23:12:15 +0000</pubDate>
		<dc:creator>Tomasz Dąbrowski</dc:creator>
		
		<guid isPermaLink="false">http://altdevblogaday.org/?p=736</guid>
		<description><![CDATA[<p>A lot of code is about transforming data. Well, from a theoretic point of view all programming is about transforming data. Of course claiming that a video game is a function that integrates mouse movements into N-dimensions framebuffer is not exactly helpful, but sometimes it&#8217;s useful to see your data being processed. Some examples are quite intuitive (like using vertex shader do transform world space vertices into screen space ones) but others are hard to notice, especially with strong OOP mindset.</p>
<p><a href="http://www.altdevblogaday.com/2011/02/15/just-in-time-data-transformations/" class="more-link">Read more on Just-in-time Data Transformations&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>A lot of code is about transforming data. Well, from a theoretic point of view all programming is about transforming data. Of course claiming that a video game is a function that integrates mouse movements into N-dimensions framebuffer is not exactly helpful, but sometimes it&#8217;s useful to see your data being processed. Some examples are quite intuitive (like using vertex shader do transform world space vertices into screen space ones) but others are hard to notice, especially with strong OOP mindset.</p>
<p>But how can you do transformations the smart way? Actual vertex transformation is quite an easy case (if you&#8217;re not doing anything fancy) &#8212; do some (<em>fixed</em>) math and you&#8217;re good to go. Particle systems would be harder. Some systems could be stateless, some not. For some of them you would like to have billboards, for other some DOF unlocked. Some would use simple textures while others&#8230; etc. This can quickly get very complex. But let&#8217;s go even further &#8212; imagine a Diablo-like (or top-down shooter) game where you have hundreds of opponents, all of them casting spells or just throwing knives and chairs into you. There are many nice Flash games out there, but unfortunately most of them is no longer fun after first 200 sprites visible on screen.</p>
<h3>1. Fixed function</h3>
<p>You can start with something like (in pseudocode)</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">SpellsSystem<span style="color: #339933;">::</span><span style="color: #202020;">Update</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span> dt<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">for</span> each <span style="color: #009900;">&#40;</span>Spell s in spells<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// do some calculations and update s state</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This is OK, but how many different effects can your spell make? What is their relationship? Maybe some effects depend on certain conditions like time delay or other objects state? The bottom line is that it may end with heavily conditioned code or use of class inheritance/virtuals/etc. Either way this causes several problems:</p>
<ul>
<li>while the code itself may be more or less readable, it will be very hard to track what is exactly going on with specific object</li>
<li>performance will be rather choppy (it may not be so bad with good branch prediction &#8212; but there are other platforms than X86)&#8230;</li>
<li>&#8230;but it&#8217;s certainly going to be terrible in Debug mode. And what is the purpose of using Debug mode when your game hardly hits realtime (in SIGGRAPH terms) framerates, let alone  smooth gameplay?</li>
</ul>
<h3>2. Oh my XML</h3>
<p>But don&#8217;t forget that you also need to specify settings for particular data system. Some may be expressed with simple flags like <tt>Particle::isTransparent</tt> or <tt>Attack::isLethal</tt>. But what if you want to express something like &#8220;attack with acid cloud for 5 seconds and then throw fireball unless below 10 HP&#8221;? I&#8217;ve seen an actual game that used XML for such things:</p>
<div style="height: 200px;overflow: auto">

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;bullet&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;emitter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;speed</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;acceleration</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ttl</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.5&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;count</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;width</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;explode-on-fade</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bullet</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;data/physicals/invisible-bullet.xml&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;none&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;flight-effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;list&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;delayed&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;time</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.15&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;retarget&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target-chooser<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;none&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;range</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;2.0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;angle</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;60.0&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aim-at-ground</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target-chooser<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;list&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;jump&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;crawling-lightning&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;bullet&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;emitter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;speed</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;acceleration</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ttl</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.5&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;count</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;width</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;explode-on-fade</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bullet</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;data/physicals/invisible-bullet.xml&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;none&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;flight-effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;delayed&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;time</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.15&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;retarget&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target-chooser<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;none&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;range</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1.5&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;angle</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;60.0&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aim-at-ground</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target-chooser<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;list&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;jump&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;crawling-lightning&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;bullet&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;emitter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;speed</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;acceleration</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ttl</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.5&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;count</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;2&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;width</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;explode-on-fade</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bullet</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;data/physicals/invisible-bullet.xml&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;none&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;flight-effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;delayed&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;time</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;0.15&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;retarget&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target-chooser<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;none&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;range</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;angle</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;60.0&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aim-at-ground</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target-chooser<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;effect</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;jump&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;crawling-lightning&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/flight-effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/emitter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/flight-effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/emitter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/flight-effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/emitter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

</div>
<p>Other possibility is to use graph nodes editor and carefully connects all such effects, actions and conditions.</p>
<p><em>(image omitted &#8212; too big and scary)</em></p>
<h3>3. Programmable pipeline</h3>
<p>Some time ago I&#8217;ve written a <a href="http://dabroz.scythe.pl/2010/11/18/quick-data-transformation">blog post</a> about data transformation pipeline build around Flex/Bison/ASMjit (and recently LLVM). This can be thought as something like regular data shader (or <em>object shader</em> if you like silly buzzwords). You can basically write a piece of code that is somewhere between a shader and Lua script and compile it in runtime. You can use your favourite approach (class hierarchy-based, components-based) and it&#8217;s still going to be fast because it&#8217;ll end as (hopefully) branchless piece of raw data processing code. You can even use XML or nodes editor to prepare such code, but &lt;rant&gt; I have no idea why anyone would like to link graph nodes instead of writing C-like code. I mean, try to implement, debug and optimize HBAO using only your mouse. &lt;/rant&gt;</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> State
<span style="color: #008000;">&#123;</span>
   float4 <span style="color: #000040;">*</span> positions<span style="color: #008080;">;</span>
   float4 <span style="color: #000040;">*</span> orientations<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">uint32_t</span> <span style="color: #000040;">*</span> hps<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">struct</span> Output
<span style="color: #008000;">&#123;</span>
   State new_state<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">uint32_t</span> <span style="color: #000040;">*</span> attack_types<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">void</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>transform_data<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>State <span style="color: #000040;">&amp;</span>, Output <span style="color: #000040;">&amp;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>Using such method, you gain performance boost in general, thanks to:</p>
<ul>
<li>using struct-of-arrays data input &amp; output</li>
<li>agressive inlining</li>
<li>not including unnecessary code in transformation (hopefully branchless)</li>
<li>optimizations of data transform code are independent with <em>general</em> profile so you can still enjoy thousands of objects in Debug</li>
<li>ability to target to specific machine (I mean, most of general JIT-ted languages like C# don&#8217;t really benefit from SSE etc., but here you can enjoy full processor power not relying that all end-users actually have SSE 4.2 and fancy DPPS ops)</li>
<li>last but not least, it can be easily parallelized</li>
</ul>
<p><strong><em>Why don&#8217;t use OpenCL/CUDA/DirectCompute for this?</em></strong></p>
<p>As far as I can see, CPU OpenCL implementations are still not production-ready (at least when I was digging the subject). And other solutions are too vendor-specific.</p>
<p><strong><em>Why don&#8217;t use GPU for this?</em></strong></p>
<p>Well, most of the time you could. But most GPGPU evangelists have trouble noticing that in typical video game, GPU already has a lot to do. So, depending on your specific needs, using GPU for heavy computations could only slow down the application in overall. But this is also system dependent. Gamers can have powerful GPU combined with low-end CPU and vice-versa. Additionally don&#8217;t forget that there is a lot of overhead in copying data between GPU and CPU. So there is no silver bullet but of course the ability to do those computations on GPU is cool.</p>
<p><span style="color: #c0c0c0">PS. I&#8217;ll try to post some benchmarks if this is interesting enough. And feel free to correct any errors &#8212; after all, I&#8217;m not AAA veteran with 30 years of experience. ;<b></b>)<br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.altdevblogaday.com/2011/02/15/just-in-time-data-transformations/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

