<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4124421301687405748</id><updated>2011-10-11T10:05:27.607+02:00</updated><title type='text'>Graphics Size Coding</title><subtitle type='html'>More Graphics, less code.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>72</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7361009263406639038</id><published>2010-10-30T21:11:00.002+02:00</published><updated>2010-10-30T21:12:49.627+02:00</updated><title type='text'>Qoob added to GeeXLab</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TMxt9JgYdKI/AAAAAAAAAP4/FenJy7vSWfs/s1600/qoobgeexlab.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://2.bp.blogspot.com/_xl45__0O0dM/TMxt9JgYdKI/AAAAAAAAAP4/FenJy7vSWfs/s400/qoobgeexlab.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;JeGX has added Qoob 1.0.2 support to his graphics quick prototyping tool GeeXLab.There is already a demo out. &lt;a href="http://qoob.weebly.com/1/post/2010/10/geexlab-adds-qoob-support.html"&gt;More about Qoob in GeeXLab and how to download&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7361009263406639038?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/7361009263406639038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-added-to-geexlab.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7361009263406639038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7361009263406639038'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-added-to-geexlab.html' title='Qoob added to GeeXLab'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/TMxt9JgYdKI/AAAAAAAAAP4/FenJy7vSWfs/s72-c/qoobgeexlab.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-6124292146967352955</id><published>2010-10-25T23:34:00.001+02:00</published><updated>2010-10-25T23:35:49.335+02:00</updated><title type='text'>Qoob added to ZGE</title><content type='html'>Vill Krumlinde has added Qoob 1.0.2 support to the &lt;a href="http://www.zgameeditor.org/"&gt;ZGameEditor (ZGE)&lt;/a&gt;. See the full details at the news section at the Qoob website as well as a link to the first ZGE demo containing qoob...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://qoob.weebly.com/news.html"&gt;http://qoob.weebly.com/news.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-6124292146967352955?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/6124292146967352955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-added-to-zge.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6124292146967352955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6124292146967352955'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-added-to-zge.html' title='Qoob added to ZGE'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-491180199399341845</id><published>2010-10-24T00:31:00.001+02:00</published><updated>2010-10-24T00:34:06.607+02:00</updated><title type='text'>Qoob libs Released and Modeller Upgraded</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TMNhejkusVI/AAAAAAAAAP0/Cpa6-W16jsg/s1600/shot_125.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="251" src="http://2.bp.blogspot.com/_xl45__0O0dM/TMNhejkusVI/AAAAAAAAAP0/Cpa6-W16jsg/s320/shot_125.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Qoob libraries are out! You can now include qoob models in intros or anything really. To go with the libs, the modeller has been upgraded and many bugs removed. It should be 99% stable now. There are a few new features such as moving the model using the mouse (much requested). Oh and Undo now works ... ahem...better.&lt;br /&gt;&lt;br /&gt;Check it out at&lt;a href="http://www.blogger.com/goog_1716766997"&gt; &lt;/a&gt;&lt;a href="http://qoob.weebly.com/"&gt;http://qoob.weebly.com &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-491180199399341845?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/491180199399341845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-libs-released-and-modeller.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/491180199399341845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/491180199399341845'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-libs-released-and-modeller.html' title='Qoob libs Released and Modeller Upgraded'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/TMNhejkusVI/AAAAAAAAAP0/Cpa6-W16jsg/s72-c/shot_125.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7667363839058548279</id><published>2010-10-16T11:18:00.002+02:00</published><updated>2010-10-16T11:24:21.855+02:00</updated><title type='text'>Benoit Mandelbrot Dead</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_xl45__0O0dM/TLlvMyi_OmI/AAAAAAAAAPw/AJBk_Ny6s-s/s1600/fractals-Benoit-Mandelbrot.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/_xl45__0O0dM/TLlvMyi_OmI/AAAAAAAAAPw/AJBk_Ny6s-s/s320/fractals-Benoit-Mandelbrot.jpg" width="231" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TLltv5gr6eI/AAAAAAAAAPs/fzUYPWO_C40/s1600/180px-JohnvonNeumann-LosAlamos.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;Rest in peace, sir.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7667363839058548279?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/7667363839058548279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2010/10/benoit-mandelbrot-dead.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7667363839058548279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7667363839058548279'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/10/benoit-mandelbrot-dead.html' title='Benoit Mandelbrot Dead'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_xl45__0O0dM/TLlvMyi_OmI/AAAAAAAAAPw/AJBk_Ny6s-s/s72-c/fractals-Benoit-Mandelbrot.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2253759120893281818</id><published>2010-10-15T09:01:00.008+02:00</published><updated>2010-10-15T09:08:55.224+02:00</updated><title type='text'>Simple Code to Calculate normals for a Quad Mesh</title><content type='html'>I'm ripping iq here. However, I've fiound a lot of people haven't read his brilliant normals idea buried deep in one of his presentations, plus I add face normals and a subtle way to rewrite crossproduct that shortens code again.&lt;br /&gt;&lt;br /&gt;Here is some tiny&amp;nbsp;&lt;b&gt; pseudo-code&lt;/b&gt; to calculate both the vertex and face normals of a&amp;nbsp; mesh made of quads. It is pseudo-code because your mesh structure will not be the same as mine.&amp;nbsp; The idea is based on&lt;a href="http://www.iquilezles.org/www/material/breakpoint2007/bp2007.pdf"&gt; iqs idea in his Breakpoint presentation.&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&lt;span style="font-size: small;"&gt;for ( i=0; i&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;numberofquads; i++) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;nmberofquads; ++)="" i=""&gt;&lt;numberofquads; i++)="" {=""&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;for (uint k=0; k&amp;lt;4; k++)&amp;nbsp; cross ( &amp;amp;quad[i].v[k], &amp;amp;quad[i].v[(k+1)&amp;amp;3], &amp;amp;facenormals[i] );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;for (uint k=0; k&amp;lt;4; k++)&amp;nbsp; add ( &amp;amp;facenormals[i], &amp;amp;vertexnormals[&amp;amp;quad[i].v[k]]);&lt;br /&gt;&amp;nbsp;}&lt;/numberofquads;&gt;&lt;/nmberofquads;&gt;&lt;/span&gt;&lt;/blockquote&gt;Now this neat and easy to read and incredibly small for such power. Essentially it is:&lt;br /&gt;&lt;blockquote&gt;for each quad&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for each edge in quad&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; accumulate crossproduct of edge vertices into face normal&lt;br /&gt;&amp;nbsp;&amp;nbsp; for each vertex in quad&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; add face normal &lt;/blockquote&gt;&lt;br /&gt;One subtle trick here in the code is that &lt;b&gt;cross product is redefined&lt;/b&gt; thus:&lt;br /&gt;cross(v1,v2,v3) ::&amp;nbsp; v3 = v3 + crossproduct (v1,v2)&lt;br /&gt;Add is as you expect:: &lt;br /&gt;add(v1,v2):: v2=v2+v1;&lt;br /&gt;&lt;br /&gt;During qoob modeller writing I found redefining cross product in this way was fine, after all it can be called with a zeroed vector in last place if a true cross product is required rather than accumulating. If you don't understand how accumulating cross products of each edge of the polygon equates to calculating a normal, see iqs presentation. That is the really smart thing here.&lt;br /&gt;&lt;br /&gt;N.B.: Assumes facenormals and vertexnormals contain zero values before calling this function.&lt;br /&gt;&amp;nbsp;The normals are not normalised (leave that to shaders or GL_NORMALIZE).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2253759120893281818?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/2253759120893281818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2010/10/simple-code-to-calculate-normals-for.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2253759120893281818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2253759120893281818'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/10/simple-code-to-calculate-normals-for.html' title='Simple Code to Calculate normals for a Quad Mesh'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-5624245405868928809</id><published>2010-10-15T08:29:00.001+02:00</published><updated>2010-10-20T16:06:17.103+02:00</updated><title type='text'>Qoob moved to its own website</title><content type='html'>So that this blog can get back to non-qoob stuff, qoob has been moved to &lt;a href="http://qoob.weebly.com/"&gt;http://qoob.weebly.com&lt;/a&gt;&lt;br /&gt;The whole package including .h and .o to link against will be out (this weekend) ermm not quite.. real soon now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-5624245405868928809?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/5624245405868928809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-moved-to-its-own-website.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5624245405868928809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5624245405868928809'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-moved-to-its-own-website.html' title='Qoob moved to its own website'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7292359882624141464</id><published>2010-10-03T16:18:00.001+02:00</published><updated>2010-10-03T16:27:24.394+02:00</updated><title type='text'>Qoob (OpenGL version) final results</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_xl45__0O0dM/TKiLyx80I0I/AAAAAAAAAOM/vI7xXg0nhH4/s1600/shot_129.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiLyx80I0I/AAAAAAAAAOM/vI7xXg0nhH4/s200/shot_129.jpg" width="158" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_xl45__0O0dM/TKiL02aSPrI/AAAAAAAAAOU/Eu7mQxSZW5c/s1600/shot_73.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="151" src="http://3.bp.blogspot.com/_xl45__0O0dM/TKiL02aSPrI/AAAAAAAAAOU/Eu7mQxSZW5c/s200/shot_73.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_xl45__0O0dM/TKiL0K2kaNI/AAAAAAAAAOQ/z3b0A8HATMk/s1600/intro+2010-09-23+07-22-05-76.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="223" src="http://3.bp.blogspot.com/_xl45__0O0dM/TKiL0K2kaNI/AAAAAAAAAOQ/z3b0A8HATMk/s400/intro+2010-09-23+07-22-05-76.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_xl45__0O0dM/TKiL2X9JYeI/AAAAAAAAAOY/dsABNAODJrw/s1600/shot_81.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="157" src="http://4.bp.blogspot.com/_xl45__0O0dM/TKiL2X9JYeI/AAAAAAAAAOY/dsABNAODJrw/s200/shot_81.jpg" width="200" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL3lOlkrI/AAAAAAAAAOc/xYhTE9ZlFLo/s1600/shot_84.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="146" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL3lOlkrI/AAAAAAAAAOc/xYhTE9ZlFLo/s200/shot_84.jpg" width="200" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL4-CgtUI/AAAAAAAAAOg/C53OdNKoRgE/s1600/shot_91.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="214" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL4-CgtUI/AAAAAAAAAOg/C53OdNKoRgE/s400/shot_91.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_xl45__0O0dM/TKiL5g6CLTI/AAAAAAAAAOk/ZV8GhUDn8h4/s1600/shot_93.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/_xl45__0O0dM/TKiL5g6CLTI/AAAAAAAAAOk/ZV8GhUDn8h4/s200/shot_93.jpg" width="138" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL6TMOWpI/AAAAAAAAAOs/V-B93ZvAS5Q/s1600/shot_99.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL6TMOWpI/AAAAAAAAAOs/V-B93ZvAS5Q/s200/shot_99.jpg" width="176" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL7ItRAeI/AAAAAAAAAOw/FCM3RpNjPHc/s1600/shot_100.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="156" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL7ItRAeI/AAAAAAAAAOw/FCM3RpNjPHc/s200/shot_100.jpg" width="200" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL8tulu0I/AAAAAAAAAO4/LeUf19yFnDQ/s1600/shot_107.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="156" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL8tulu0I/AAAAAAAAAO4/LeUf19yFnDQ/s200/shot_107.jpg" width="200" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL8OooYxI/AAAAAAAAAO0/Or88wN4spuQ/s1600/shot_101.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="156" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL8OooYxI/AAAAAAAAAO0/Or88wN4spuQ/s200/shot_101.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL9aRUpAI/AAAAAAAAAO8/HXegFfX-3Fg/s1600/shot_112.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="149" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL9aRUpAI/AAAAAAAAAO8/HXegFfX-3Fg/s200/shot_112.jpg" width="200" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TKiMcPs_UWI/AAAAAAAAAPc/dakGn2EolwY/s1600/shot_103.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="156" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiMcPs_UWI/AAAAAAAAAPc/dakGn2EolwY/s200/shot_103.jpg" width="200" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_xl45__0O0dM/TKiL-IgA3JI/AAAAAAAAAPE/SHvxKND-944/s1600/shot_121.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="251" src="http://3.bp.blogspot.com/_xl45__0O0dM/TKiL-IgA3JI/AAAAAAAAAPE/SHvxKND-944/s320/shot_121.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL9pKUzMI/AAAAAAAAAPA/GracGlDYS6E/s1600/shot_120.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL9pKUzMI/AAAAAAAAAPA/GracGlDYS6E/s320/shot_120.jpg" width="230" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TKiMchHuIuI/AAAAAAAAAPg/FksMSwGnRRQ/s1600/shot_95.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiMchHuIuI/AAAAAAAAAPg/FksMSwGnRRQ/s320/shot_95.jpg" width="130" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL_AWDOMI/AAAAAAAAAPM/9n2k2TOZt9U/s1600/shot_124.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="175" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL_AWDOMI/AAAAAAAAAPM/9n2k2TOZt9U/s200/shot_124.jpg" width="200" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_xl45__0O0dM/TKiMAkuGoSI/AAAAAAAAAPY/JWwZHPr8Ujc/s1600/shot_128.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/_xl45__0O0dM/TKiMAkuGoSI/AAAAAAAAAPY/JWwZHPr8Ujc/s200/shot_128.jpg" width="198" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL-p7ragI/AAAAAAAAAPI/Wn2d5ed529o/s1600/shot_123.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL-p7ragI/AAAAAAAAAPI/Wn2d5ed529o/s200/shot_123.jpg" width="198" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;Qoob library for 3d modelling and uncompression of 3d models is compiled in two ways. One includes all the loading and saving etc used for modelling. The other mode is an intro mode. After making a basic test intro with qoob, I discovered speed was a factor and had to rewrite a few routines. This forced me to add a few bytes but not too many. Now finding normals and smoothing are much much faster and models typically load in sub-second time.This is important if we are using 50+ models in an intro - compo rules usually enforce a total run time that includes loading/unpacking.&lt;br /&gt;&lt;br /&gt;The final size using crinkler 1.1 with settings : &lt;br /&gt;&lt;span style="font-size: x-small;"&gt;/CRINKLER /COMPMODE:SLOW&amp;nbsp; /ORDERTRIES:3000 /UNSAFEIMPORT /REPORT:report.html /TRANSFORM:CALLS &lt;/span&gt;&lt;br /&gt;is &lt;b&gt;2165 bytes&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;This includes, selection handling and recording specific polygons used in modelling, 3d maths lib, catmull clarke smoothing with holes, subdivision, insertion and deletion, unpack routine, extrusion, tapering, bulging, rotations, translations and scaling on polygons and model level, making a cage and making rounded holes, basic cube geometry, vertex and face normals.&lt;br /&gt;&lt;br /&gt;Models vary in size. The largest I've done so far is around 350 bytes which was a unicorn head. The compression of models is better than I predicted as picking polygons early in modelling is inexpensive as polygon ids fit within one byte and crinkler does a good job with them. Most abstract models come in around 30-70 bytes and most real world ones 100-200. Better than expected.&lt;br /&gt;&lt;br /&gt;If you want to play with the qoob modeller (opengl), send me an email on my gmail account chris &lt;dot&gt; thornborrow and I'll release it to you. Especially if you are a 3d modeller used to wings3d - I'd like feedback.&lt;/dot&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_xl45__0O0dM/TKiSwuXPs7I/AAAAAAAAAPo/36dyScXuO4U/s1600/ghead.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="287" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiSwuXPs7I/AAAAAAAAAPo/36dyScXuO4U/s320/ghead.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7292359882624141464?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/7292359882624141464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-opengl-version-final-results.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7292359882624141464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7292359882624141464'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/10/qoob-opengl-version-final-results.html' title='Qoob (OpenGL version) final results'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/TKiLyx80I0I/AAAAAAAAAOM/vI7xXg0nhH4/s72-c/shot_129.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-5089152149544980978</id><published>2010-08-11T00:29:00.001+02:00</published><updated>2010-08-11T00:29:52.106+02:00</updated><title type='text'>3d Modelling : the challenges for Compression</title><content type='html'>Quick reminder, qoob is a modeller and library that stores 3d models by a series of modelling commands, not by storing the mesh. The hope is to get smaller models for intros. As I write qoob, three fundamental challenges are emerging: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;The size of the qoob library with the modelling commands code&lt;/li&gt;&lt;li&gt;Storing modelling commands in a compact way&lt;/li&gt;&lt;li&gt;Picking and selection compression&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;The Size of the Library&lt;/b&gt;&lt;br /&gt;The Qoob library is around 2k after compression. It must be included in intros to decode cube models. As such the existing library simply wont work at 4k. Its fine for 64k and for 8k/16k. However I'm also hopeful a much smaller one could be produced. There would be three keys:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;use DX maths and subdivision&lt;/li&gt;&lt;li&gt; reduce the modelling options and target abstract objects ONLY&lt;/li&gt;&lt;li&gt;use default values for all functions so storing a model means storing only a series of commands - no parameters.&lt;/li&gt;&lt;/ul&gt;That may seem crazy but there are a huge range of abstract objects that can be done this way. From plants to cubes to geometric abstracts. Even basic human figures.The first characters I showed on this blog were done this way!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Storing Modelling Commands&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I made the mistake of targetting a low number of entry points in qoob lib. This kept the library small and tight but meant even a simple extrude needed 9 bytes to store!! However after considerable redesign, I've managed to reduce the average byte count per modelling command to less than 2. The result is less compressible but not by much&lt;b&gt; &lt;/b&gt;and a factor of 5x on average is a very good saving. 50 modelling commands is a enough for many models. Thats 100 bytes BEFORE compression.&lt;br /&gt;&lt;br /&gt;The first trick was to increase the number of possible commands (eg translate became translate, translateX, translateY, translateZ). Translate in X requires only one float whereas translate requires 3. Often the modeller does not need the full expressive power. In most cases the reduced bytes needed to store the new commands parameters far outweigh the extra code, which is highly compressible.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;The second trick comes from accepting that we dont need the full range and accuracy of floats. A single byte is enough for most functions and should greater range be required, the modeller can always concatenate. For example, a translate in X can be expressed as a single byte. If further translation is required, the modeller simply translates again, however usually this is not the case.&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Selection Compression&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A talk with iq depressed me. Essentially selections needs 5 bytes (command and quad id) to store. In addition polygon ids are random (over many picks) and so do not compress. Iq guessed that 50 picks would render qoob models less effective than mesh based compression.&lt;br /&gt;Well this is a fundamental mathematical barrier. The trick is to avoid it. Procedural selection comes to the rescue. Commands like "select similar" from wings3d mean that the modeller picks a single seed polygon then expands the selection using a command or two.&lt;br /&gt;I'm still exploring the solution here so more when I'm sure what is a good thing but Im pleased with what I have so far.&lt;br /&gt;&lt;br /&gt;So qoob lib got bigger but that could be fixed by porting to dx and reducing flexibility. Models got much smaller and picking is nearly solved but again costs bytes in the library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-5089152149544980978?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5089152149544980978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5089152149544980978'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/08/3d-modelling-challenges-for-compression.html' title='3d Modelling : the challenges for Compression'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-5359526878037121500</id><published>2010-08-09T12:17:00.000+02:00</published><updated>2010-08-09T12:17:04.528+02:00</updated><title type='text'>Simple Algebraic Surfaces Reference</title><content type='html'>Serious size coding involves trawling forums and the net for ideas and resources. Here is a little link that came over twitter this morning with a bunch of tiny algebraic surfaces that may, or may not, be useful:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.freigeist.cc/gallery.html"&gt;http://www.freigeist.cc/gallery.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-5359526878037121500?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5359526878037121500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5359526878037121500'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/08/simple-algebraic-surfaces-reference.html' title='Simple Algebraic Surfaces Reference'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-6930505676414308995</id><published>2010-07-19T23:49:00.007+02:00</published><updated>2010-07-20T08:09:58.144+02:00</updated><title type='text'>Qoob Matures</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/TETJkjbYmsI/AAAAAAAAANs/F81p2TvPtms/s1600/shot_84.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 235px;" src="http://1.bp.blogspot.com/_xl45__0O0dM/TETJkjbYmsI/AAAAAAAAANs/F81p2TvPtms/s320/shot_84.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5495739075121420994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Qoob now has about 80% of the functionality I want in a basic modeller, at least for now. For personal reasons I will take a break from coding for a few weeks and leave you with a few more sample images. The next step will be to make an actual intro using the tool. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TETJY3D12zI/AAAAAAAAANk/EHIMBU6-27c/s1600/shot_83.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 253px;" src="http://3.bp.blogspot.com/_xl45__0O0dM/TETJY3D12zI/AAAAAAAAANk/EHIMBU6-27c/s320/shot_83.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5495738874232953650" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Click on the images for larger versions. I've managed to get some organic, some holes and some asymmetry into the modeller. Undo is implemented (well,ok, one level). The next major step is to put the geometry lib into a 64k framework.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TETKIRbTAyI/AAAAAAAAAN0/tRH1NFeMcBg/s1600/shot_90.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 175px;" src="http://3.bp.blogspot.com/_xl45__0O0dM/TETKIRbTAyI/AAAAAAAAAN0/tRH1NFeMcBg/s320/shot_90.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5495739688764506914" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TETKb7po_oI/AAAAAAAAAN8/pJL0gFmzYtI/s1600/shot_91.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 174px;" src="http://2.bp.blogspot.com/_xl45__0O0dM/TETKb7po_oI/AAAAAAAAAN8/pJL0gFmzYtI/s320/shot_91.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5495740026516471426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But a burning question is - how big is the Qoob library? Whats the overhead?&lt;br /&gt;Here is a test I performed.&lt;br /&gt;Using crinkler 1.0 ( I cant get 1.1 to work for me) I constructed a minimal OGL program : 600 bytes after compression. I then added Qoob library and called each function once to force inclusion. The program size was 2.4k with crinkler settings of /CRINKLER /COMPMODE:SLOW /ORDERTRIES:3000 /UNSAFEIMPORT. No smarts here to help crinkler and probably not the right settings. Likely, the library can shrink a bit but also could grow a little with the few functions I have left to put in. Its safe to assume therefore that &lt;2k is the Qoob overhead. &lt;br /&gt;&lt;br /&gt;2k - thats good, better than I expected. Very useful for 64k. The models range from 3 bytes (a chamfered cube) to 200 for the characters. &lt;br /&gt;&lt;br /&gt;Maybe its worth rewriting this using DirectX and getting it into 4ks after all? The 4k might be non-demoscene standard - a sort of model show in 4k...but thats an achievement by itself in some ways.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-6930505676414308995?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6930505676414308995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6930505676414308995'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/07/qoob-matures.html' title='Qoob Matures'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/TETJkjbYmsI/AAAAAAAAANs/F81p2TvPtms/s72-c/shot_84.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-3585828004034968648</id><published>2010-07-19T14:54:00.005+02:00</published><updated>2010-07-19T15:02:18.606+02:00</updated><title type='text'>Shorter code for Point in Interval</title><content type='html'>Nice little coding trick for checking if a value lies within two other values. The result is faster and (slightly) smaller than checking both values. The trick could be extended to do bounding box intersections for collision detection for example.&lt;br /&gt;&lt;a href="http://www.strchr.com/checking_if_point_belongs_to_interval"&gt;&lt;br /&gt;Neat trick&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It resolves down to this macro:&lt;br /&gt;&lt;br /&gt;#define InRange(ch, a, b) (unsigned((ch) - (a)) &lt;= (b) - (a))&lt;br /&gt;&lt;br /&gt;.cool&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-3585828004034968648?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/3585828004034968648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/3585828004034968648'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/07/shorter-code-for-point-in-interval.html' title='Shorter code for Point in Interval'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-73227050573344418</id><published>2010-07-18T14:34:00.004+02:00</published><updated>2010-07-18T15:00:30.669+02:00</updated><title type='text'>Qoob Character modelling</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/TEL2zq8Cd5I/AAAAAAAAANc/gOVwkXJMNI0/s1600/shot_89.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 252px;" src="http://1.bp.blogspot.com/_xl45__0O0dM/TEL2zq8Cd5I/AAAAAAAAANc/gOVwkXJMNI0/s320/shot_89.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5495225862905296786" /&gt;&lt;/a&gt;&lt;br /&gt;So, Qoob, the tiny modeller, finally is competent enough to model simple characters. Its all a bit pikachu for now - but that may be more my inner pokemon than the tool, not sure yet. The qoob library grew hardly at all to support this, only the modeller.&lt;br /&gt;&lt;br /&gt;Characters are about 200 bytes. Thats ok but not great. The culprit is picking. You do quite a lot of polygon picking to model the limbs, eyes, nose etc. Click on the images to see larger versions.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TEL11Cq14eI/AAAAAAAAANU/MlvKPnS0GhI/s1600/character.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 251px;" src="http://2.bp.blogspot.com/_xl45__0O0dM/TEL11Cq14eI/AAAAAAAAANU/MlvKPnS0GhI/s320/character.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5495224786943861218" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Picking consists of a command (1 byte) and a polygon (3 bytes). Thats 4 bytes before compression. Assuming the command compresses well, the specific polygon id is the problem. A lot of the time the first byte will be zero which will help. Still, we can assume a total of 3 bytes on average per pick after compression. These models take about 50 picks. Hence 150 bytes as a base. Ideas:&lt;br /&gt;1. Store the command pick n times, (meaning select the next polygon n away in the array). This means great compression but even so, thats a lot of data to compress and there may be problems.&lt;br /&gt;2. Duplicate what the modeller does, by storing the 2d pick co-ordinates and have qoob lib project that into polygon space. Well its 2-3 bytes anyway and then the projection code. So no.&lt;br /&gt;3. Delta encode the polygon id. In my modelling at least this would help often. Polygons being picked often come from the same base polygon in the model before subdivision and therefore their ids are similar.&lt;br /&gt;4. Exploit hierarchy of subdivision more ... have to think here. In theory a polygon might be identified by 3 bits for original face of cube (the base input)2 bits x n where n is the subdivision level.&lt;br /&gt;5. Restrict picking to be pick + grow pick. This would help with large groups of polys but the modeller would go nuts.&lt;br /&gt;&lt;br /&gt;... hmm need to think more, none of the above convince me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-73227050573344418?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/73227050573344418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/73227050573344418'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/07/qoob-character-modelling.html' title='Qoob Character modelling'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/TEL2zq8Cd5I/AAAAAAAAANc/gOVwkXJMNI0/s72-c/shot_89.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-5909934832331773261</id><published>2010-07-10T09:51:00.007+02:00</published><updated>2010-07-10T12:22:43.277+02:00</updated><title type='text'>3d Modelling thoughts.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TDhJ5UquXTI/AAAAAAAAANM/lXhBUKWtZkI/s1600/shot_82.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 251px;" src="http://2.bp.blogspot.com/_xl45__0O0dM/TDhJ5UquXTI/AAAAAAAAANM/lXhBUKWtZkI/s320/shot_82.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5492220994727599410" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:100%;"&gt;The objective of Qoob is to be a demoscene modeller that targets 64k intros. It should allow hundreds of models in a 64k. That means man made and organic. Organic seems to require arbitrary extrusion (think pipe or ribbon). It allows for models like loonies use in their 4ks eg &lt;a href="http://pouet.net/prod.php?which=25850"&gt;benetoite&lt;/a&gt; and, more impressively, 64ks such as &lt;a href="http://pouet.net/prod.php?which=18340"&gt;Flight666&lt;/a&gt;. The maths for modelling with arbitrary extrusions is quite large (&gt;500 bytes) and adds a lot of bytes to Qoob which is already growing in size.&lt;br /&gt;&lt;br /&gt;In addition, Qoob must support selecting individual polygons for arbitrary complex shapes. That will be the key to true modelling. But selecting, say 50 polygons currently requires:&lt;br /&gt;select p1&lt;br /&gt;select p2&lt;br /&gt;select p3&lt;br /&gt;... 50 selections&lt;br /&gt;to be stored and compressed. Compressing the command is obvious and cool. I'll just store the command queue and the data queue seperately. The data for each entry is four bytes and may not compress well. I could try sorting and delta encoding - the usual tricks - of course. This worries me.&lt;br /&gt;&lt;br /&gt;Size wise then, I'm struggling now: selections and extrusions add lots of bytes. ONe to the lib and one to the models. &lt;span style="font-weight:bold;"&gt;Suggestions are welcome.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;However, on the bright side, Qoob &lt;span style="font-weight:bold;"&gt;could&lt;/span&gt; support displacements on large and small scale, like sculpting. I might therefore be able to create highly detailed geometry with bumps and ridges, for very little cost. &lt;br /&gt;&lt;br /&gt;In the mean time, some screenies of what can be done without such functions:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TDgqhSeLP1I/AAAAAAAAAM0/kLn_1FbFuDI/s1600/shot_79.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 252px;" src="http://3.bp.blogspot.com/_xl45__0O0dM/TDgqhSeLP1I/AAAAAAAAAM0/kLn_1FbFuDI/s320/shot_79.jpg" alt="" id="BLOGGER_PHOTO_ID_5492186496960773970" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/TDgq2b6okxI/AAAAAAAAAM8/6k7ki5X4Cew/s1600/shot_80.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 290px;" src="http://4.bp.blogspot.com/_xl45__0O0dM/TDgq2b6okxI/AAAAAAAAAM8/6k7ki5X4Cew/s320/shot_80.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5492186860273308434" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/TDgrHKDJ36I/AAAAAAAAANE/lF6__Ce1tRk/s1600/shot_81.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 253px;" src="http://4.bp.blogspot.com/_xl45__0O0dM/TDgrHKDJ36I/AAAAAAAAANE/lF6__Ce1tRk/s320/shot_81.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5492187147534983074" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;p.s. Hope people like the new design for the pages here. Also check out the demotivation demoscene picture to the right (with apologies to iq/mentor) as &lt;a href="http://pouet.net/prod.php?which=52938"&gt;elevated&lt;/a&gt; races toward 500 thumbs on Pouet. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-5909934832331773261?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5909934832331773261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5909934832331773261'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/07/3d-modelling-thoughts.html' title='3d Modelling thoughts.'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/TDhJ5UquXTI/AAAAAAAAANM/lXhBUKWtZkI/s72-c/shot_82.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7508949063460377915</id><published>2010-07-06T11:32:00.008+02:00</published><updated>2010-07-07T18:33:07.335+02:00</updated><title type='text'>Catmull Clark Subdivision Musings</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TDL6e9hn-OI/AAAAAAAAAMM/mjiT6LqEr5I/s1600/125539461.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 251px;" src="http://3.bp.blogspot.com/_xl45__0O0dM/TDL6e9hn-OI/AAAAAAAAAMM/mjiT6LqEr5I/s320/125539461.jpg" alt="" id="BLOGGER_PHOTO_ID_5490726305536669922" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Before you read on. Blogger is simply crap for posting code. I've done my best for formatting but if you see dodgy symbols or things that make no sense - blame blogger as this code is right out of the compiler.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Modellers seems to like quads. Catmull Clark subdivision smooths and maintains a quads only model. Doo-sabin introduces triangles. Loop works on triangles. So I decided to use Catmull clark in qoob. I got it working last night after spending a whole weekend when I should have been in the sun. The model above, I estimate, would be around 22 bytes to store compressed. Its approaching organic but is still embarressingly geometrical. Thats has to be the next goal, to produce some organic stuff.&lt;br /&gt;&lt;br /&gt;Most code on the net works using winged edge data structures. Classes abound. The examples are no use for size coders. Fortunately iq tackled CCSD in his 2007 presentation for breakpoint, &lt;a href="http://www.iquilezles.org/www/material/breakpoint2007/bp2007.pdf"&gt;Tricks and techniques for RGBAs Past and Future Intros&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;(By the way his normal a mesh trick in that presentation is without doubt the best piece of size coding I've seen.&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;Firstly &lt;a href="http://en.wikipedia.org/wiki/Catmull%E2%80%93Clark_subdivision_surface"&gt;wikipedia has a description of the algorithm. &lt;/a&gt;Unfortunately, its not totally clear what an edge point is -the midpoint of an edge or the new displaced midpoint of the edge (its the first). But there are other references to clear this up.  IQ proved its possible to do Catmull clark without winged edges but still he uses edge ids. I wanted to avoid this and did so but in doing so, each time I add a vertex I loop through all vertices to see if an identical one already exists. I think its a case of what I gain on the flat I lose on the hill.  Here is the final code in old style C (ie no C++ operators for maths) which makes it look horrendous - thats why operators were introduced :-).&lt;br /&gt;&lt;br /&gt;addVert is key. It checks all existing vertices for an exact duplicate (exact is fine in this case) and returns either the index to the existing one or adds the new vertex and returns its index. addquad adds a quad to the model. The last line deletes old quadsr. The routine supports subdivision without displacement and CCSD, hence the if(smooth) in places.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Vert disp[MAXSIZE]; // displacements&lt;br /&gt;uint val[MAXSIZE];  // valences&lt;br /&gt;&lt;br /&gt;void subdObj (Object *ob, uint smooth) {&lt;br /&gt;Vert tmp,ep,fp;&lt;br /&gt;uint eid[4],cni; //indices for new vertices, edges and centre&lt;br /&gt;uint onq = ob-&amp;gt;nq;&lt;br /&gt;uint onv = ob-&amp;gt;nv;&lt;br /&gt;&lt;br /&gt;ZeroMemory(disp,MAXSIZE*sizeof(Vert));&lt;br /&gt;ZeroMemory(val,MAXSIZE*sizeof(uint));&lt;br /&gt;for (uint iq=0; iq &amp;lt; onq; iq++  ) {&lt;br /&gt;          centroid (ob, iq, &amp;amp;fp);                        &lt;br /&gt;          cni=addVert(ob,&amp;amp;fp);                       &lt;br /&gt;          for (uint v=0; v&amp;lt;4; v++  ) { // for each vertex in each quad quad&lt;br /&gt;              lerp(&amp;amp;(QV(ob,iq,v)), &amp;amp;(QV(ob,iq,(v 1)&amp;amp;3)), 0.5f, &amp;amp;ep);                                 &lt;br /&gt;              copy(&amp;amp;ep,&amp;amp;tmp);                                  &lt;br /&gt;              if (smooth) smul(&amp;amp;tmp,0.5f);                                 &lt;br /&gt;              eid[v]=addVert(ob,&amp;amp;tmp);   // orignal vertices of edge/4.0                                 &lt;br /&gt;              // add contrib of face points to displacement for new edge points                                 &lt;br /&gt;              smadd (&amp;amp;fp,0.25f, &amp;amp;(disp[eid[v]]), &amp;amp;(disp[eid[v]]) ); // add fp/4 to edge vector                                 &lt;br /&gt;              // add face points to displacement for original point&lt;br /&gt;             add (&amp;amp;fp, &amp;amp;(disp[ob-&amp;gt;q[iq][v]]),&amp;amp;(disp[ob-&amp;gt;q[iq][v]]) );&lt;br /&gt;             // add 2x edge points to disp for original points&lt;br /&gt;             smadd (&amp;amp;ep, 2.0f, &amp;amp;(disp[ob-&amp;gt;q[iq][v]]),&amp;amp;(disp[ob-&amp;gt;q[iq][v]]) );&lt;br /&gt;             val[ob-&amp;gt;q[iq][v]]  ; // add up valences&lt;br /&gt;       }&lt;br /&gt;  // now construct four new quads&lt;br /&gt;for (uint k=0;k&amp;lt;4;k++  ) addQuad (ob, ob-&amp;gt;q[iq][k], eid[k], cni, eid[(k-1)&amp;amp;3], selected(iq));&lt;br /&gt;}&lt;br /&gt;// now displace all vertices...face points will be unaffected&lt;br /&gt;if (smooth) for (uint v=0; v &amp;lt;q-&amp;gt;nv; v++  ) {&lt;br /&gt;  if (v &amp;lt; onv) { // this must be an original point     &lt;br /&gt;     smul (&amp;amp;(disp[v]), 1.0f/val[v]);     // average the displacement values     &lt;br /&gt;     smadd  (&amp;amp;(ob-&amp;gt;v[v]), val[v]-3.0f, &amp;amp;(disp[v]), &amp;amp;(ob-&amp;gt;v[v]) ); // correct for extraordinary vertex&lt;br /&gt;     smul (&amp;amp;(ob-&amp;gt;v[v]), 1.0f/val[v]);     // divide through by valence&lt;br /&gt;  } else add (&amp;amp;(ob-&amp;gt;v[v]), &amp;amp;(disp[v]), &amp;amp;(ob-&amp;gt;v[v]));&lt;br /&gt;}&lt;br /&gt;for (uint iq=0; iq&amp;lt;onq; iq++  ) delQuad(ob,0);&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Well depending how you count lines of code its 20-25. addVert and addQuad make it 25-30. So lets call it 30 lines of code Catmull Clark in C. C++ operators would make this a bit shorter. IQ claims 50 lines of code but if counted in the same way, his code is about the same 30-35.&lt;br /&gt;&lt;br /&gt;The way the code works is a two pass algorithm first over quads of the original model and secondly over the vertices of the new model. The first pass subdivides and accumulates displacement in a seperate vector. This enables the first pass to calculate all the valences and store them before averaging the final displacement and applying it in the correct manner depending on the type of point (original, edge or face). There are a couple of gotchas but thats the basic idea. No winged edge, infact no edges at all.&lt;br /&gt;&lt;br /&gt;Coding style sucks. Happy with result so thought I'd publish it.&lt;br /&gt;&lt;br /&gt;One cool thing is the model pictures is about 22 bytes to store. A champfered cube is about 12 bytes and a sphere similar. It means we are looking at qoob providing a library of demo type objects in a few hundred bytes. The spheres are made of quads and do not suffer from peaks at top and bottom. Ther qoob library is a few kilo unfortunately. DX would help but I think I'll target 64k so not to worry.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7508949063460377915?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7508949063460377915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7508949063460377915'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/07/catmull-clark-subdivision-musings.html' title='Catmull Clark Subdivision Musings'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_xl45__0O0dM/TDL6e9hn-OI/AAAAAAAAAMM/mjiT6LqEr5I/s72-c/125539461.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-5260817662233205635</id><published>2010-07-01T01:42:00.003+02:00</published><updated>2010-07-01T01:46:12.456+02:00</updated><title type='text'>Qoob Progressing</title><content type='html'>My modeller is progressing. Heres a screen shot:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TCvWqusTbWI/AAAAAAAAAME/boNqBRklOsY/s1600/shot_76.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 252px;" src="http://3.bp.blogspot.com/_xl45__0O0dM/TCvWqusTbWI/AAAAAAAAAME/boNqBRklOsY/s320/shot_76.jpg" alt="" id="BLOGGER_PHOTO_ID_5488716600457784674" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The model in the picture takes about 30 bytes to store. Smoothing is next up.&lt;br /&gt;Organic stuff is escaping me right now but I'll work on that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-5260817662233205635?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5260817662233205635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5260817662233205635'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/07/qoob-progressing.html' title='Qoob Progressing'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_xl45__0O0dM/TCvWqusTbWI/AAAAAAAAAME/boNqBRklOsY/s72-c/shot_76.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-3531389691462020861</id><published>2010-06-30T00:00:00.009+02:00</published><updated>2010-06-30T13:25:23.975+02:00</updated><title type='text'>stupid idea 247: worlds smallest vector maths library</title><content type='html'>Here is a tiny 3d vector maths library:&lt;br /&gt;&lt;pre&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;span style="font-family:courier new;"&gt;typedef float vec3[3];&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;br /&gt;vec3 *vec(vec3 *v, float x) {v[0]=v[1]=v[2]=x;return v;}&lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;br /&gt;float *mav(vec3 *v1,vec3 *v2,vec3 *v3,vec3 *v4,vec3 *v5){&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;span style="font-family:verdana;"&gt; for (int i=0; i!=3; i++) v3[i]=v1[i]*v4[i]+v2[i]*v5[i];&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;br /&gt; return v3[0]+v3[1]+v3[2];&lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;br /&gt;}&lt;/span&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;br /&gt;vec3 VZERO={0,0,0};&lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;  vec3 VONE={1,1,1};&lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt; vec3 VMONE={-1,-1,-1};&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;Thats it. It can do zero, set, add, sub, length2, dotprod, negate, lerp, centroid. e.g add is :&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;mav(&amp;amp;v1, &amp;amp;v2, &amp;amp;v3, &amp;amp;VONE, &amp;amp;VONE  ); // v3=v2+v1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Lerp means that centroid (the centre vertex of a quad) can be found without a division by using two lerps.&lt;span style="font-family:arial;"&gt; For a moment it seems cool until you realise the calls to it dont compress all that well.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The challenges remaining are xprod, normalise and max/min. then I have everything for handling my 3d modeller qoob.If I can make minor adjustments to get those, this might be worth persuing.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-3531389691462020861?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/3531389691462020861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/3531389691462020861'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/06/stupid-idea-247-worlds-smallest-vector.html' title='stupid idea 247: worlds smallest vector maths library'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-6860055269080972853</id><published>2010-06-16T18:03:00.001+02:00</published><updated>2010-06-16T18:04:56.867+02:00</updated><title type='text'>Very .cool</title><content type='html'>&lt;a href="http://www.ctrl-alt-test.fr/?page_id=7"&gt;GLSL Minifier.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;"GLSL Minifier is a tool to pack GLSL shader code. It generates a code as small as possible that is equivalent to the input code. The generated code is also designed to compress well. It has been optimized for use with Crinkler, but should perform well with any other compression tool. GLSL Minifier generates a C header file you can include from your code."&lt;br /&gt;&lt;br /&gt;Very .cool&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-6860055269080972853?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6860055269080972853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6860055269080972853'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/06/very-cool.html' title='Very .cool'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-8067853300998286362</id><published>2010-06-14T08:32:00.008+02:00</published><updated>2010-06-14T09:29:31.489+02:00</updated><title type='text'>3d modelling for Intros ? qoob.</title><content type='html'>I'm investigating meshes for a while. First attempts with Pohar from Rebels resulted in some pretty detailed modelling for 4k. It was the usual way. Create a mesh in a modelling tool, compress it, load it, smooth it, just the same as iqs approaches to the problem. As dx provides smoothing (loop I think), this results in tiny code and models of 500bytes or more as seed meshes. One of the problems with this technique is the model is equally "smooth" all over  at the end. Its hard to have smooth parts and rough parts. Iq overcomes this by coding displacements.&lt;br /&gt;&lt;br /&gt;This image fo a dragon was done using this technique and the result (with crinkler, shader, mesh and mesh code) was just over 2k...&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TBXV-VYNfcI/AAAAAAAAALk/05ezBsGoRXI/s1600/dragon.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 230px;" src="http://2.bp.blogspot.com/_xl45__0O0dM/TBXV-VYNfcI/AAAAAAAAALk/05ezBsGoRXI/s320/dragon.jpg" alt="" id="BLOGGER_PHOTO_ID_5482523388260744642" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/topic.php?which=4679&amp;amp;page=1&amp;amp;x=22&amp;amp;y=11"&gt;Theres a good read about meshes in intros at Pouet.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I once did a &lt;a href="http://www.pouet.net/prod.php?which=31632"&gt;1k with several curved "lathe" objects&lt;/a&gt;, but it was com dropping and thats unreliable. I haven't fixed that so no code on Pouet right now.  Maybe i'll try again with crinkler at some point. Lathes seem to be an option for modelling at 1k/4k.  In the code I developed for gcc the &lt;span style="font-weight: bold;"&gt;models were just 8 bytes&lt;/span&gt; each before compression. The code to create the objects was around 350 after compression and the objects are curved: there is non-linear interpolation between points in the model. Click on the image to see what I mean.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/TBXSuuQj-jI/AAAAAAAAALc/iQOBBX-IMA0/s1600/shot_72.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 170px;" src="http://1.bp.blogspot.com/_xl45__0O0dM/TBXSuuQj-jI/AAAAAAAAALc/iQOBBX-IMA0/s320/shot_72.jpg" alt="" id="BLOGGER_PHOTO_ID_5482519821526759986" border="0" /&gt;&lt;/a&gt;But Lathes are limited.&lt;br /&gt;&lt;br /&gt;Another technique I looked into was intersections of regular primitives. This can often produce surprising results. The idea is simply to rotate/translate a single primitive. The two screenshots below illustrate some results. The first is a rotated cone, resulting in a star. The second is a very small routine (180 bytes after compression) to generate organic like structures. Again no randomness, just rotate, translate, rotate stuff.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/TBXWumyf_cI/AAAAAAAAALs/Bla3OVZ7pd0/s1600/shot_3.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 262px;" src="http://1.bp.blogspot.com/_xl45__0O0dM/TBXWumyf_cI/AAAAAAAAALs/Bla3OVZ7pd0/s320/shot_3.jpg" alt="" id="BLOGGER_PHOTO_ID_5482524217568132546" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/TBXXKQeLMwI/AAAAAAAAAL0/2wFPWttILHs/s1600/organic3.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 274px;" src="http://4.bp.blogspot.com/_xl45__0O0dM/TBXXKQeLMwI/AAAAAAAAAL0/2wFPWttILHs/s320/organic3.jpg" alt="" id="BLOGGER_PHOTO_ID_5482524692613640962" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can see the last one live in the second half of the awesomely coloured :-) 4k intro &lt;a href="http://pouet.net/prod.php?which=33677"&gt;Fruit of the Loop.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But my goal is always to get away from embarressingly geometrical to something that looks modelled. It occurred to me that crinkler is very successful because it works at compile stage for compression, its not simply an exe packer. Thus my latest project is a modeller, the idea being to use the modelling commands to better compress the end model. qoob is a simple subdivision modeller based on wings3d functionality but very cut down. Its a fresh project but already I can see that no way will this be useful for 4k, only 64k. Thats disappointing but it comes from the fact that the library used to reproduce objects is 2-3k. An early screenshot is not impressive:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TBXZrKmWgRI/AAAAAAAAAL8/Z9Rcp-syfl0/s1600/shot_71.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 288px;" src="http://2.bp.blogspot.com/_xl45__0O0dM/TBXZrKmWgRI/AAAAAAAAAL8/Z9Rcp-syfl0/s320/shot_71.jpg" alt="" id="BLOGGER_PHOTO_ID_5482527456996262162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The idea remains right though: this is the modelling equivalent of a texture builder.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-8067853300998286362?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8067853300998286362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8067853300998286362'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2010/06/3d-modelling-for-intros-qoob.html' title='3d modelling for Intros ? qoob.'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/TBXV-VYNfcI/AAAAAAAAALk/05ezBsGoRXI/s72-c/dragon.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-3514913128466953682</id><published>2009-11-05T00:46:00.004+01:00</published><updated>2009-11-05T01:18:54.011+01:00</updated><title type='text'>FRequency To the Road of Ribbon in 1k for win32</title><content type='html'>Instead of producing my own stuff, I've spent time crunching down the original &lt;a href="http://www.pouet.net/prod.php?which=53939"&gt;Linux 1k from Frequency&lt;/a&gt;. Mainly I did it to see it on my ati card (the original was messed up) but also to see if I could get a win32 version, written in C, down to 1024 bytes.&lt;br /&gt;&lt;br /&gt;During the crunching it became obvious I'd have to make a few compromises:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The colour of the ribbon is the same as the walls. This is the biggest artistic compromise and definitely it can be criticised as compromising the original. To compensate I added a more dramatic camera path that gets very close to the ribbon.&lt;/li&gt;&lt;li&gt;Clock is less accurate and resets, causing a jump to a new viewpoint. This is not as good as the original.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;View angle is smaller - caused by a new method of calculating view vectors. Not a big issue.&lt;/li&gt;&lt;/ul&gt;Thats really it. On the plus side, I've cured a bug that caused the ribbon to be reflected many times and I made the new version run a bit faster enabling a higher resolution. I've completely rewritten the code that generates the olour but I've stayed as close to the original as I could. I hope its not noticeable too much. However, mine is darker, perhaps I can cure this later.&lt;br /&gt;&lt;br /&gt;This is a fantastic intro and not one I thought could be done in 1k in win32 in C when I started. Linux 1ks have smaller frameworks and so have more space available for the intro; and asm is of course more space efficient than C.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;a style="font-weight: bold;" href="http://scener.neostrada.pl/demos/FreqRtoRibbon1kwin32.zip"&gt;Here is the source code and an exe to try out&lt;/a&gt;&lt;/span&gt;. I hope you agree it has kept the essence of the original whilst being 1k in win32. I used crinkler 1.1 (even though 1.2 would produce smaller code) as 1.2 doesn't work for me. So the intro wont work under win7!!&lt;br /&gt;&lt;br /&gt;Respect to FRequency from auld^titan.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-3514913128466953682?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/3514913128466953682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/3514913128466953682'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2009/11/frequency-road-to-ribbon-in-1k-for.html' title='FRequency To the Road of Ribbon in 1k for win32'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-4352389850049993602</id><published>2009-11-01T09:56:00.005+01:00</published><updated>2009-11-01T16:28:10.084+01:00</updated><title type='text'>Frequencies To The Road of Ribbon Reactivated</title><content type='html'>Frequency did a really great Linux 1k recently. &lt;a href="http://www.pouet.net/prod.php?which=53939"&gt;To the Road of the Ribbon&lt;/a&gt; is a classic labyrinth but (to my knowledge) for the first time with reflections and even a ribbon added. It fits in Linux at 1k nicely but is about 1240 bytes under windows, though xt95 made no attempt to make it smaller under windows, it was small enough under Linux. For some reason it was buggy on my ATi box so out of interest I converted the Linux assembler to  C and ported to windows.&lt;br /&gt;&lt;br /&gt;I couldn't quite get the code down to 1k using crinkler under windows (setup for windows is larger). Perhaps some jolly fellow can convert it back to asm? &lt;a href="http://scener.neostrada.pl/Main.cpp"&gt;You can get my C version here&lt;/a&gt;, with a much compressed shader. Its around 1070 bytes using crinkler.&lt;br /&gt;&lt;br /&gt;There are some nice tricks in this intro. I like the hi-res clock passed in through glColor4ubv:&lt;br /&gt;&lt;br /&gt;t=timeGetTime();&lt;br /&gt;glColor4ubv((unsigned char *)(&amp;t));&lt;br /&gt;&lt;br /&gt;and then in the shader (my version):&lt;br /&gt;&lt;br /&gt;float w=dot(vec3(gl_Color),vec3(256/256,256,256*256))*.256;&lt;br /&gt;&lt;br /&gt;The dot product was a great idea to get a hi-res clock, not sure if its original to Frequency but its very cool. I optimised the size a little by making the original vec3(1,256,65536) into the form above.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-4352389850049993602?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4352389850049993602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4352389850049993602'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2009/11/frequencies-to-road-of-riboon.html' title='Frequencies To The Road of Ribbon Reactivated'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2005305635947225556</id><published>2009-10-21T22:53:00.003+02:00</published><updated>2009-10-21T22:56:14.437+02:00</updated><title type='text'>Bad intro year</title><content type='html'>I started this year trying to code a full blown demo which is a long term work in progress now. In the mean time work took over and coding hasn't been possible. The hiatus has given me two very clear ideas for intros. I'll see if they come out as 4ks or something bigger later.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2005305635947225556?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2005305635947225556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2005305635947225556'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2009/10/bad-intro-year.html' title='Bad intro year'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-6948260734085820286</id><published>2009-01-20T23:37:00.006+01:00</published><updated>2009-01-20T23:51:51.673+01:00</updated><title type='text'>GLSL Shader Creation: Geometry, Vertex and Fragment</title><content type='html'>To the point, I recently expanded my tiny shader creation framework to include geometry shaders. Not much to say about it. Notice that Geometry and Vertex shaders are optional. The code is getting quite long so it might be worth testing if loading the function pointers in a loop and indexing them would be smaller, nontheless its highly repetitive so crinkler should cope well.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;GLuint ShaderCompile(const char *gs, const char *vs, const char *fs) {&lt;br /&gt;GLuint p,s;&lt;br /&gt;  p = ((PFNGLCREATEPROGRAMPROC)(wglGetProcAddress("glCreateProgram")))();&lt;br /&gt;  if (gs!=NULL) {  &lt;br /&gt;    //if there is a geom shader...&lt;br /&gt;    s=((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_GEOMETRY_SHADER_EXT);&lt;br /&gt;    ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &amp;gs, NULL);&lt;br /&gt;    ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);&lt;br /&gt;    ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);&lt;br /&gt;  }&lt;br /&gt;  if (vs!=NULL) {  &lt;br /&gt;    //if there is a vertex shader...&lt;br /&gt;    s=((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_VERTEX_SHADER);&lt;br /&gt;   ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &amp;vs, NULL);&lt;br /&gt;   ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);&lt;br /&gt;   ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);&lt;br /&gt;  }&lt;br /&gt;  s=((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_FRAGMENT_SHADER); &lt;br /&gt;  ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &amp;fs, NULL);&lt;br /&gt;  ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);&lt;br /&gt;  ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);&lt;br /&gt;  ((PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"))(p);&lt;br /&gt;  return p;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(I'll return to DirectX and OpenGL next post.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-6948260734085820286?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6948260734085820286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6948260734085820286'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2009/01/glsl-shader-creation-geometry-vertex.html' title='GLSL Shader Creation: Geometry, Vertex and Fragment'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-181211758659387876</id><published>2009-01-12T12:47:00.009+01:00</published><updated>2009-01-13T18:28:02.971+01:00</updated><title type='text'>How to Use D3Dx and OpenGL together : Part 1</title><content type='html'>I love OGL but the OGL SDK is a shoddy collection of web links. Worse, although as size coders we have GLU, DX coders have a lot of advantages in the standard libraries they have access to. Fortunately, DirectX is quite well designed in the way libraries are broken down and from OGL its possible to use the d3dx support library without rendering using D3d. Its a little overhead of course compared to rendering everything in d3d, but in terms of bytes at 4k its almost nothing.&lt;br /&gt;&lt;br /&gt;Inside d3dx are cool routines for getting normals to a mesh, smoothing meshes, raytracing (!) which can be used for collisions, splines for motion and camera paths, the elusive cube and torus, neither of which for some inexplicable reason appear in GLU, and a whole range of maths functions. In this little blog I'll show code to set up OGL and d3d together. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;LPDIRECT3D9       pD3D;&lt;br /&gt;LPDIRECT3DDEVICE9     pd3dDevice;&lt;br /&gt;&lt;br /&gt;void initD3D(HWND hWnd) &lt;br /&gt;{&lt;br /&gt;D3DPRESENT_PARAMETERS d3dpp;&lt;br /&gt;&lt;br /&gt;    pD3D = Direct3DCreate9 (D3D_SDK_VERSION);&lt;br /&gt;    d3dpp.Windowed = TRUE;&lt;br /&gt;    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;&lt;br /&gt;    pD3D-&gt;CreateDevice( 0, D3DDEVTYPE_HAL, hWnd,&lt;br /&gt;                D3DCREATE_SOFTWARE_VERTEXPROCESSING, &amp;d3dpp, &amp;pd3dDevice );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The code above sets up D3D. To be precise, it initialises D3D enough so that we can use functions from d3dx. To be more precise, DirectX 9 functions. It may be possible to get smaller but I'm a beginner with d3d, so send me an email if you can beat it. As both pD3D and pd3dDevice are required by d3dx routines, we make them global. It may be possible to use a static declaration for d3dpp to make this smaller byt a few bytes.&lt;br /&gt;&lt;br /&gt;Now we need some code to initialise windows and opengl and use this routine to initialise D3D:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;static PIXELFORMATDESCRIPTOR pfd={&lt;br /&gt;0, // Size Of PFD... BAD coding, saves bytes&lt;br /&gt;1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 0, 0, 0, 0, 0, 0, &lt;br /&gt;0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0 &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void WINAPI WinMainCRTStartup()&lt;br /&gt;{&lt;br /&gt;    HWND hWnd = CreateWindow( "EDIT", NULL, WS_POPUP|WS_VISIBLE|WS_MAXIMIZE, &lt;br /&gt;                          0, 0, 0, 0, 0, 0, 0, 0 );&lt;br /&gt;    initD3D(hWnd);&lt;br /&gt;    HDC hDC = GetDC( hWnd );&lt;br /&gt;    SetPixelFormat ( hDC, ChoosePixelFormat ( hDC, &amp;pfd) , &amp;pfd );&lt;br /&gt;    wglMakeCurrent ( hDC, wglCreateContext (hDC) );&lt;br /&gt;    ShowCursor(FALSE);&lt;br /&gt;    .&lt;br /&gt;    .&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The code above is a little larger than normal because the d3d initialisation requires the window handle as well as the GetDC call, so we have to store it in hWnd variable.&lt;br /&gt;&lt;br /&gt;In this blog then, I've presented a tiny framework that initialises win32, opens a window, initialises d3d and initialises opengl.  In the next Blog, I'll describe how to use mesh functions in d3dx and render using OpenGL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-181211758659387876?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/181211758659387876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/181211758659387876'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2009/01/how-to-use-d3dx-and-opengl-together.html' title='How to Use D3Dx and OpenGL together : Part 1'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7548578184182966061</id><published>2009-01-01T19:48:00.001+01:00</published><updated>2009-01-13T17:36:33.255+01:00</updated><title type='text'>Place to live</title><content type='html'>Joined Titan. Good to have a home :-). Titan gets a lot of bad press. So much so I once decided to leave but luckily they are a forgiving bunch and let me back in. However, inside Titan there are fabulously talented people and its hard to see why Titan hasn't been more successful to this time. Anyway, thanks for letting me back in, I'm already enjoying myself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7548578184182966061?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7548578184182966061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7548578184182966061'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2009/01/place-to-live.html' title='Place to live'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-5490363555763083497</id><published>2008-12-29T11:30:00.003+01:00</published><updated>2008-12-29T11:32:18.763+01:00</updated><title type='text'>Very small Code for Cornell Box</title><content type='html'>I don't often just add links here (first time) but here is one worth seeing for size coders. Its a &lt;a href="http://kevinbeason.com/smallpt/"&gt;complete global illumination solution in 99 lines of C++ code&lt;/a&gt;. I notice the exe can be less than 4k.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-5490363555763083497?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5490363555763083497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5490363555763083497'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/12/very-small-code-for-cornell-box.html' title='Very small Code for Cornell Box'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-1328122579503277528</id><published>2008-12-22T22:50:00.006+01:00</published><updated>2008-12-23T09:34:46.081+01:00</updated><title type='text'>Code for Moving Camera in GLSL Raytracer</title><content type='html'>Suppose you have a "two triangles and a shader" program as iq likes to call them. Essentially, you cover the screen with a polygon and then draw everything with a shader. This might be raytracing, for example. The problem is this: how to move the camera around in very few bytes. Better, how to write a very small shader that lets us use OpenGL commands like gluLookAt and glRotate to control the camera?&lt;br /&gt;&lt;br /&gt;A good solution hit me today so here is the code. First the main opengl loop to draw that polygon contains:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;glRects(-1,-1,1,1);&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;This is one good advantage for size coding of OGL over D3D. A single polygon covers the screen. We cant use texture coords or colours at the vertices or we would have to define a quad or two triangles. So we are stuck with just the vertices.&lt;br /&gt;&lt;br /&gt;Now the magical, tiny, Vertex shader which will give us a moving camera:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;varying vec3 v,EP;&lt;br /&gt;void main(){&lt;br /&gt;  gl_Position=gl_Vertex;&lt;br /&gt;  v = vec3( gl_ModelViewMatrix*gl_Vertex);&lt;br /&gt;  EP= vec3( gl_ModelViewMatrix*vec4(0,0,-1,1) );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The first line, makes sure that the glRect still covers the screen in the Pixel shader. It does not transform it but leaves it where it is. The second line, however records the transformed vertex in world space as a vec3. This in effect will record the position in world space for every pixel on the screen.&lt;br /&gt;&lt;br /&gt;The last line is recording the eye position. Arbitrarily, the eye position is hardcoded here to be one unit in Z away from the screen giving a filed of view of 90 degrees - quite normal for a camera. Note that eye point needs a homogeneous value of 1 as the fourth co-ordinate to work properly.&lt;br /&gt;&lt;br /&gt;We could have used vec4 for both lines above and the code would be shorter, but as most raytracing will use vec3 later, yuo can chose to bite the bullet and make the code longer here and shorter in the fragment shader. Horses for courses.&lt;br /&gt;&lt;br /&gt;Now in the fragment shader its easy to construct the ray to start tracing:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;varying vec3 v,EP;&lt;br /&gt;void main(){&lt;br /&gt;vec3 Ro=EP;     //set ray origin&lt;br /&gt;vec3 Rd=v-Ro;   //set ray direction&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Its that easy. Now you can move the camera in your raytracer using normal OpenGL commands. To finish here is an image from YAST (yet another sphere tracer as I'm calling my glsl raytracer). I'm able to move around the spheres as I chose. As usual, click on the image to see a bigger version.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/SVASGpXq0LI/AAAAAAAAALU/bObbsn3fJGM/s1600-h/shot_43.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_xl45__0O0dM/SVASGpXq0LI/AAAAAAAAALU/bObbsn3fJGM/s320/shot_43.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5282742268299235506" /&gt;&lt;/a&gt;&lt;br /&gt;Out of interest, on an x1950, 1024x768, 30 spheres, one light, shadows and 3 levels of reflection, I'm getting around 50fps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-1328122579503277528?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1328122579503277528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1328122579503277528'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/12/code-for-moving-camera-in-glsl.html' title='Code for Moving Camera in GLSL Raytracer'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_xl45__0O0dM/SVASGpXq0LI/AAAAAAAAALU/bObbsn3fJGM/s72-c/shot_43.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7658768965347495373</id><published>2008-12-21T11:20:00.005+01:00</published><updated>2008-12-21T11:53:22.851+01:00</updated><title type='text'>Getting OpenGL shaders even smaller</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/SU4fSZOUGsI/AAAAAAAAALM/wsQRTuh7Tww/s1600-h/30589.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 150px;" src="http://2.bp.blogspot.com/_xl45__0O0dM/SU4fSZOUGsI/AAAAAAAAALM/wsQRTuh7Tww/s200/30589.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5282193813821201090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=30589"&gt;Flow2&lt;/a&gt; is a 1k of mine from over 12 months ago. It was 1022 bytes. Since then, several things changed. Firstly, ATi fixed their drivers for *some* cards so that you no longer need a vertex shader/fragment shader pair. As per the glsl spec only a fragment shader is necessary. Fearmoths exploited this in their Linux 1k &lt;a href="http://www.pouet.net/prod.php?which=51762"&gt;You Massive Clod&lt;/a&gt;. Secondly, last January &lt;a href="http://www.pouet.net/prod.php?which=18158"&gt;Crinkler 1.1a&lt;/a&gt; was released which compressed better (20 or so bytes). Thirdly, I got better at size reducing C code for crinkler.&lt;br /&gt;&lt;br /&gt;So, it was time to revisit an old intro and try to size reduce it. As it happens flow2 didnt have a proper timer so I decided to add one, taking the intro way up over 1024 bytes. Nontheless the current exe is ... wait for it... &lt;span style="font-weight:bold;"&gt;890 bytes!!&lt;/span&gt;&lt;br /&gt;Thats extra timer code and still 130 bytes smaller. OK, some code. Flow2 is a "one polygon and a shader" style of intro. The point is now you don't need a vertex shader, just a pixel shader, the tiny glsl code can be even smaller:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void setShaders() {&lt;br /&gt;GLuint p,s;&lt;br /&gt;   s = ((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_FRAGMENT_SHADER); &lt;br /&gt;   ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &amp;fsh, NULL);&lt;br /&gt;   ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);&lt;br /&gt;   p = ((PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"))();&lt;br /&gt;   ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader"))(p,s);&lt;br /&gt;   ((PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"))(p);&lt;br /&gt;   ((PFNGLUSEPROGRAMPROC) wglGetProcAddress("glUseProgram"))(p);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now the big question...can you fit a synth and music in 130 bytes? Midi for sure but a real synth? The wav header alone is around 43 bytes after compression, add in PlaySoundA and already half the bytes are gone. It seems unlikely but ... well...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7658768965347495373?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7658768965347495373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7658768965347495373'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/12/getting-opengl-shaders-even-smaller.html' title='Getting OpenGL shaders even smaller'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/SU4fSZOUGsI/AAAAAAAAALM/wsQRTuh7Tww/s72-c/30589.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-978191750944971855</id><published>2008-12-10T13:04:00.006+01:00</published><updated>2008-12-23T23:50:48.271+01:00</updated><title type='text'>Tiny code for Using Multicore CPU Multithreading</title><content type='html'>Its easier than most people think to use multicores, even with very small code.&lt;br /&gt;The trick is to realise that a CPU, when given more than one thread, will try to run those threads on different cores where possible. I used multithreading (and hence multicore) in a 1k once. I wanted the music in a different thread because I had no space for a real timer for the music. So, the music was written as a function that played the next note. The function was called from the main loop. Timing issues connected to drawing the graphics meant the note was played slightly off beat at times and it was very disconcerting.&lt;br /&gt;&lt;br /&gt;So instead I changed the music routine to be:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Loop:&lt;br /&gt; Issue notes&lt;br /&gt; Sleep for some time&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then I set it up in another thread before, entering the main loop, using:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SetThreadPriority(_beginthread( &amp;addTune,0,0), THREAD_PRIORITY_TIME_CRITICAL);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(Watch out this was done using GCC - VC++ may need other, more precise, syntax)&lt;br /&gt;beginthread kicks off a new thread with the function addTune as the first function called in that thread when it starts. SetThreadPriority ensures that even on a single core the music thread will have higher priority than the main graphics thread and the music will not suffer tiny stalls. The ear is more sensitive to this than the eye to the occassional graphics frame dropped.&lt;br /&gt;&lt;br /&gt;You need to include process.h for the thread calls above.&lt;br /&gt;&lt;br /&gt;On multiple cores this would now be configured by the O/S to be two threads running on two cores.&lt;br /&gt;&lt;br /&gt;What about synch? In the 1k I synched the music to the graphics. This means communicating between the two threads (and cores). Again this is deceptively simple. &lt;br /&gt;A variable is declared and the music thread assigns it each time is plays a new note. The drawing thread uses the variable (read only) to decide how to move the graphics just as normal. Globals can be used to communicate between threads and even to synchronise them.&lt;br /&gt;&lt;br /&gt;Threads and cores can be very tricky beasts in true parallel programming (I used to work at Edinburgh Parallel Computing Centre on the supercomputers there) but they can also be used in even a 1k intro!&lt;br /&gt;&lt;br /&gt;Addendum, to avoid linking with MSVCRT and use win32 functions instead, its possible to use syntax like this in VC++:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SetThreadPriority((HANDLE)CreateThread( NULL, 0, &lt;br /&gt;  (LPTHREAD_START_ROUTINE)&amp;addTune,0,0,0), THREAD_PRIORITY_TIME_CRITICAL); &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-978191750944971855?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/978191750944971855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/978191750944971855'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/12/multicore-and-multithread-for-intros.html' title='Tiny code for Using Multicore CPU Multithreading'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2882910862476599292</id><published>2008-11-03T23:01:00.003+01:00</published><updated>2008-11-03T23:28:14.531+01:00</updated><title type='text'>Intersecting a ray with spheres: GLSL</title><content type='html'>To the point, here is a dump of some very small code to intersect a ray with N spheres. I used it for my wada rendering so its hardwired to four spheres. It is a function so can be dropped into anyones code. Its dumb and just does a linear search over the spheres. However, you can get reasonable speeds up to 20 spheres or so depending on your card. It is of course ps3.0.&lt;br /&gt;&lt;br /&gt;p: the point of origin of the ray. &lt;br /&gt;rd: ray direction.&lt;br /&gt;si: OUTPUT, the closest sphere hit.&lt;br /&gt;t is returned, the distance to the closest intersection point.&lt;br /&gt;&lt;br /&gt;Assumption: spheres are passed in as vec4s into a uniform, in the normal GLSL manner. Each vec4 is (x,y,z,r2): centre and radius squared.&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;uniform vec4 sph[4];  // in this case 4 spheres&lt;br /&gt;&lt;br /&gt;float isect (in vec3 p, in vec3 rd, out vec4 si){&lt;br /&gt;float t=999.9,tnow,b,disc;&lt;br /&gt;  for (int i=0; i&lt;4; i++) {  //each sphere&lt;br /&gt;    tnow = 9999.9;           //temporary closest hit is far away&lt;br /&gt;    //next 4 lines are the intersect routine for a sphere&lt;br /&gt;    vec3 sd=sph[i].xyz-p;    &lt;br /&gt;    b = dot ( rd,sd );&lt;br /&gt;    disc = b*b + sph[i].w - dot ( sd,sd );&lt;br /&gt;    if (disc&gt;0.0) tnow = b - sqrt(disc);&lt;br /&gt;    // hit, so compare and store if this is the closest&lt;br /&gt;    if ((tnow&gt;0.0001)&amp;&amp;(t&gt;tnow)) {t=tnow; si=sph[i];}&lt;br /&gt;  }&lt;br /&gt;  return t;&lt;br /&gt;}&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;&lt;br /&gt;A couple of explanations:&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;disc = b*b + sph[i].w - dot ( sd,sd );&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;sph[i].w is already a radius squared so saves some code here. Also dot(sd,sd) is short for length(sd) - less bytes.&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;if ((tnow&gt;0.0001)&amp;&amp;(t&gt;tnow))...&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;tnow is the current intersection parameter, the distance along rd of the current intersection. If tnow is very small, we may be intersection with the sphere we are already on and must ignore it. 0.0001 is arbitrary.&lt;br /&gt;Of course to get the actual intersection you need to do this in the main routine:&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;if (t!=999.9) inter=p+t*rd;&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;or something similar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2882910862476599292?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2882910862476599292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2882910862476599292'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/11/intersecting-ray-with-spheres-glsl.html' title='Intersecting a ray with spheres: GLSL'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-8436487611318259001</id><published>2008-11-03T22:40:00.003+01:00</published><updated>2008-11-03T22:51:18.903+01:00</updated><title type='text'>Returning to IFS</title><content type='html'>A few years ago I posted on &lt;a href="http://in4k.untergrund.net/index.php?title=aulds_IFS"&gt;how to make IFS small&lt;/a&gt; over on in4k. Now fractals aren't that well received in the demoscene (a bit been there, done that). The fact is though they are amazing for graphics size coding. The following image was generated using only two (!!) transforms and some nice colour mapping. That would be about 150 bytes.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/SQ9w6x1vtmI/AAAAAAAAAIA/rgcKp4jchgQ/s1600-h/ifs-2transforms.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 133px;" src="http://4.bp.blogspot.com/_xl45__0O0dM/SQ9w6x1vtmI/AAAAAAAAAIA/rgcKp4jchgQ/s200/ifs-2transforms.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5264550644532885090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Click on the image to see it larger. &lt;br /&gt;&lt;br /&gt;Now with geometry shaders, an IFS could be run in the geometry pipeline to create complex 3d structures from simple primitives ...lets say, oh I don't know....cubes, in exactly the same way traditional IFS fractal flames are created using points in 2d.&lt;br /&gt;&lt;br /&gt;Anyone with geometry shading hardware care to try?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-8436487611318259001?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8436487611318259001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8436487611318259001'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/11/returning-to-ifs.html' title='Returning to IFS'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_xl45__0O0dM/SQ9w6x1vtmI/AAAAAAAAAIA/rgcKp4jchgQ/s72-c/ifs-2transforms.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7912898279495394718</id><published>2008-10-26T22:20:00.005+01:00</published><updated>2008-10-26T22:46:57.564+01:00</updated><title type='text'>Disappointing Last 4k</title><content type='html'>Last year I quit dbfinteractive forums, where previously I was very active. If you dont know it, I recommend it as a place to find interesting code snippets for beginners in the demoscene. I also did my last 1k. Largely, I felt I was going nowhere fast with my 1ks. The same is true of my 4ks now and Triangle Ted is my last 4k. TT was meant to be my first 100+ thumbs on Pouet, and my last 4k. Instead it turned out to be a backward step (in rating terms) but remains my last 4k. Disappointing but thats life.&lt;br /&gt;&lt;br /&gt;I hope that you've enjoyed some of my 4ks and maybe even been inspired to try yourself.&lt;br /&gt;&lt;br /&gt;I like the challenge of size coding so this blog will continue and when I produce anything useful it will go here. As a consequence of not competing in the scene I can be freer with code and what I do which is really what I need now. This means more code should be available on this blog than before. Hurrah!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7912898279495394718?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7912898279495394718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7912898279495394718'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/10/disappointing-last-4k.html' title='Disappointing Last 4k'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-948220674528472824</id><published>2008-10-19T22:02:00.002+02:00</published><updated>2008-10-19T22:14:57.318+02:00</updated><title type='text'>4k Procedural Graphics</title><content type='html'>A new category in size coding has been legitimised by the fantastic work of RGBAs iq: 4k procedural graphics. Unlike intros, procedural graphics draw a single image and stop. Usually the image takes from a few seconds to upwards of a minute to render. &lt;br /&gt;&lt;br /&gt;Here are some of the best examples to date:&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=50068"&gt;ixaleno&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=51074"&gt;rgba_slisesix&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=51285"&gt;godspeed&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=51278"&gt;photon race&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=50064"&gt;off the shelf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It occurs to me though that there is huge scope for innovation in this category. Here are some ideas:&lt;br /&gt;&lt;br /&gt;- Image plus music. An image is drawn and accompanying mood music plays.&lt;br /&gt;- Image plus movement. An image bigger than the screen could be drawn and scrolled or zoomed.&lt;br /&gt;- Slide show. Several images are rendered and displayed with some transition one afetr another.&lt;br /&gt;- Red-blue image. 3D images requiring red-blue glasses.&lt;br /&gt;- RDS Images (random dot stereograms)&lt;br /&gt;- Movies (perhaps this breaks the fundamentals of no animation)&lt;br /&gt;&lt;br /&gt;It seems there may be lots of ways to expand this category. 2009 promising to be equally as interesting as 2008 has been in the sizecoding area.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-948220674528472824?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/948220674528472824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/948220674528472824'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/10/4k-procedural-graphics.html' title='4k Procedural Graphics'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-461785328501104208</id><published>2008-10-18T09:33:00.009+02:00</published><updated>2008-10-19T18:00:37.640+02:00</updated><title type='text'>New 4k finished</title><content type='html'>Despite a very tough year for me, I've finally finished another 4k. This time the synth and music come from s!p and graphics and concept (yes, there is a concept!) from me. It was released tonight at TRSAC. Thanks go to Rbraz too for a piece of code he placed at dbfinteractive forum for all to use. As usual, click for larger versions.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/SPmSXGKS6eI/AAAAAAAAAHs/xSOCiS5t1SE/s1600-h/shot_32.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_xl45__0O0dM/SPmSXGKS6eI/AAAAAAAAAHs/xSOCiS5t1SE/s200/shot_32.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5258394965420206562" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/SPmSXnLEVOI/AAAAAAAAAH0/4-EdTZ4tfls/s1600-h/shot_26.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_xl45__0O0dM/SPmSXnLEVOI/AAAAAAAAAH0/4-EdTZ4tfls/s200/shot_26.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5258394974281815266" /&gt;&lt;/a&gt;&lt;br /&gt;The 4k is about my experience as an "oldskool" guy seeking work in a "newskool" environment. In a country where I don't speak the language too well. Requires PS3.0 card and quite a strong one (say x1800 or 7XXX class onwards). It runs under XP or Vista and also on Nvidia and ATi. &lt;br /&gt;&lt;br /&gt;Watch out for it on Pouet soon: Triangle Ted Seeks a Job. Once again, Youtube succeeds in murdering the quality (the uploaded version was quite good) but here is the video anyway. It should whet your apetite to &lt;a href="http://www.pouet.net/prod.php?which=51888"&gt;see the intro for real I hope&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="350"&gt; &lt;param name="movie" value="http://www.youtube.com/v/KXlbVq-dNV4"&gt; &lt;/param&gt; &lt;embed src="http://www.youtube.com/v/KXlbVq-dNV4" type="application/x-shockwave-flash" width="425" height="350"&gt; &lt;/embed&gt; &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-461785328501104208?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/461785328501104208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/461785328501104208'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/10/new-4k-finished.html' title='New 4k finished'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/SPmSXGKS6eI/AAAAAAAAAHs/xSOCiS5t1SE/s72-c/shot_32.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-6673689686080444302</id><published>2008-09-21T08:49:00.003+02:00</published><updated>2008-09-28T18:16:21.689+02:00</updated><title type='text'>Ati is dead in the Demoscene</title><content type='html'>There are a precious few groups (the best groups) who are able to write shaders for both Nvidia and ATi cards. Weaker coders just code until it works on their cards and release, not knowing they are writing bad code. The worst of these will then blame bad drivers for their poor coding but the truth is they probably didn't even read the specification.&lt;br /&gt;&lt;br /&gt;This situation was ok(ish) at the beginning of this year, before Nvidia demo boxes were sent out. However, now Nvidia dominates the demoscene (well done, it was great marketing by the way). Of the 4k teams out there, only TBC, RGBA and Fairlight are sure fire to work across many platforms. Notice how each group has a star programmer in there? ATi owners are left in the cold - few 4ks now running on their hardware.&lt;br /&gt;&lt;br /&gt;Whilst 2008 seems to have been a good year for the quality and variation in 4ks, there is a darker side too. PC 4ks have become dramatically less compatible. Precious few run on ATi cards, PS4.0 has been used but runs on very few cards out there and, the winning 4k at NVScene doesn't even run on the XP operating system. &lt;br /&gt;&lt;br /&gt;If you are new at this you probably don't know that being compatible costs bytes. It means your sound engine cannot use tracks available in one OS. It means shaders become slightly bigger, maybe even with multiple versions. It is not a level competition between the compatible and "works on one machine" 4ks. Not just this but producing compatible 4ks is harder - it requires more work. I spent a day recently debugging my shaders on Nvidia after size reducing them on ATi. Simply put, compatible 4ks should be given more credit. In a world where 100 bytes makes all the difference, exploiting OS specific advantages is a huge advantage.&lt;br /&gt;&lt;br /&gt;Non-compatible 4ks usually claim to work on the "compo" machine. After all they wouldn't be released otherwise. This is fine except the bigger parties are now providing very high end machines (full HD, quad core, &gt;2Gig of RAM, ps4.0 new graphics cards). Most people do not have access to this technology, creating an elite who do. Thank goodness for smaller parties with more modest machines for competition, yet even they this year got their hands on Nvidia demo boxes, temporarily (I hope) exaggerating the problem.&lt;br /&gt;&lt;br /&gt;How far will we go with the non-compatibility? I suspect we will go all the way. The competition system is set up to reward those who do produce something that works on one machine. Nothing else matters.&lt;br /&gt;&lt;br /&gt;What if it changed? What if competitions DID NOT announce the hardware or OS? Imagine a 4k intro competition with these rules:&lt;br /&gt;*...&lt;br /&gt;* OS will be XP or Vista&lt;br /&gt;* Card will be ATi or Nvidia but will support PS3.0&lt;br /&gt;* Organisers will run entries on compo machine and report results to competitors but no information about the compo machine will be released even at the party&lt;br /&gt;*...&lt;br /&gt;&lt;br /&gt;Isn't that the problem solved? If nobody knows the machine, it forces competitors to try to be compatible, not use too much CPU, be conservative on memory use. 4ks will run no a wider range of platforms and within one year we will all know how to write shaders properly.&lt;br /&gt;&lt;br /&gt;I saw once someone suggesting we have a standard competition machine. I think this is unworkable. How will, say Riverwash, be able to access the same tech as Breakpoint? Its unlikely. In addition it doesn't solve the real issue. It just means every 4k will run on that platform (much like the Nvidia demobox problem of 2008) and no other.&lt;br /&gt;&lt;br /&gt;Another possibility is to allow remote voting. Provide the entries live at the party for download. We at home can try them and vote. If they dont run we can give bad votes. The problem with this is (I suspect) it is open to abuse too much. It would be a brave party organiser who tried this.&lt;br /&gt;&lt;br /&gt;No, the real solution is to make the target platform anonymous. Though, wait! If the platform is anonymous, some people will fail to get their precious 4k working. This will reduce the number of entries shown at parties. The smaller parties in 2008 struggled anyway to compete with the bigger ones for number of entries. So there is a downside.&lt;br /&gt;&lt;br /&gt;Well, it seems the solution is simple then. Buy nvidia, upgrade to vista, replace that 2 year old PC with a new one and add lots of memory.&lt;br /&gt;&lt;br /&gt;I know a good bank manager...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-6673689686080444302?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6673689686080444302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6673689686080444302'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/09/ati-is-dead-in-demoscene.html' title='Ati is dead in the Demoscene'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-8885654751366610804</id><published>2008-09-13T08:34:00.003+02:00</published><updated>2008-09-13T08:58:07.670+02:00</updated><title type='text'>Glass tile distortion shader</title><content type='html'>Occassionally, I will post tiny shaders, useful for effects in 4k intros (eg kaleidoscope). I discovered recently how to do glass tiles as a post process overlay in very little code. Distortion shaders require you to render to copy to texture first. I have done other blogs about this. However I would guess most 4ks already do this for blur, AO, rgb distortion or whatever already, so the extra bytes of this shader are absolutely tiny.&lt;br /&gt;&lt;br /&gt;Here is the shader pair:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;varying vec4 v;&lt;br /&gt;void main(){ v = gl_Position = ftransform(); }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The vertex shader assumes something is drawn on the screen (a quad say) and covers the screen as a surface for the distortion shader. This means v will hold co-ordinates -1.0..1.0 &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;uniform sampler2D s;&lt;br /&gt;varying vec4 v;&lt;br /&gt;void main(){&lt;br /&gt;  vec2 x = v.xy/2.0 + 0.5;&lt;br /&gt;  gl_FragColor = texture2D( s, x + 0.1*tan(x*5.0) );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Firstly v is mapped to 0.0..1.0 range of normal texture co-ordinates. The glass tile effect is then simply that tan distortion! Here is an image of what it can produce - ignore the background, thats just something to be distorted.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/SMtibE1aXUI/AAAAAAAAAHk/_WucfD4vesg/s1600-h/shot_15.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_xl45__0O0dM/SMtibE1aXUI/AAAAAAAAAHk/_WucfD4vesg/s200/shot_15.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5245394408296832322" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you want to "waste" bytes, its a good idea to do something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  gl_FragColor = texture2D( s, x+min( 0.1*tan(x*5.0), 0.2 ) );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This helps to prevent "sparklies" in the distortion by keeping that tan under control.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-8885654751366610804?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8885654751366610804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8885654751366610804'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/09/glass-tile-distortion-shader.html' title='Glass tile distortion shader'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_xl45__0O0dM/SMtibE1aXUI/AAAAAAAAAHk/_WucfD4vesg/s72-c/shot_15.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7627530950163620619</id><published>2008-08-20T10:07:00.009+02:00</published><updated>2008-08-20T18:44:32.900+02:00</updated><title type='text'>Float casting in GLSL (today)</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Boring&lt;/span&gt; but may be helpful.&lt;br /&gt;According to the GLSL spec version 1.2, ints can be cast to floats automatically. Ati has always held back on casting, nvidia being far more forgiving. However recently ATi made some advances in their compiler and now it works - almost. People programming small shaders, should be very careful in one particular case: functions.&lt;br /&gt;Since the July driver update from ATi, the following are now all valid on Ati (verified with x1900, no version of shaders declared):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;float a=1;&lt;br /&gt;vec3 a=vec3(1);&lt;br /&gt;float a=1/128;&lt;br /&gt;a=max(a,0);  //warning:invalid on NVIDIA..do not use&lt;br /&gt;a=pow(a,8);  //warning:invalid on NVIDIA..do not use&lt;br /&gt;if(a&gt;0)...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Previous Ati drivers required (in most cases above) to use a "." in the number eg:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;a=max(a,0.);&lt;br /&gt;if(a&gt;0.)...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However, even on ATi, one exception still remains: user defined functions.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;float f(float x) {return x+1;}  //valid&lt;br /&gt;f(1); // INVALID&lt;br /&gt;f(1.); // valid&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Also:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;float f(float x) {return 0;}  //INVALID&lt;br /&gt;float f(float x) {return 0.;}  //valid&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, essentially, values passed to and back from a user defined function must still be explicitly typed. This is the only exception I have found so far on ATI. Intrinsic functions operate by implicitly casting (eg max). &lt;span style="font-weight:bold;"&gt;However on Nvidia, intrinsic functions must also be strongly typed.&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;So the only safe way forward as of today is to make sure that all parameters into and out of *any* function are strongly typed (use the "." form) and do not rely on implicit casting.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The GLSL spec says that functions may be overloaded just by changing the types input. Therefore, the cards are trying to show the correct behaviour. The only hiccup is that ATI have decided that intrinsic functions are known and the user has not provided an overloaded version themselves so the implicit cast will go ahead. This seems to be an open (but known) issue in the spec.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7627530950163620619?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7627530950163620619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7627530950163620619'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/08/float-casting-today.html' title='Float casting in GLSL (today)'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-4236926094386759502</id><published>2008-08-13T19:27:00.004+02:00</published><updated>2008-08-14T09:48:19.684+02:00</updated><title type='text'>Thanks for credits</title><content type='html'>I wanted to say quickly that that I had credits/greets in two recent 4ks. This really encouraged me to continue posting "useful" snippets here even though sometimes my ideas get used before I get chance to finish a 4k! Thanks guys.&lt;a href="http://www.pouet.net/prod.php?which=51114"&gt;Nucleophile&lt;/a&gt; which won at Assembly and &lt;a href="http://www.pouet.net/prod.php?which=51215"&gt;fractoblob&lt;/a&gt; which uses the wada idea from a previous blog but successfully removes the sparklies that I suffered.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-4236926094386759502?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4236926094386759502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4236926094386759502'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/08/thanks-for-credits.html' title='Thanks for credits'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-4192557934990354766</id><published>2008-08-13T18:56:00.006+02:00</published><updated>2008-08-13T19:29:34.334+02:00</updated><title type='text'>Isosurfaces in GLSL</title><content type='html'>To render an isosurface in GLSL, you'll need:&lt;br /&gt;* a fast graphics card&lt;br /&gt;* ps 3.0&lt;br /&gt;&lt;br /&gt;The basic algorithm is simple:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;For each pixel&lt;br /&gt;  Step along ray until surafce is hit&lt;br /&gt;  Find normal&lt;br /&gt;  Light and output colour&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are two complications though. Firstly when you ray march, you need to step a certain amount along the ray. Of course when you step, you may go through the surface, not exactly hit it. The smaller the step, the less this is important but the more compute power is required. The solution is a root finder. Essentially a root finder is required (eg secant, newton etc) so the steop along the ray is acceptably large (for performance) but a close enough approximation to the surface can be found (for visual integrity). When the ray passes through the surface a root finder is used to find the EXACT intersection.&lt;br /&gt;&lt;br /&gt;Here is a very simple root finder function in glsl:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;float rootfind(in float a,in float b,in vec3 eye,in vec3 raydirection){&lt;br /&gt;float exact;&lt;br /&gt;  for(int i=0;i&lt;9;i++){&lt;br /&gt;    exact=(b+a)/2.0;&lt;br /&gt;    if ( func(eye+exact*raydirection)&lt;0.0 ) b=exact;&lt;br /&gt;    else a=exact;&lt;br /&gt;  }&lt;br /&gt;  return exact;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the above example the function "func" is the isosurface we ar trying to intersect.&lt;br /&gt;&lt;br /&gt;Here the algorithm is simple and tiny. a and b are parametric values for points either side of the exact intersection (you have these from ray marching). The rootfinder iterates a fixed number of times. Each time, the exact answer is approximated by the value half way between the previous two best guesses (initially a and b) which are an upper bound and a lower bound of the exact value. If the function value at "exact" is negative we must make the lower bound (b) equal to "exact", if its positive we update the upper bound instead because the intersection is when the function is equal to 0.&lt;br /&gt;&lt;br /&gt;This is inefficient but its the simplest root finder to understand and can be coded very small.&lt;br /&gt;&lt;br /&gt;So assuming we find the exact intersection using this method, mow what is the Normal to the surface? The normal is the rate of change of the function in x,y and z. We already have the value of the function at one point (the intersection point). So we need to call the function three more times, offset in each of x,y and z, find the differences and , optionally, normalise the results.&lt;br /&gt;&lt;br /&gt;Here is a simple function in glsl to find a normal of an isosurface:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;vec3 isonormal (in vec3 v, in float val)&lt;br /&gt;{&lt;br /&gt;  return normalize(vec3(val-func( vec3(v.x+.01, v.y, v.z) ),&lt;br /&gt;                        val-func( vec3(v.x, v.y+.01, v.z) ),&lt;br /&gt;                        val-func( vec3(v.x, v.y, v.z+.01) ) ) );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;The function above takes the intersection point and the value of "func" at this intersection point as input and returns the normalised normal as a vec3. Notice how a small delta is added to each of x, y and z for the intersection point to get a new position in space. e.g.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;val-func( vec3(v.x+.01, v.y, v.z) )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;is a single float representing the change in "func" between the intersection point a a new point just a little to its right in x.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-4192557934990354766?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4192557934990354766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4192557934990354766'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/08/isosurfaces-in-glsl.html' title='Isosurfaces in GLSL'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2405005772323103485</id><published>2008-08-08T10:51:00.005+02:00</published><updated>2008-08-14T09:45:15.592+02:00</updated><title type='text'>New 4k coming, Nvidia Zero</title><content type='html'>Real life has kept me from programming for a long time. Fortunately things are sorting themselves out so I have a new 4k coming up (in conjunction with s!p this time). This one is heavy on the shaders and Pohar has challenged me to get 20 shader pairs into a single 4k. So be it Pohar - 20 shader pairs it is ;-).&lt;br /&gt;&lt;br /&gt;However, blogs with no useful stuff in them suck so here goes.&lt;br /&gt;&lt;br /&gt;Mentor recently pointed out on Pouet that he used the "noise" function for his brilliant Himalaya 1k. Only noise does not work on graphics cards at hardware speeds. He used it in software! This started me to thinking that it would be possible to pre-render cool textures using shaders in SOFTWARE during the pre-calc of a 4k/64k. The idea was simple, write shaders as normal but use the powerful functions that drop back to software (noise, dfdx etc), have them render to a back buffer slowly during the "loading" section of hte product, capture the texture, and then use the textures in real time shaders later.&lt;br /&gt;&lt;br /&gt;A simple example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;const char *vsh="void main(){gl_Position=ftransform();}";&lt;br /&gt;const char *fsh="&lt;br /&gt;void main(){&lt;br /&gt;  gl_FragColor= vec4(&lt;br /&gt;    sin(30.0*length(noise2(gl_FragCoord.xy*0.01)))&lt;br /&gt;  );\&lt;br /&gt;}";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Results in:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/SJwUvxi1YMI/AAAAAAAAAHY/mNtM5djilbQ/s1600-h/shot_3.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_xl45__0O0dM/SJwUvxi1YMI/AAAAAAAAAHY/mNtM5djilbQ/s200/shot_3.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5232079678083522754" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Great - finally a way to do interesting textures at 4k in very few bytes (assuming you are using shaders anyway).&lt;br /&gt;&lt;br /&gt;Only. No. This is OpenGL, not directx texture rendering. Nothing works the way it should. In this case the correct results (as per the GLSL specification) are achieved on ATi. On Nvidia, the rules break and Noise - the key to these textures - returns a big fat zero. This renders (you see what I did there :-) the whole idea useless. &lt;br /&gt;&lt;br /&gt;ATi 1 - Nvidia 0.&lt;br /&gt;&lt;br /&gt;So, noise on Nvidia cards returns 0 in GLSL. Sigh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2405005772323103485?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2405005772323103485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2405005772323103485'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/08/new-4k-coming-nvidia-zero.html' title='New 4k coming, Nvidia Zero'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_xl45__0O0dM/SJwUvxi1YMI/AAAAAAAAAHY/mNtM5djilbQ/s72-c/shot_3.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-4481249311781275282</id><published>2008-07-16T13:28:00.006+02:00</published><updated>2008-07-16T14:05:39.787+02:00</updated><title type='text'>Iss3 - another 4k, while I slept</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_xl45__0O0dM/SH3bwwOslgI/AAAAAAAAAGk/m1Wfle704LE/s1600-h/50932.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_xl45__0O0dM/SH3bwwOslgI/AAAAAAAAAGk/m1Wfle704LE/s320/50932.jpg" alt="" id="BLOGGER_PHOTO_ID_5223572773446391298" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Real life has prevented me coding for a long time now. But something as simple as not coding shouldn't prevent you making releases. Pohar of Hardread had some of my shader code lying around and, in deadline desperation I suspect, threw it into his new intro and gave me some credits. Inno from Conspiracy did the music and the synth is Pohars too. The 4k came second at SceneCon08 in Hungary.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=50932"&gt;Get iss3 here.&lt;/a&gt;&lt;br /&gt;Requires ps2.0&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/WA-eZU6OLDE&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/WA-eZU6OLDE&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;The video really doesnt do the shaders justice, I recommend trying the original.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://levelup.hu/video.php?todo=details&amp;amp;vid=203"&gt;Hungarian Television&lt;/a&gt; also did a piece about SceneCon demoparty in which the intro in shown. Its 40 minutes of mainly Hungarian but I know quite a few visitors to this page are from Hungary so there it is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-4481249311781275282?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4481249311781275282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4481249311781275282'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/07/iss3-another-4k-while-i-slept.html' title='Iss3 - another 4k, while I slept'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_xl45__0O0dM/SH3bwwOslgI/AAAAAAAAAGk/m1Wfle704LE/s72-c/50932.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7035177164735345357</id><published>2008-04-24T23:32:00.003+02:00</published><updated>2008-07-16T13:40:18.682+02:00</updated><title type='text'>The end of an era: no more 1ks</title><content type='html'>Well its time to confess. The Riverwash 1k invitro will be my last 1k. I've been doing 1ks for over 2 years now and its time to move on. Thanks to everyone who voted for it and thanks to Riverwash organisers for asking me. Although I said I wouldn't publish code anymore, I can't think of a better way to bow out of 1k coding than to publish the last one so you can &lt;a href="http://scener.neostrada.pl/releases/riverwash_code.zip"&gt;download the code here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I hope in the last 2 years, my efforts at 1k and my publishing code have encouraged and enabled a few people to get going with 1ks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7035177164735345357?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7035177164735345357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7035177164735345357'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/04/end-of-era.html' title='The end of an era: no more 1ks'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-5266278577975196660</id><published>2008-04-16T13:11:00.003+02:00</published><updated>2008-04-16T13:20:34.765+02:00</updated><title type='text'>Chip Magazine</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/SAXf2aTt74I/AAAAAAAAAGc/qDXEIcIsO1c/s1600-h/chip.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_xl45__0O0dM/SAXf2aTt74I/AAAAAAAAAGc/qDXEIcIsO1c/s400/chip.png" alt="" id="BLOGGER_PHOTO_ID_5189800271482318722" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Today Chip Magazine was released so I can finally put an image here from the magazine. It basically says that the 1k intro collection by auld (me) is on the DVD together with some coding frameworks.&lt;br /&gt;&lt;br /&gt;If you find your way here from reading Chip and are completely confused about the demoscene or how 1k intros are developed, I have set up an email address to contact me:&lt;br /&gt;&lt;br /&gt;auld67 .at. gmail.com&lt;br /&gt;&lt;br /&gt;You should also know that the framework included is old and non-optimal as there are license issues distributing the new one which includes a special compressor called "crinkler". So if you get into size coding, contact me and I'll explain how to get set up with crinkler.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-5266278577975196660?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5266278577975196660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5266278577975196660'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/04/chip-magazine_16.html' title='Chip Magazine'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/SAXf2aTt74I/AAAAAAAAAGc/qDXEIcIsO1c/s72-c/chip.png' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-1749908196052448670</id><published>2008-04-09T07:30:00.007+02:00</published><updated>2008-04-14T19:51:40.552+02:00</updated><title type='text'>Riverwash 1k invitro</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/SANhLKTt73I/AAAAAAAAAGU/qlpspjBx2E4/s1600-h/50376.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_xl45__0O0dM/SANhLKTt73I/AAAAAAAAAGU/qlpspjBx2E4/s400/50376.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5189098040034455410" /&gt;&lt;/a&gt;&lt;br /&gt;I've just finished a tiny (1k) invitro for the &lt;a href="http://www.riverwash.info/"&gt;Riverwash party&lt;/a&gt; as an experiment. It was a real challenge to squeeze in all the usual text for an invitro (name, date, place, compos, website) into a 1k and present it in an interesting way. Its no work of art but it does the job quite nicely. I don't know any other invitros of this size so I think its the smallest one ever done.&lt;br /&gt;&lt;br /&gt;The concept is very simple: an infinite zoom on text. At Evoke 2006,'Die Ewigkeit schmerzt' by neuro won the demo compo using a version of this technique. Neuro and Farbrausch then won Breakpoint 2008 demo competition with a very advanced and beautiful version.  &lt;br /&gt;&lt;br /&gt;Getting it into 1k would have been impossible without the '+' sign. The technique relies on one item being displayed inside another as you zoom. So things have to be carefully placed. However, by using the plus sign, I was able to guarantee a character in an area of the screen that would always be placed correctly for the next text. Its not always necessary (capital P, R and so on do not need it as they have horizontal bars in the right place), but it often is. This simple trick meant I did not need to store text co-ordinates or interpolate as I zoom from one place to another. &lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=50376"&gt;&lt;br /&gt;Download it here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Incase you are wondering, the extreme colours are because Riverwash takes place in Poland.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-1749908196052448670?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/1749908196052448670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/04/riverwash-1k-invitro.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1749908196052448670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1749908196052448670'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/04/riverwash-1k-invitro.html' title='Riverwash 1k invitro'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_xl45__0O0dM/SANhLKTt73I/AAAAAAAAAGU/qlpspjBx2E4/s72-c/50376.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-1437990003184906286</id><published>2008-04-09T07:27:00.002+02:00</published><updated>2008-04-09T07:30:11.512+02:00</updated><title type='text'>Chip Magazine</title><content type='html'>Polish Chip Magazine will be publishing all my 1 kilobyte intros in next months edition (available from 16th April). The good ones and the bad ones!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-1437990003184906286?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/1437990003184906286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/04/chip-magazine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1437990003184906286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1437990003184906286'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/04/chip-magazine.html' title='Chip Magazine'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-4771303935942114241</id><published>2008-03-30T22:45:00.005+02:00</published><updated>2008-03-30T23:02:57.198+02:00</updated><title type='text'>Raytraced spheres (again)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/R-_93uDgDNI/AAAAAAAAAGM/oyO_93UOi9Y/s1600-h/4k+2008-03-30+13-08-24-97.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_xl45__0O0dM/R-_93uDgDNI/AAAAAAAAAGM/oyO_93UOi9Y/s400/4k+2008-03-30+13-08-24-97.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5183640829824077010" /&gt;&lt;/a&gt;&lt;br /&gt;The image here shows a snapshot of an animation through a cloud of 40,000 raytraced spheres. I was able to get 2.6million raytraced spheres per second from an x1900, 2.2 Ghz core duo PC at 1024x768 resolution. In fact, the rate was limited by the host PC. The method used was to render a quad billboard for each sphere and send a single spheres details (centre, radius) to the raytracing shaders using a glColor4f call. Sounds odd, but it saved on extensions code. The billboarding is calculated by hand, as it were, on the host and each quad uses four glVertex calls. Switching to submitting a vertex buffer and calculating the billboarding in a vertex shader would probably speed things up but as my graphics card is already melting, I gave it a break.&lt;br /&gt;&lt;br /&gt;There are no shadows or reflections so technically this is raycasting only. Nontheless seeing 40,000 perfectly shaped spheres (even close up) drifting by, is quite a joy. I also went to the trouble of uploading camera co-ordinates to the shader and created a free roaming camera - all my raytracing so far has been from a fixed point of view.&lt;br /&gt;&lt;br /&gt;One last point, look at the picture and you can see spheres intersect. This is because the z value output in the shader is not the z-value of the billboard but the real z-value of the sphere. This shows that the image isnt constructed from a simple point sprite system or a particle system using texture mapping but uses real raycasting on each sphere.&lt;br /&gt;&lt;br /&gt;The spheres are per-pixel lit and bump-mapped. Click on the image for a larger version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-4771303935942114241?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/4771303935942114241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/03/raytraced-spheres-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4771303935942114241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4771303935942114241'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/03/raytraced-spheres-again.html' title='Raytraced spheres (again)'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_xl45__0O0dM/R-_93uDgDNI/AAAAAAAAAGM/oyO_93UOi9Y/s72-c/4k+2008-03-30+13-08-24-97.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2862898473053851104</id><published>2008-03-16T15:26:00.003+01:00</published><updated>2008-03-16T15:29:18.842+01:00</updated><title type='text'>Shader Programming is Bad for your Health</title><content type='html'>Well OK, the health of your PC graphics card. Here is an error message I got from one of my 1ks today:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/R90uaMy1VbI/AAAAAAAAAF0/Zvehwu3AgUw/s1600-h/shot_04.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_xl45__0O0dM/R90uaMy1VbI/AAAAAAAAAF0/Zvehwu3AgUw/s320/shot_04.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5178346174191850930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Click on it to see a bigger version. The fans are fine, there is no blockage. Think I better buy a backup card...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2862898473053851104?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/2862898473053851104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/03/shader-programming-is-bad-for-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2862898473053851104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2862898473053851104'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/03/shader-programming-is-bad-for-your.html' title='Shader Programming is Bad for your Health'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/R90uaMy1VbI/AAAAAAAAAF0/Zvehwu3AgUw/s72-c/shot_04.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-8719207370656899246</id><published>2008-03-14T20:13:00.008+01:00</published><updated>2008-03-21T16:02:16.405+01:00</updated><title type='text'>Very small logos for 4k?</title><content type='html'>There was a topic on Pouet recently of doing logos in 256bytes. I didn't even know this was possible so I gave it a go. The logo below is 183 bytes.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/R9rPF8y1VZI/AAAAAAAAAFk/ludRgJ2TPts/s1600-h/pouet.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/R9rPF8y1VZI/AAAAAAAAAFk/ludRgJ2TPts/s320/pouet.png" alt="" id="BLOGGER_PHOTO_ID_5177678422741439890" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I learnt a few things. Firstly, PNG tends to be smaller than JPEG at this level of compression so PNG is best. Second, I used Paint Shop Pro (can't afford photoshop) and switched on all its optimising and the image was well over 300 bytes. However I then downloaded &lt;a href="http://www.irfanview.com/"&gt;irfanView&lt;/a&gt; and the available plugins for it. One of the plugins is called PNGOUT and its great at compressing. &lt;br /&gt;&lt;br /&gt;One thing, make sure you set save chunks to NONE. Heres another example, much larger, and only 227 bytes. Obviously the black helps...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/R9rkKcy1VaI/AAAAAAAAAFs/aHRjPkj03dA/s1600-h/auld2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_xl45__0O0dM/R9rkKcy1VaI/AAAAAAAAAFs/aHRjPkj03dA/s320/auld2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5177701589795034530" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So it would be possible to make a logo for a 4k intro for 150-200 bytes. PNG loading is easy too, simply load the image using d3dx - very few bytes. It can be read into an array and passed to OpenGL textureing if required...at least I hope so - the logo is 1 bit per pixel, I'm not sure how it will appear in memory when loaded. One way to find out...&lt;br /&gt;&lt;br /&gt;In more tests, I did 16x16 images to see if texturing would be possible this way. Once you have the code to load a PNG it makes sense to use it as many times as possible. However the file over head is such that even the simplest of 16x16 images is around 100 bytes. So there is no significant advantage in going very small and really any PNG image looks like it is going to be 100-200 bytes as a minimum. At this size it makes more sense to encode the 1-bit bitmaps into the code itself and use GL_BITMAP type for the texture (16x16x1 = 32 bytes).&lt;br /&gt;&lt;br /&gt;A couple more tries, close to 256bytes each.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/R-PN1ODgDLI/AAAAAAAAAF8/Jy5DV70-op8/s1600-h/pouet2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_xl45__0O0dM/R-PN1ODgDLI/AAAAAAAAAF8/Jy5DV70-op8/s400/pouet2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5180210310595742898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/R-PN1-DgDMI/AAAAAAAAAGE/Kv9akgFgaMU/s1600-h/pouet4.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_xl45__0O0dM/R-PN1-DgDMI/AAAAAAAAAGE/Kv9akgFgaMU/s400/pouet4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5180210323480644802" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-8719207370656899246?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/8719207370656899246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/03/very-small-logos-for-4k.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8719207370656899246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8719207370656899246'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/03/very-small-logos-for-4k.html' title='Very small logos for 4k?'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/R9rPF8y1VZI/AAAAAAAAAFk/ludRgJ2TPts/s72-c/pouet.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-4977553908072332274</id><published>2008-03-12T22:20:00.006+01:00</published><updated>2008-04-10T10:16:27.653+02:00</updated><title type='text'>Traditionally Sceners Dont Publish Code</title><content type='html'>I read that in a scene magazine recently. Since I started I've been publishing code and trying to help people newer than myself to improve. I was naive and thought that was just the right thing to do. Dumb or clever, I shared  my code. Some of it useful, most not so much, but I shared it. However, lately its been more trouble than its worth. Actually no, right from the start. I published code then removed it only to receive nasty emails about the removal, as if people had a right to my code. I've had my code ripped with no credits. I've had people contact me very late at night to fix their code and been angry that I don't want to help at midnight. I've helped people as much as I could and then not received any credit. People have been angry at me that I size optimised their code: one guy even seems not to want to share code anymore.&lt;br /&gt;&lt;br /&gt;Real-life is enough hassle without all this. So, after a lot of thought, I've decided to restrict this blog to the usual boring stuff like what I am working on and so forth. No more code here: I'll do it the traditional way from now on.&lt;br /&gt;&lt;br /&gt;Now Ill just wait for someone to be angry at me because I stopped sharing code...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-4977553908072332274?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/4977553908072332274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/03/traditionally-sceners-dont-publish-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4977553908072332274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4977553908072332274'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/03/traditionally-sceners-dont-publish-code.html' title='Traditionally Sceners Dont Publish Code'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-404564805013455388</id><published>2008-03-11T18:46:00.004+01:00</published><updated>2008-03-11T18:52:04.768+01:00</updated><title type='text'>The Best (sur)Prize!</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/R9bGasy1VYI/AAAAAAAAAFc/SNWtckECa3w/s1600-h/rebs.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_xl45__0O0dM/R9bGasy1VYI/AAAAAAAAAFc/SNWtckECa3w/s320/rebs.jpg" alt="" id="BLOGGER_PHOTO_ID_5176542983712232834" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Well, lifes a bit rough now and then (more sort of now than then) but sometimes you get really cheered up. This package arrived today from Pohar of Rebels. So opening it, I found s cool Rebels t-shirt. I did a couple of 4ks for rebels with Pohar last year, so this is my prize and I have to say - its a good one. Heres a piccie especially for my mates over at Rebels - in my opinion, the group improving most all the time in the demoscene.&lt;br /&gt;&lt;br /&gt;Go Rebels!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-404564805013455388?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/404564805013455388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/03/best-surprize.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/404564805013455388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/404564805013455388'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/03/best-surprize.html' title='The Best (sur)Prize!'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_xl45__0O0dM/R9bGasy1VYI/AAAAAAAAAFc/SNWtckECa3w/s72-c/rebs.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-92134138371304755</id><published>2008-03-07T16:31:00.006+01:00</published><updated>2008-04-10T10:21:06.834+02:00</updated><title type='text'>All my 1ks (1024byte) intros</title><content type='html'>Again, I published a lot of these under different names but incase there is any confusion, &lt;span style="font-weight: bold;"&gt;all these tiny intros are my own work&lt;/span&gt;. Its clear to see from these that I got better and better: well as a general trend anyway. Its good to see such a progression over the last two years. I'd advise anyone entering the scene, no matter how much experience you have that it will take a few years to get good. I still haven't made a 4k I'm happy with but I do like my latest 1k chocolux. This one turned out well and for once I'm happy. Anyway to the list. They are in (roughly) reverse order, so the most recent one is first.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=49796"&gt;Chocolux&lt;/a&gt; (PS3.0 required)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: Recursive raytracing of spheres.&lt;br /&gt;Personal Rating: 9/10. Colours right! At last 9/10 - one I like.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=31090"&gt;Labyrinth1k &lt;/a&gt;(FAST PS3.0 required)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: Raymarching.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Personal Rating: 7/10. Colours wrong! Camera path and animation synched in 1k isnt bad though. I feel this one is underrated. I can see why though. Slooooow.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=30589"&gt;Flow2&lt;/a&gt; (PS2.0 required)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A corrupted mandelbrot set with two merging rendering schemes.&lt;br /&gt;Personal Rating: 8/10. Its really very nice to look at.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=2463"&gt;Annoying Blue Circle&lt;/a&gt; (PS2.0 required)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A sphere with displacement shader and cool colours.&lt;br /&gt;Personal Rating: 8/10. It works, its fun and has good sound by ampli.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=2062"&gt;Mandelflow&lt;/a&gt; (PS2.0 required)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A corrupted mandelbrot set with candy colour scheme.&lt;br /&gt;Personal Rating: 7/10. Its nice to look at but not quite as advanced as flow2.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=1340"&gt;Morpheus&lt;/a&gt; (PS2.0 required)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A sphere with displacement shader.&lt;br /&gt;Personal Rating: 7/10. It works, it has sound and texture.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=1325"&gt;Trinity&lt;/a&gt; (PS2.0 required)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A sphere with displacement shader and noise.&lt;br /&gt;Personal Rating: 8/10. This is my fav of the matrix trilogy. This one feels like trinity to me. No sound loses it points ut the presentation works very well.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=1321"&gt;MrAnderson&lt;/a&gt; (PS2.0 required)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A sphere with displacement shader.&lt;br /&gt;Personal Rating: 7/10. The first OGL and shader 1k anywhere!&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=2412"&gt;Ah Bollocks&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A sphereflake (sortof) with a cool animated texture by mind.&lt;br /&gt;Personal Rating: 4/10. I dont like it. Its rough and colours are depressing.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=1611"&gt;Grail1k&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: Curved, animated, 3d models in 1k!&lt;br /&gt;Personal Rating: 6/10. OK it looks rough but curved 3d models gives it points for me.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=815"&gt;Scotland the furball&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: Fur in 1k.&lt;br /&gt;Personal Rating: 4/10. The fur should animate and its way too slow. Still - fur!&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=743"&gt;Revolver&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A tenticular monster, animated.&lt;br /&gt;Personal Rating: 4/10. Very low tech but it works ok, the animation is nice.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=736"&gt;Hive&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A proper intro (start, middle, music, textures, 3d model, camera move)&lt;br /&gt;Personal Rating: 6/10. It looks rough again (why do I do this) but its got so much in it I have to rate it well.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=1322"&gt;Abscrapt&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: An interpreter language in 1k drawing some abstract rubbish.&lt;br /&gt;Personal Rating: &lt;/span&gt;&lt;span style="font-size:85%;"&gt;3/10. &lt;/span&gt;&lt;span style="font-size:85%;"&gt;Just awful colours destroy this one.  &lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=435"&gt;Mus1k&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: a real synth in 1k.&lt;br /&gt;Personal Rating: 3/10. It just didnt work.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=421"&gt;Hypnot1k&lt;/a&gt; (WinXP SP2 ONLY)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: Music, speach, text and graphics in 1k.&lt;br /&gt;Personal Rating: 2/10. My god what was I thinking - the colours - the sound.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=362"&gt;Kagazoon &lt;/a&gt;(WinXP ONLY)&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: Watch your screen spin in 1k.&lt;br /&gt;Personal Rating: 7/10 the first time. 5/10 thereafter. Its not bad looking but its a gimmick. &lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=335"&gt;Rad1kal&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: 6 or seven scenes in 1k!&lt;br /&gt;Personal Rating: 6/10. The scenes are too long and a bit ugly but damn thats a lot of effects in 1k! Show me any 1k with even half this many scenes.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=332"&gt;Debut1k&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Comment: A texture gen engine in 1k.&lt;br /&gt;Personal Rating: 5/10. Not bad, not too ugly. Texture gen in 1k is not so easy.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Phew I think thats all. These days even a 1k takes me more than a month to find a good idea and nail it so it works on Nvidia, ATi and fits inside 1k.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-92134138371304755?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/92134138371304755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/03/all-my-1ks-1024byte-intros.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/92134138371304755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/92134138371304755'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/03/all-my-1ks-1024byte-intros.html' title='All my 1ks (1024byte) intros'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-4615842211108764497</id><published>2008-03-06T18:28:00.005+01:00</published><updated>2008-04-10T10:17:45.107+02:00</updated><title type='text'>My 4ks</title><content type='html'>I thought it was worth listing all my 4ks so far here. Not all credits in files say Auld. Thats because I liked to use different names to publish code under. These days I only use Auld.&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=32225"&gt;&lt;br /&gt;Spheres Dream&lt;/a&gt;.&lt;br /&gt;Requirements: PS2.0, OpenGL 2.0&lt;br /&gt;Comment: Done for Rebels demogroup. Voted best Mac intro of 2007. Second at Function 2007. Mellow, dreamy, spherey.&lt;br /&gt;Credits: Auld (code and design), H20 (design), Pohar (synth), Vincennzo (music).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.pouet.net/prod.php?which=33677"&gt;Fruit of the Loop&lt;/a&gt;&lt;br /&gt;Requirements: PS2.0, OpenGL 2.0&lt;br /&gt;Comment: Done for Rebels demogroup. Second at Kindergarten 2007. A bit weird.&lt;br /&gt;Credits: Auld (code and design), Pohar (code and synth), Vincennzo (music).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=1268"&gt;Inferno&lt;/a&gt;.&lt;br /&gt;Requirements: OpenGL 1.4&lt;br /&gt;Comment: Done for Titan demogroup. Winner Evoke 2006 4k intro. Dantes trip to Hell, re-interpreted and set to hard music.&lt;br /&gt;Credits: Auld (code, synth, design), Saida (tools, synth), Strobe (music), Alien^pdx (design)&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=1271"&gt;&lt;br /&gt;GS&lt;/a&gt;.&lt;br /&gt;Requirements: OpenGL 1.4&lt;br /&gt;Comment: Done for MUPS demogroup.&lt;br /&gt;Credits: Auld (code, synth, "design" :-)), Saida (tools, synth), SOR (nfo file), ampli (music)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.intro-inferno.com/production.php?id=1569"&gt;Halls o' Halloween&lt;/a&gt;&lt;br /&gt;Requirements: OpenGL 1.4&lt;br /&gt;Comment: done for DBF Halloween competition 2006. Won 1st place. Lots of geometry for 4k.&lt;br /&gt;Credits: Auld (code, synth), Saida (tools, synth), Ampli (music)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-4615842211108764497?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/4615842211108764497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/03/my-4ks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4615842211108764497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4615842211108764497'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/03/my-4ks.html' title='My 4ks'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2179996409568044124</id><published>2008-03-01T17:59:00.003+01:00</published><updated>2008-03-01T23:51:51.901+01:00</updated><title type='text'>To Vertex Shade or not to Vertex Shade</title><content type='html'>The GLSL specification says that it is legal to create a shader that has one instance of a fragment shader and no vertex shader. Under these conditions, the default vertex pipeline should run. This worked on Nvidia and ATi - sort of. ATi allowed it but did not set up gl_FragCoord correctly - effectively making the fragment shader useless. In other words, it didn't work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;However, on Feb 13th 2008 ATi released new drivers which cured the problem.  So its now possible to write tiny glsl code without a vertex shader.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Only tested for sure on x1950 so far but will test on other cards soon...&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2179996409568044124?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/2179996409568044124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/03/to-vertex-shade-or-not-to-vertex-shade.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2179996409568044124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2179996409568044124'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/03/to-vertex-shade-or-not-to-vertex-shade.html' title='To Vertex Shade or not to Vertex Shade'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-4891068325516139217</id><published>2008-02-26T22:41:00.007+01:00</published><updated>2008-03-01T18:16:56.333+01:00</updated><title type='text'>Chocolux 1k intro</title><content type='html'>Chocolux is a real-time recursive raytracer using four spheres. Lighting and intersections are all approximated to fit the 1024 bytes boundary. I used crinkler 1.1 for compression. The executable can be downloaded at &lt;a href="http://www.pouet.net/prod.php?which=49796"&gt;Pouet&lt;/a&gt; or &lt;a href="http://www.intro-inferno.com/production.php?id=6074"&gt;Intro Inferno&lt;/a&gt;. For those with no PS3.0 card is a video:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/au1j1hV9H5U"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/au1j1hV9H5U" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://scener.neostrada.pl/releases/chocolux_code.zip"&gt;code&lt;/a&gt; can be downloaded here.&lt;br /&gt;&lt;br /&gt;Probably the best space saving trick in the code is:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;t=GetTickCount();&lt;br /&gt;glRecti(t,t,-t,-t);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This allows the time to be passed into the shader without either using glGetProcAddress calls for the extensions or using glColor3f which is smarter but still not as good. So long as t is bigger than 1 (it will be as GetTickCount is a millisecond counter from boot time of the PC) the screen will be drawn and the value of the vertex can be used for the timer.&lt;br /&gt;&lt;br /&gt;The recursive raytracer is no use to anyone outside this code as the maths is corrupted to give a more detailed image and smaller bytes. However, Pohar found a trick worth mentioning. The nested loops in the fragment shader both use i as the variable (rather than say i and j). This allows crinkler to really go to work and compress this code down. Its legal in shaders and, I'm told, C too.&lt;br /&gt;&lt;br /&gt;One other byte saving trick I haven't seen anywhere else is I have no background test in the code when rays do not intersect objects. Normally this would be an if and some calculation to assign colour for the background. Instead, I place the scene inside a sphere so I know the ray will always hit one object. This also adds a lot of visual complexity to the scene.&lt;br /&gt;&lt;br /&gt;There are pragma statements like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#pragma data_seg(".shad2")&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;#pragma code_seg(".compile")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;scattered through the code. These are to assist crinkler as it may reorder the code more, saving here, 6 bytes. These are placed just before data and just before every function and the main entry point.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-4891068325516139217?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/4891068325516139217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/02/chocolux-1k-intro.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4891068325516139217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4891068325516139217'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/02/chocolux-1k-intro.html' title='Chocolux 1k intro'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-8462629012695308913</id><published>2008-02-17T20:24:00.003+01:00</published><updated>2008-02-17T20:29:05.795+01:00</updated><title type='text'>POVRay 2008 Short Coding Compo Results</title><content type='html'>All I can say is wow, &lt;a href="http://local.wasp.uwa.edu.au/~pbourke/exhibition/scc5/final.html"&gt;some of these animations are amazing&lt;/a&gt;. Congrats to all the winners. My personal favourite is second place. It lacks a little of the visual artistry of the winner but the technical aspects are amazing. Shaking camera, explosion of light, nuclear cloud. Animated. IN 512 bytes? Awesome work. The idea to use a sphere instead of a sky sphere so the sky glows for an instant when the explosion happens is really inventive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-8462629012695308913?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/8462629012695308913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/02/povray-2008-short-coding-compo-results.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8462629012695308913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8462629012695308913'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/02/povray-2008-short-coding-compo-results.html' title='POVRay 2008 Short Coding Compo Results'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2923189714523349602</id><published>2008-02-17T10:13:00.006+01:00</published><updated>2008-02-17T19:42:15.945+01:00</updated><title type='text'>Wada updated</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/R7f_ZSP4EtI/AAAAAAAAAE0/gkcmqkwJ1Kc/s1600-h/shot_34.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_xl45__0O0dM/R7f_ZSP4EtI/AAAAAAAAAE0/gkcmqkwJ1Kc/s320/shot_34.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5167879907291173586" /&gt;&lt;/a&gt;&lt;br /&gt;I finally got around to fixing the colours and fixing the distortion in the wada fractal. The wada, as a reminder, is a non-self similar fractal formed by placing four reflective spheres touching each other in a kind of pyramid. Although I didn't size crunch, I guess the whole thing would be sub 1.3k. Its hard to crunch it as the wada is very sensitive to things like ambient, diffuse and specular contributions so a full raytracer has to be implemented, not just a fake approximation.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/R7f_ZiP4EuI/AAAAAAAAAE8/qzOUvyX_C9I/s1600-h/shot_38.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_xl45__0O0dM/R7f_ZiP4EuI/AAAAAAAAAE8/qzOUvyX_C9I/s320/shot_38.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5167879911586140898" /&gt;&lt;/a&gt;&lt;br /&gt;I'm rapidly coming to the conclusion that there are a range of interesting special effects available with very simple, recursive, raytracing. I won't publish code yet as likely I'll do a 4k using some of the tricks I'm working on. The point is, the wada would be very hard for traditional polygon rendering to do. The reflections would be too hard to achieve accurately. So, tiny raytracers should concentrate on lots of reflection and refraction instead of doing a range of simple primitives (sphere, cylinder, planes etc) and using you bytes this way is a mistake. Such scenes are unimpressive. &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/R7f_ZyP4EvI/AAAAAAAAAFE/7UY4BbJBTCs/s1600-h/shot_35.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_xl45__0O0dM/R7f_ZyP4EvI/AAAAAAAAAFE/7UY4BbJBTCs/s320/shot_35.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5167879915881108210" /&gt;&lt;/a&gt;&lt;br /&gt;Add to this the possiblity for traditional 2d post processing (blur, depth of field, glow) on top of raytracing and there is definitely room for overcoming the "spheres on chequer board" factor.&lt;br /&gt;&lt;br /&gt;The wada images above can be clicked on for larger versions. They are real screen captures from a real time wada renderer. Hence the larger images have some artefacts. A small blur post-processor shader will overcome this.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/R7gLjSP4EwI/AAAAAAAAAFM/-j8adxAYGeY/s1600-h/shot_39.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_xl45__0O0dM/R7gLjSP4EwI/AAAAAAAAAFM/-j8adxAYGeY/s320/shot_39.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5167893273229398786" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2923189714523349602?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/2923189714523349602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/02/wada-updated.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2923189714523349602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2923189714523349602'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/02/wada-updated.html' title='Wada updated'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_xl45__0O0dM/R7f_ZSP4EtI/AAAAAAAAAE0/gkcmqkwJ1Kc/s72-c/shot_34.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2585211323817448537</id><published>2008-02-11T14:32:00.000+01:00</published><updated>2008-02-11T23:43:00.651+01:00</updated><title type='text'>Helping Crinkler</title><content type='html'>There are two things to understand about crinkler that can help. Crinkler replaces your linker which means it has access to sections of code and data when linking. It can re-arrange these sections to achieve more compression. Even more, crinkler uses two different schemes for compression: one for code and one for data. The Crinkler manual talks about defining data and code blocks in assembler. However, its possible from C too.&lt;br /&gt;&lt;br /&gt;#pragma data_seg(".name1")&lt;br /&gt;#pragma code_seg(".name2")&lt;br /&gt;&lt;br /&gt;The pragma statements can be and should be used just before every chunk of data and every new function. Any names can be used but meaningful ones are useful when Crinkler outputs its report.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2585211323817448537?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/2585211323817448537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/02/helping-crinkler.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2585211323817448537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2585211323817448537'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/02/helping-crinkler.html' title='Helping Crinkler'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-7450972636611373566</id><published>2008-01-17T20:30:00.000+01:00</published><updated>2008-01-17T20:41:13.951+01:00</updated><title type='text'>POVRay short code contest now on</title><content type='html'>The 5th POVRay short code contest is &lt;a href="http://local.wasp.uwa.edu.au/%7Epbourke/modelling_rendering/scc5/"&gt;running&lt;/a&gt;. I'm not entering this year but here are my entries from last year, complete with code. I didn't win but had a lot of fun trying.&lt;br /&gt;&lt;br /&gt;The Cave:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/R4-uLWf6JuI/AAAAAAAAAEk/C-1NFImNsBI/s1600-h/gragbv.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/R4-uLWf6JuI/AAAAAAAAAEk/C-1NFImNsBI/s200/gragbv.png" alt="" id="BLOGGER_PHOTO_ID_5156531608403715810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#macro A(f)finish{reflection{,f}} #end&lt;br /&gt;union{plane{z,20}normal{wrinkles}A(2)}union{sphere{z*22-3,5}A(1)}&lt;br /&gt;union{plane{y,-3}normal{agate.3}A(1)}sky_sphere{pigment{agate scale 3}}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;X-Ray:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/R4-uzGf6JvI/AAAAAAAAAEs/AilrgPpoaek/s1600-h/rhahrd.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_xl45__0O0dM/R4-uzGf6JvI/AAAAAAAAAEs/AilrgPpoaek/s200/rhahrd.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5156532291303515890" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#macro A(f)cylinder{&lt;9*sin(f),6*cos(f*f),6&gt;,&lt;cos(f),sin(f),9&gt;,1,2} #end&lt;br /&gt;union{&lt;br /&gt;blob {A(4)A(5)A(8)A(9)A(0)A(1)A(2)}  &lt;br /&gt;pigment{wood}&lt;br /&gt;finish {reflection{,6}}&lt;br /&gt;}&lt;br /&gt;sky_sphere{pigment{wrinkles}}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-7450972636611373566?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/7450972636611373566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2008/01/povray-short-code-contest-now-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7450972636611373566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/7450972636611373566'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2008/01/povray-short-code-contest-now-on.html' title='POVRay short code contest now on'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/R4-uLWf6JuI/AAAAAAAAAEk/C-1NFImNsBI/s72-c/gragbv.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-9143779335730327669</id><published>2007-11-21T20:55:00.002+01:00</published><updated>2008-03-11T23:09:00.970+01:00</updated><title type='text'>Another 4k Finished.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/R0SWAKcMQ-I/AAAAAAAAAEc/09R-yx8ghFY/s1600-h/fruit4.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_xl45__0O0dM/R0SWAKcMQ-I/AAAAAAAAAEc/09R-yx8ghFY/s200/fruit4.jpg" alt="" id="BLOGGER_PHOTO_ID_5135394404655973346" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/R0SNo6cMQ7I/AAAAAAAAAEE/DnIUrCOUw8Q/s1600-h/fruit1.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://2.bp.blogspot.com/_xl45__0O0dM/R0SNo6cMQ7I/AAAAAAAAAEE/DnIUrCOUw8Q/s200/fruit1.jpg" alt="" id="BLOGGER_PHOTO_ID_5135385209130992562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/R0SNpKcMQ8I/AAAAAAAAAEM/fARG3De2IU0/s1600-h/fruit2.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_xl45__0O0dM/R0SNpKcMQ8I/AAAAAAAAAEM/fARG3De2IU0/s200/fruit2.jpg" alt="" id="BLOGGER_PHOTO_ID_5135385213425959874" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/R0SNpacMQ9I/AAAAAAAAAEU/MbLHzPHxmJ4/s1600-h/fruit3.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://4.bp.blogspot.com/_xl45__0O0dM/R0SNpacMQ9I/AAAAAAAAAEU/MbLHzPHxmJ4/s200/fruit3.jpg" alt="" id="BLOGGER_PHOTO_ID_5135385217720927186" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Using the latham and kaleidoscope shaders, I've done another 4k. This was done with Pohar (code) and Vincenzo (music) of Rebels. You can get the &lt;a href="http://scener.neostrada.pl/fruit.zip"&gt;executable here&lt;/a&gt;. It requires ps2.0. There is a final and a party version with wildly different colours. The key pieces of code are already on this blog further down. Hope you enjoy it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-9143779335730327669?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/9143779335730327669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/11/using-latham-and-kaleidoscope-shaders.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/9143779335730327669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/9143779335730327669'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/11/using-latham-and-kaleidoscope-shaders.html' title='Another 4k Finished.'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_xl45__0O0dM/R0SWAKcMQ-I/AAAAAAAAAEc/09R-yx8ghFY/s72-c/fruit4.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-5689662304271756951</id><published>2007-11-17T06:58:00.003+01:00</published><updated>2008-03-11T23:09:27.676+01:00</updated><title type='text'>Kaleidoscope shader</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/Rz6DfacMQ5I/AAAAAAAAAD0/iIqc1tEXOiA/s1600-h/kal1.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://2.bp.blogspot.com/_xl45__0O0dM/Rz6DfacMQ5I/AAAAAAAAAD0/iIqc1tEXOiA/s200/kal1.jpg" alt="" id="BLOGGER_PHOTO_ID_5133685200945693586" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/Rz6DfqcMQ6I/AAAAAAAAAD8/Cb8lPlUC_ZE/s1600-h/kal2.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_xl45__0O0dM/Rz6DfqcMQ6I/AAAAAAAAAD8/Cb8lPlUC_ZE/s200/kal2.jpg" alt="" id="BLOGGER_PHOTO_ID_5133685205240660898" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The images above are created by rendering some graphics to the back buffer, capturing this as a texture and then using that as input for a kaleidoscope shader. The kaleidoscope shader is trivially. I'm assuming you have drawn your scene and captured it to texture (see previous articles).&lt;br /&gt;&lt;br /&gt;First the vertex shader.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;varying vec4 vertexcoord;&lt;br /&gt;void main(){&lt;br /&gt;vertexcoord = gl_Vertex;&lt;br /&gt;gl_Position = gl_Vertex;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;First line 2. It sets the position to be the input vertex (not the more usual ftransform()). This ensures whatever object we draw ignores the transformation matrix. It just makes it easy to draw an object covering the screen. The important line is : vertexcoord = gl_Vertex;  Vertexcoord will be used as texture coordinates in the fragment shader.&lt;br /&gt;&lt;br /&gt;Now the fragment shader...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;uniform sampler2D tex;&lt;br /&gt;varying vec4 vertexcoord;&lt;br /&gt;void main() {&lt;br /&gt;gl_FragColor = texture2D ( tex, abs(vertexcoord.xy) );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;So an input image is drawn on the screen using the vertexcoord set in the vertex shader. Theres a trick here: abs. This is the kaleidoscope effect - this simple! Now in the main code we just draw a rect...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;glRecti(-1,-1,1,1);&lt;br /&gt;&lt;/pre&gt;A Kaleidoscope shader in very few bytes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-5689662304271756951?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/5689662304271756951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/11/kaleidoscope-shader.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5689662304271756951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5689662304271756951'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/11/kaleidoscope-shader.html' title='Kaleidoscope shader'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/Rz6DfacMQ5I/AAAAAAAAAD0/iIqc1tEXOiA/s72-c/kal1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2678346367273196433</id><published>2007-11-12T14:15:00.001+01:00</published><updated>2007-11-12T14:18:08.916+01:00</updated><title type='text'>New Layout</title><content type='html'>Site quickly redesigned to allow for wider and more readable code segments and fit the minimalist theme, so useless information has been removed. Comments (due to some trolling) removed. Most people seem to contact me by email anyway. Hope its cleaner and more useful for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2678346367273196433?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/2678346367273196433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/11/new-layout.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2678346367273196433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2678346367273196433'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/11/new-layout.html' title='New Layout'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-4534635933728603903</id><published>2007-11-04T18:22:00.000+01:00</published><updated>2007-11-12T22:25:27.757+01:00</updated><title type='text'>Read shader from file without stdlib</title><content type='html'>Over at &lt;a href="http://www.lighthouse3d.com/opengl/"&gt;Lighthouse&lt;/a&gt; there are some useful tutorials and some example code. One piece of code I've found all over is the "read a shader from a file" code. Unfortunately its not much use for size coders as it uses stdlib. Essentially it allows you to write shaders in a normal text file and load them as a string.So here I've done a conversion using win32 equivalent functions. It doesn't check error codes (wasted bytes) so be careful to pass in the right filename. I'm not sure this is the smallest way, its just a translation of Lighthouse code.&lt;br /&gt;&lt;br /&gt; Essentially adding this code to your intro allows you to develop the shader without constant recompiles.&lt;br /&gt;&lt;pre&gt;#include "windows.h"&lt;br /&gt;&lt;br /&gt; char *textFileRead(char *fn) {&lt;br /&gt;&lt;br /&gt; char *content=NULL;&lt;br /&gt; DWORD dummy;&lt;br /&gt;&lt;br /&gt; HANDLE fp = CreateFile (fn, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);&lt;br /&gt; DWORD count=SetFilePointer (fp, 0 ,NULL, FILE_END);&lt;br /&gt; SetFilePointer (fp, 0 ,NULL, FILE_BEGIN);&lt;br /&gt; content = (char *)GlobalAlloc(0,(SIZE_T)(count+1));&lt;br /&gt; ReadFile(fp, (LPVOID)content, count, &amp;amp;dummy, NULL);&lt;br /&gt; content[count] = '\0';&lt;br /&gt; CloseHandle(fp);&lt;br /&gt; return content;&lt;br /&gt;}&lt;br /&gt;&lt;/windows.h&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-4534635933728603903?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/4534635933728603903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/11/read-shader-from-file-without-stdlib.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4534635933728603903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/4534635933728603903'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/11/read-shader-from-file-without-stdlib.html' title='Read shader from file without stdlib'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-8821775343797303667</id><published>2007-11-03T11:58:00.000+01:00</published><updated>2007-11-12T13:06:04.821+01:00</updated><title type='text'>Wada basin in real time</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/RyxWDAaalBI/AAAAAAAAACw/xB056RZcNng/s1600-h/wada1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/RyxWDAaalBI/AAAAAAAAACw/xB056RZcNng/s200/wada1.jpg" alt="" id="BLOGGER_PHOTO_ID_5128568685318542354" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/RyxWDgaalCI/AAAAAAAAAC4/S_Lpck37Aoc/s1600-h/wada2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_xl45__0O0dM/RyxWDgaalCI/AAAAAAAAAC4/S_Lpck37Aoc/s200/wada2.jpg" alt="" id="BLOGGER_PHOTO_ID_5128568693908476962" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;My raytracer works well enough to set up something never seen before (I think). This is a shot of a real time animation of a Wada Basin fractal. It runs around 30 fps with no attempt to optimise. Its early days yet but I'm hoping this will really pay off. The slightly wrong shape is due to a severe perspective distortion. I'll fix this and publish better images soon. &lt;span style="font-style: italic;"&gt;As usual bigger images are available by clicking on small images.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you are unsure what a Wada Basin is and why a real time one is quite a novelty, have a look here at &lt;a href="http://local.wasp.uwa.edu.au/%7Epbourke/fractals/wada/"&gt;Paul Bourkes superb web pages&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/Ry4LZgaalDI/AAAAAAAAADA/et0j9j76-oM/s1600-h/wada3.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/Ry4LZgaalDI/AAAAAAAAADA/et0j9j76-oM/s200/wada3.jpg" alt="" id="BLOGGER_PHOTO_ID_5129049558446937138" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/Ry4LZwaalEI/AAAAAAAAADI/C84ZusfxfYI/s1600-h/wada4.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_xl45__0O0dM/Ry4LZwaalEI/AAAAAAAAADI/C84ZusfxfYI/s200/wada4.jpg" alt="" id="BLOGGER_PHOTO_ID_5129049562741904450" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm not happy with colours or shape yet but in motion, it looks great.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/Ry4rgQaalFI/AAAAAAAAADQ/DXhDA1L86rM/s1600-h/wada5.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_xl45__0O0dM/Ry4rgQaalFI/AAAAAAAAADQ/DXhDA1L86rM/s200/wada5.jpg" alt="" id="BLOGGER_PHOTO_ID_5129084858783142994" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/Ry4rggaalGI/AAAAAAAAADY/r2klslFaTDc/s1600-h/wada6.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/Ry4rggaalGI/AAAAAAAAADY/r2klslFaTDc/s200/wada6.jpg" alt="" id="BLOGGER_PHOTO_ID_5129084863078110306" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-8821775343797303667?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/8821775343797303667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/11/wada-basin-in-real-time.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8821775343797303667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8821775343797303667'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/11/wada-basin-in-real-time.html' title='Wada basin in real time'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/RyxWDAaalBI/AAAAAAAAACw/xB056RZcNng/s72-c/wada1.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-3542317231484312255</id><published>2007-10-30T07:12:00.002+01:00</published><updated>2008-03-11T23:09:59.634+01:00</updated><title type='text'>Real Time Raytracing</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/Ry4xogaalHI/AAAAAAAAADg/y34eKFtSTLg/s1600-h/rt1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; float: left; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/Ry4xogaalHI/AAAAAAAAADg/y34eKFtSTLg/s200/rt1.jpg" alt="" id="BLOGGER_PHOTO_ID_5129091597586830450" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/RybM1Qaak-I/AAAAAAAAACY/DKAYql4exm0/s1600-h/shot_05.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://4.bp.blogspot.com/_xl45__0O0dM/RybM1Qaak-I/AAAAAAAAACY/DKAYql4exm0/s200/shot_05.jpg" alt="" id="BLOGGER_PHOTO_ID_5127010441118782434" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/RybM1Qaak_I/AAAAAAAAACg/z_65i5Z5-KY/s1600-h/shot_06.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://4.bp.blogspot.com/_xl45__0O0dM/RybM1Qaak_I/AAAAAAAAACg/z_65i5Z5-KY/s200/shot_06.jpg" alt="" id="BLOGGER_PHOTO_ID_5127010441118782450" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/RydwWwaalAI/AAAAAAAAACo/_-AwSFDz8CU/s1600-h/shot_10.jpg"&gt;&lt;img style="float: left;" src="http://3.bp.blogspot.com/_xl45__0O0dM/RydwWwaalAI/AAAAAAAAACo/_-AwSFDz8CU/s200/shot_10.jpg" alt="" id="BLOGGER_PHOTO_ID_5127190237039727618" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've decided to make a tiny PS3.0 raytracer. It will take some time to get it working on lots of platforms and size optimised but here are the first two buggy but pleasing images. I'll add updates and later publish the code. &lt;span style="font-weight: bold;"&gt;Click images for larger versions. &lt;/span&gt;&lt;span&gt;It runs at about 50-60fps on my x1900 at 1024x768 resolution with six levels of reflection.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-3542317231484312255?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/3542317231484312255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/real-time-raytracing.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/3542317231484312255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/3542317231484312255'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/real-time-raytracing.html' title='Real Time Raytracing'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/Ry4xogaalHI/AAAAAAAAADg/y34eKFtSTLg/s72-c/rt1.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-6150429761017258360</id><published>2007-10-27T15:45:00.001+02:00</published><updated>2007-11-12T14:20:57.541+01:00</updated><title type='text'>Shaders to render normals : NOT!</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/RyNCmgaak8I/AAAAAAAAACI/v0Lk3Iw095Y/s1600-h/shot_3.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_xl45__0O0dM/RyNCmgaak8I/AAAAAAAAACI/v0Lk3Iw095Y/s200/shot_3.jpg" alt="" id="BLOGGER_PHOTO_ID_5126014030180946882" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;A useful debugging tool is to get a colour representation of the normals in a scene. With a bit of maths, it can also produce some nice, free colouring for an intro. Above is a correct image. It shows a whole bunch of spheres. Red is the x component of the normal, green the y and blue is z. Study it and you'll see its right. Only it took me a few hours to get this right. I made a very simple error, which maybe others do too so I thought I'd document it here.&lt;br /&gt;&lt;br /&gt;Hmmm, this is what I actually got:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/RyNDBQaak9I/AAAAAAAAACQ/2kCm-fpeELA/s1600-h/shot_2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/RyNDBQaak9I/AAAAAAAAACQ/2kCm-fpeELA/s200/shot_2.jpg" alt="" id="BLOGGER_PHOTO_ID_5126014489742447570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Pretty,yes. Wrong, definitely. Here is the WRONG CODE. This code has a serious bug:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;const GLchar *normalsvsh="\&lt;br /&gt;varying vec3 n;\&lt;br /&gt;void main(){\&lt;br /&gt;n = normalize(gl_Normal*gl_NormalMatrix);\&lt;br /&gt;gl_Position=ftransform();\&lt;br /&gt;}";&lt;br /&gt;&lt;br /&gt;const GLchar *normalsfsh="\&lt;br /&gt;varying vec3 n;\&lt;br /&gt;void main(){\&lt;br /&gt;gl_FragColor = vec4((n+1.0)*0.5,1);\&lt;br /&gt;}";&lt;br /&gt;&lt;/pre&gt;Can you spot the error? Heres a clue, the spheres are rotating about their centres at different speeds.&lt;br /&gt;&lt;br /&gt;The solution is...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;n = normalize(gl_NormalMatrix*gl_Normal);\&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-6150429761017258360?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/6150429761017258360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/shaders-to-render-normals-not.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6150429761017258360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6150429761017258360'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/shaders-to-render-normals-not.html' title='Shaders to render normals : NOT!'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/RyNCmgaak8I/AAAAAAAAACI/v0Lk3Iw095Y/s72-c/shot_3.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-6822048159801179605</id><published>2007-10-25T10:41:00.000+02:00</published><updated>2007-10-25T15:29:05.381+02:00</updated><title type='text'>Tiny OpenGL Windowing Code</title><content type='html'>Time for another framework update. Most of the framework stuff I have posted over on in4k was developed and optimised for dropper/apack. Last year hitchhiker released the first 1k  using crinkler which is now the standard for 1ks (until Mentor releases a better compressor). So its time to update the OpenGL in a window framework code. Here it is. It opens an OGL window and also handles  DEVMODE. I've added the DEVMODE bytes because shader performance varies so much on cards currently  that its critical to control the screen size of the PC your into runs on. Besides, at 4k who would ever not use DEVMODE?&lt;br /&gt;&lt;br /&gt;Tested under XP...Vista I don't know yet. If you try it, let me know OK?&lt;br /&gt;&lt;br /&gt;So, Full screen, any resolution, ultra cheap GL window:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &lt; windows.h &gt;&lt;br /&gt;#include &lt; GL/gl.h &gt;&lt;br /&gt;&lt;br /&gt;static PIXELFORMATDESCRIPTOR pfd={&lt;br /&gt;0, // Size Of This Pixel Format Descriptor... BAD coding, nothing new, saves 6 bytes&lt;br /&gt;1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 0, 0, 0, 0, 0, 0, &lt;br /&gt;0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0 &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static DEVMODE dmScreenSettings={&lt;br /&gt;"",0,0,sizeof(dmScreenSettings),0,DM_PELSWIDTH|DM_PELSHEIGHT,&lt;br /&gt;0,0,0,0,0,0,0,0,0,0,0,0,0,"",0,0,1024,768,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void WINAPI WinMainCRTStartup()&lt;br /&gt;{&lt;br /&gt;   ChangeDisplaySettings (&amp;dmScreenSettings,CDS_FULLSCREEN);  &lt;br /&gt;   HDC hDC = GetDC( CreateWindow("edit", 0, WS_POPUP|WS_VISIBLE|WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0) );&lt;br /&gt;   SetPixelFormat ( hDC, ChoosePixelFormat ( hDC, &amp;pfd) , &amp;pfd );&lt;br /&gt;   wglMakeCurrent ( hDC, wglCreateContext(hDC) );&lt;br /&gt;   ShowCursor(FALSE); &lt;br /&gt;   do {&lt;br /&gt;        // insert breakpoint winning 1k here&lt;br /&gt;        // pohar insert breakpoint winning 5k :-)&lt;br /&gt;         SwapBuffers(hDC);&lt;br /&gt;    } while ( !GetAsyncKeyState(VK_ESCAPE) );   &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-6822048159801179605?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/6822048159801179605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/tiny-opengl-windowing-code.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6822048159801179605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/6822048159801179605'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/tiny-opengl-windowing-code.html' title='Tiny OpenGL Windowing Code'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-8728187617286507717</id><published>2007-10-24T12:14:00.000+02:00</published><updated>2007-10-24T12:24:05.321+02:00</updated><title type='text'>Tiny code to Setup GLSL Shaders</title><content type='html'>I posted code some time ago on in4k to load GLSL shaders. The code was small but it could get smaller. Using crinkler 1.0a, this code is about 20 bytes smaller than before after compression. Not much, but enough for one more line of shader code.&lt;br /&gt;OpenGL still doesn't compete with DX at this level (1k) of shader coding but I noticed that loonies recently used the framework so I thought it was worth an update. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;static void setShaders(){&lt;br /&gt;GLuint p,s;&lt;br /&gt;  p = ((PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"))();&lt;br /&gt;  s = ((PFNGLCREATESHADERPROC)(wglGetProcAddress("glCreateShader")))(GL_VERTEX_SHADER);&lt;br /&gt;  ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &amp;vsh, NULL);&lt;br /&gt;  ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);&lt;br /&gt;  ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);&lt;br /&gt;&lt;br /&gt;  s = ((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_FRAGMENT_SHADER); &lt;br /&gt;  ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &amp;fsh, NULL);&lt;br /&gt;  ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);&lt;br /&gt;  ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);&lt;br /&gt;   &lt;br /&gt;  ((PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"))(p);&lt;br /&gt;  ((PFNGLUSEPROGRAMPROC) wglGetProcAddress("glUseProgram"))(p);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-8728187617286507717?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/8728187617286507717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/tiny-code-to-setup-glsl-shaders.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8728187617286507717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8728187617286507717'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/tiny-code-to-setup-glsl-shaders.html' title='Tiny code to Setup GLSL Shaders'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2464356774090786065</id><published>2007-10-17T13:03:00.000+02:00</published><updated>2007-10-17T13:47:44.919+02:00</updated><title type='text'>Real Time Ambient Occlusion of Spheres</title><content type='html'>Well, with SSAO (see article below), this trick is a little redundant. However, I'll put it here  for my own records as much as anything else.&lt;br /&gt;&lt;br /&gt;I was looking for a trick to squeeze ambient occlusion in real time into 1k. It turns out that the occlusion of a sphere on another sphere can be calculated analytically. Similarly a sphere and plane can occlude each other and the result is analytic. This means it can be calculated using a simple equation for every pixel on the screen.&lt;br /&gt;&lt;br /&gt;Fine, so a fragment shader would do?&lt;br /&gt;Yes. And no. I couldnt get it to below 1k. 4k yes, but 1k no. So I started to examine the equations. To my amazement, traditional OpenGL lighting can be set up to model ambient occlusion of spheres on spheres and planes on spheres!&lt;br /&gt;&lt;br /&gt;Inside each sphere we place a dark light, a light with negative colour! This is a point light source. Then we set the light attenuation, how the light fades with respect to distance, to exactly that required by the ambient occlusion equations. Lastly we assume all spheres have radius of 1, which simplifies the setup and equations.&lt;br /&gt;&lt;br /&gt;Now draw all the spheres cast darkness onto each other correctly. Oh one trick to watch for is to switch off the light inside a sphere when drawing that sphere - a sphere does not occlude itself.&lt;br /&gt;&lt;br /&gt;Here is the image:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/RxXvRO_dL7I/AAAAAAAAABo/KT8DG5mvIe0/s1600-h/ao.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/RxXvRO_dL7I/AAAAAAAAABo/KT8DG5mvIe0/s200/ao.jpg" alt="" id="BLOGGER_PHOTO_ID_5122263230564872114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Not bad. Notice all the shadows. We need one light per sphere and OpenGL allows us 8 lights so we can have 8 spheres. The spheres can also occlude a plane:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/RxXv5u_dL8I/AAAAAAAAABw/KmVac8r3WYw/s1600-h/shot_36.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_xl45__0O0dM/RxXv5u_dL8I/AAAAAAAAABw/KmVac8r3WYw/s200/shot_36.jpg" alt="" id="BLOGGER_PHOTO_ID_5122263926349574082" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Lastly, the plane can also occlude the spheres. This is trickier. In essence one light source is used for the plane and as each sphere is drawn,  this light source is moved onto the plane directly under the sphere. I used a point light source which is incorrect (the plane is infinite and requires a directional light but this is not then attenuated correctly). Here is the final result:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/RxXwye_dL9I/AAAAAAAAAB4/FLGJwTRZ25c/s1600-h/shot_37.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_xl45__0O0dM/RxXwye_dL9I/AAAAAAAAAB4/FLGJwTRZ25c/s200/shot_37.jpg" alt="" id="BLOGGER_PHOTO_ID_5122264901307150290" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Notice the dark patches at the bottom of spheres now from the plane below them. Lastly here is an image where I've used the technique for real. The image was created for Rebels demogroup, but I dont think they will use it. M:ET gave permission to use the Rebels logo here, originally by H2O. The background image is a greeble image created by alien^pdx. I used two passes, the first to draw ambient occlusion, the second to draw the glossy surface. It could be done in one pass, but really 7 or 8 spheres are not hard for PCs now.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/RxXx5-_dL-I/AAAAAAAAACA/g_VLCsMH538/s1600-h/aoballs.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_xl45__0O0dM/RxXx5-_dL-I/AAAAAAAAACA/g_VLCsMH538/s200/aoballs.jpg" alt="" id="BLOGGER_PHOTO_ID_5122266129667796962" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(&lt;span style="font-weight: bold;"&gt;Click any image to see a larger version&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;Finally some code to implement the dynamic sphere occlusion...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;const float white[] = { 0.75, 0.75, 0.75, 1 };&lt;br /&gt;const float black[] = { 0, 0, 0, 1 }; //doubles as position of lights&lt;br /&gt;const float darklight[] = { -2.0f, -2.0f, -2.0f, 2.0f };&lt;br /&gt;&lt;br /&gt;void drawAOSpheres(){&lt;br /&gt;int i;&lt;br /&gt;&lt;br /&gt;  // we skip the first light as this has its own initial rules&lt;br /&gt;  // by ignoring it, the code gets smaller...half size infact&lt;br /&gt;   glDisable(GL_LIGHT0);&lt;br /&gt;   // everything in the scene will receive white ambient light&lt;br /&gt;   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, white);&lt;br /&gt;   // set the lights in position and switch them on&lt;br /&gt;   for (i=1; i &lt; 8; i++) {&lt;br /&gt;        moveSphere(i);&lt;br /&gt;        // lights are set with NEGATIVE colour!&lt;br /&gt;        glLightfv(GL_LIGHT0+i,GL_DIFFUSE,darklight);&lt;br /&gt;        // black is 0,0,0,1, which are the values we need for&lt;br /&gt;        // a point light at the origin.&lt;br /&gt;        glLightfv (GL_LIGHT0+i, GL_POSITION, black);&lt;br /&gt;        // a quadratic falloff of light power is needed&lt;br /&gt;        // attenuation is 1/(constant + linear*dist + quadratic*dist)&lt;br /&gt;        // we want 1,0,1, default is 1,0,0&lt;br /&gt;        glLightf(GL_LIGHT0+i, GL_QUADRATIC_ATTENUATION,  1.0f);&lt;br /&gt;        glEnable (GL_LIGHT0+i);  &lt;br /&gt;   }&lt;br /&gt;   // draw the spheres being careful not to draw a sphere occluding itself   &lt;br /&gt;   for (i=1; i &lt; 8; i++) {&lt;br /&gt;        //glColor4f (1.0f-(i/5.0f),0.7f+(i/20.0f),1.0f,1.0f);&lt;br /&gt;        // a sphere should not occlude itself so switch off its own light&lt;br /&gt;        glDisable (GL_LIGHT0+i);  &lt;br /&gt;        moveSphere(i);&lt;br /&gt;        mySphere(1,60); //gluSphere(q,1,60,60);&lt;br /&gt;        glEnable (GL_LIGHT0+i);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;13 lines of code and some constants!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2464356774090786065?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/2464356774090786065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/real-time-ambient-occlusion-of-spheres.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2464356774090786065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2464356774090786065'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/real-time-ambient-occlusion-of-spheres.html' title='Real Time Ambient Occlusion of Spheres'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/RxXvRO_dL7I/AAAAAAAAABo/KT8DG5mvIe0/s72-c/ao.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-8429160258501896327</id><published>2007-10-14T22:27:00.000+02:00</published><updated>2007-10-22T11:24:16.163+02:00</updated><title type='text'>Screen Space Shading</title><content type='html'>One new technique in size coding is screen space shading. The idea is to avoid lots of shader code or even host code and produce shading code purely in screen space in the fragment shader.&lt;br /&gt;&lt;br /&gt;For example, suppose we wish to do phong shading. Normally we would need to do the following:&lt;br /&gt;&lt;br /&gt;1. Submit vertex normals&lt;br /&gt;2. Write a vertex shader to output normals at vertices and the eye position&lt;br /&gt;3. Write a fragment shader to normalize these&lt;br /&gt;4. Calculate lighting&lt;br /&gt;&lt;br /&gt;Instead though, steps 1,2 and 3 can be avoided and the normal recovered just from the pixels in the screen. GLSL offers a couple of functions dFdx and dFdy. These tend to work on cards supporting PS3.0 and later. In essence they give us the rate of change of a value across pixels. So recovering a normal in screen space can be written in GLSL as:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;vec3 n=normalize(vec3(dFdx(gl_FragCoord.z),dFdy(gl_FragCoord.z),1));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you are familiar with height maps and deriving normals, thats exactly this equation. There are issues with borders of objects which can result in a black border round the object, but this can also be exploited as a special effect.&lt;br /&gt;&lt;br /&gt;Another effect that can be done in screen space is Ambient Occlusion. Iq of rgba has published a few articles on this and the technique seems to have been first used by Crytek. Essentially, in the fragment shader, a number of points are generated around the surface normal in world space. These are samples for the AO. These are then projected into screen space again and their depths tested against the pixels they project to. If the point is further away in z, that sample is occluded. The results are summed as you might expect.&lt;br /&gt;&lt;br /&gt;Here is an image from &lt;a href="http://www.pouet.net/prod.php?which=32549"&gt;Kindernoiser by iq of rgba&lt;/a&gt; using this technique. It is amazing just how well it works! Its fast, dynamic and less code than traditional AO techniques.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/RxKBGO_dL6I/AAAAAAAAABg/IM5lPOqTgoI/s1600-h/32549.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_xl45__0O0dM/RxKBGO_dL6I/AAAAAAAAABg/IM5lPOqTgoI/s200/32549.jpg" alt="" id="BLOGGER_PHOTO_ID_5121297670377123746" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There are drawbacks of screen space shading. For example, take a sphere subdivided into a number of flat polygons. With standard normal interpolation the sphere will look smooth as the normal is interpolated across the pixels as if the surface is curved. In screen space, we have only local information so the flat surfaces still look flat. Nontheless advantages in size can be worth it.&lt;br /&gt;&lt;br /&gt;Slight update:&lt;br /&gt;Here are some more images of screen space (or image space) illumination. Quite extraordinary. I must get an image space renderer written.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gamedev.net/community/forums/topic.asp?topic_id=465715"&gt;http://www.gamedev.net/community/forums/topic.asp?topic_id=465715&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-8429160258501896327?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/8429160258501896327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/screen-space-shading.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8429160258501896327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/8429160258501896327'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/screen-space-shading.html' title='Screen Space Shading'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xl45__0O0dM/RxKBGO_dL6I/AAAAAAAAABg/IM5lPOqTgoI/s72-c/32549.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-2795534372622482846</id><published>2007-10-11T12:31:00.000+02:00</published><updated>2007-10-11T13:45:55.774+02:00</updated><title type='text'>Organic Art</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/Rw39hu_dL0I/AAAAAAAAAAs/RKdaa1lj46w/s1600-h/latham1.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_xl45__0O0dM/Rw39hu_dL0I/AAAAAAAAAAs/RKdaa1lj46w/s320/latham1.jpg" alt="" id="BLOGGER_PHOTO_ID_5120027107381817154" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/Rw39hu_dL1I/AAAAAAAAAA0/7dE5apg1_4k/s1600-h/latham2.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_xl45__0O0dM/Rw39hu_dL1I/AAAAAAAAAA0/7dE5apg1_4k/s320/latham2.jpg" alt="" id="BLOGGER_PHOTO_ID_5120027107381817170" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/Rw39hu_dL2I/AAAAAAAAAA8/33bELN0zsCQ/s1600-h/latham3.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_xl45__0O0dM/Rw39hu_dL2I/AAAAAAAAAA8/33bELN0zsCQ/s320/latham3.jpg" alt="" id="BLOGGER_PHOTO_ID_5120027107381817186" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Back at college I had a few heroes of computer graphics. One of them, Professor William Latham was creating fascinating organic art. &lt;span style="font-weight: bold;"&gt;The three images above are his work&lt;/span&gt; and are reproduced with permission. I strongly encourage you to see these images in higher resolution at Williams web site: &lt;a title="http://www.williamlatham1.com/" href="http://www.williamlatham1.com/"&gt;&lt;span title="http://www.williamlatham1.com/"  style="color:black;"&gt;&lt;span title="http://www.williamlatham1.com/"  style="color:#000000;"&gt;www.williamlatham1.com&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It recently occurred to me that such organic art may be possible in real time and in very few bytes using OpenGL. Whilst I can't hope to match the beauty of the images in very few bytes, I can get close in form.&lt;br /&gt;&lt;br /&gt;Here are some images I'm working on. Each image is taken from a real-time program which animates the structure in a more or less organic way.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/Rw4Gmu_dL5I/AAAAAAAAABU/CvtO85T0TwE/s1600-h/organic3.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://4.bp.blogspot.com/_xl45__0O0dM/Rw4Gmu_dL5I/AAAAAAAAABU/CvtO85T0TwE/s200/organic3.jpg" alt="" id="BLOGGER_PHOTO_ID_5120037088885813138" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/Rw4Gme_dL4I/AAAAAAAAABM/Vrh_t2PfjVk/s1600-h/organic2.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_xl45__0O0dM/Rw4Gme_dL4I/AAAAAAAAABM/Vrh_t2PfjVk/s200/organic2.jpg" alt="" id="BLOGGER_PHOTO_ID_5120037084590845826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/Rw4Gl-_dL3I/AAAAAAAAABE/OnGcNRu1Y6I/s1600-h/organic1.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/Rw4Gl-_dL3I/AAAAAAAAABE/OnGcNRu1Y6I/s200/organic1.jpg" alt="" id="BLOGGER_PHOTO_ID_5120037076000911218" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The structures above are mine. Aside fom the colours and lighting which needs work, I think the code is beginning to show promise. The "latham" routine to generate the shapes is &lt;span style="font-weight: bold;"&gt;less than 300 bytes&lt;/span&gt; after compression.&lt;br /&gt;&lt;br /&gt;The code is a recursive, iterative and randomised. I think there is loads of potential here.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void latham (uint32 depth, uint32 n, uint32 seed) {&lt;br /&gt;uint32 i;&lt;br /&gt;float s;&lt;br /&gt;&lt;br /&gt;#define OPENNESS 40.0f  // lower is more open&lt;br /&gt;#define SPACING  2.0f   // distance between generated points...higher, more&lt;br /&gt;#define TWISTINESS 10.0f // how weird the structure gets...lower, less&lt;br /&gt;   &lt;br /&gt;  if (depth==0) return;&lt;br /&gt;    for (i=0; i &lt; n; i++) {&lt;br /&gt;        mirand = seed;&lt;br /&gt;        s= my_sin(sfrand()*(seed+i)*0.04f);&lt;br /&gt;         glRotatef ( s*OPENNESS, s*sfrand(),s*sfrand(),s*sfrand() );&lt;br /&gt;        s= my_sin(s*TWISTINESS)*SPACING;&lt;br /&gt;        glTranslatef ( s*sfrand(), s*sfrand(), s*sfrand() );&lt;br /&gt;        if (i%(n/4)==0) {&lt;br /&gt;            glPushMatrix();&lt;br /&gt;            glScalef(0.5f,0.5f,0.5f);&lt;br /&gt;            latham (depth-1, n/2, seed+1);&lt;br /&gt;            glPopMatrix();&lt;br /&gt;        }&lt;br /&gt;        drawSphere(SPACING); // SPACING=radius of sphere&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;sfrand() is a function that returns a psuedo-random number between -1 and 1. Mirand is used to set the seed for random number generation. Dirty: but this is size coding. The code iterates applying a random (but repeatable by seed) rotation and translation and drawing a sphere. At a certain iteration, a new random seed is passed recursively into the function in order to draw "branches" off the main creature.&lt;br /&gt;&lt;br /&gt;I have removed the animation code here (which is tiny) but you can figure that out yourself.&lt;br /&gt;&lt;br /&gt;Overall, through fortuitous randomness we can come close to resembling Lathams structures and animate them in real time. Now if only I had some artistic ability I could light them and colour them better!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-2795534372622482846?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/2795534372622482846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/organic-art.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2795534372622482846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/2795534372622482846'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/organic-art.html' title='Organic Art'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_xl45__0O0dM/Rw39hu_dL0I/AAAAAAAAAAs/RKdaa1lj46w/s72-c/latham1.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-1882810035119086779</id><published>2007-10-10T15:56:00.000+02:00</published><updated>2007-10-11T10:05:04.979+02:00</updated><title type='text'>Tiny Distortion Shader</title><content type='html'>Whilst working on Spheres Dream, Pasy of Rebels gave me some code for a distortion shader. I used it to quite good effect but completely size reduced and rewritten. I'll present my distortion shader here but first what is a distortion shader? Well, imagine a lens floating infront of your graphics, it would distort the image behind. To do this in OpenGL we would:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Draw the image to be distorted to an offscreen buffer&lt;/li&gt;&lt;li&gt;Capture this to texture (see NPOT article)&lt;/li&gt;&lt;li&gt;Clear the screen&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Enable a lens distortion shader&lt;/li&gt;&lt;li&gt;Draw a textured quad&lt;/li&gt;&lt;/ul&gt;The shader would distort the texture co-ordinates as if looking through a lens. Easy. However the lens can be highly complex, have a bumpy surface or even be a second texture.&lt;br /&gt;&lt;br /&gt;The first image is a very flat image before distortion. The second image is applying a distortion shader and adds complexity and interest to the image.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/Rwzb0e_dLyI/AAAAAAAAAAc/V8MF26NGtR4/s1600-h/nodistort.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_xl45__0O0dM/Rwzb0e_dLyI/AAAAAAAAAAc/V8MF26NGtR4/s320/nodistort.jpg" alt="" id="BLOGGER_PHOTO_ID_5119708571132309282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/RwzcPu_dLzI/AAAAAAAAAAk/wr6Y-gfkzCA/s1600-h/distort.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_xl45__0O0dM/RwzcPu_dLzI/AAAAAAAAAAk/wr6Y-gfkzCA/s320/distort.jpg" alt="" id="BLOGGER_PHOTO_ID_5119709039283744562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I did not want to use a second texture to distort the image. Instead I used a simple trick. The image is drawn and the distort is calculated from the orginal image alone. Infact the distortion is a function of colour in the original image.&lt;br /&gt;&lt;br /&gt;Here is the vertex shader:&lt;span style="color: rgb(0, 153, 0);font-size:100%;" &gt;&lt;br /&gt;&lt;pre&gt;const char *vsh="varying vec4 p;\&lt;br /&gt;void main(){\&lt;br /&gt;gl_Position=ftransform();\&lt;br /&gt;p=ftransform();\&lt;br /&gt;}";&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;So p is set to the co-ordinate of the transformed vertex. Which ranges between -1 and 1 in my screen space.&lt;br /&gt;&lt;br /&gt;Here is the fragment shader:&lt;span style="color: rgb(0, 153, 0);font-size:100%;" &gt;&lt;br /&gt;&lt;pre&gt;const char *distortScreenfsh="\&lt;br /&gt;uniform sampler2D s;\&lt;br /&gt;varying vec4 p;\&lt;br /&gt;void main(){\&lt;br /&gt;vec4 t=p/2.0+0.5;\&lt;br /&gt;float d=length(texture2D(s,t.xy).xyz);\&lt;br /&gt;gl_FragColor=texture2D(s,t.xy+d*p.xy*0.3);\&lt;br /&gt;}";&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;So t maps to between 0..1 and corresponds exactly to (0,0) in one corner of the screen and (1,1) in the opposite corner. This avoids having to  define texture co-ordinates in the main OpenGL code and also, infact means one big trick. In the main code now we can use a gluDisk rather than define a real quad!  This is far fewer bytes. If I had tried to use real texture co-ordinates in the shader I couldn't use a Disk as the texture co-ordinates would be wrong.&lt;br /&gt;&lt;br /&gt;The real magic then is here:&lt;span style="color: rgb(0, 153, 0);font-size:100%;" &gt;&lt;br /&gt;&lt;pre&gt;float d=length(texture2D(s,t.xy).rgb);\&lt;br /&gt;gl_FragColor=texture2D(s,t.xy+d*p.xy*0.3);\&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;We do a texture lookup in the original image using t as the texture co-ordinates. We read the rgb values and then take the length of this as a vector. So somehow d is a measure of the intensity of colour in the original image.&lt;br /&gt;&lt;br /&gt;Then we finally do a texture lookup in the original image, adjusted by d and p. This is the distort right here (+d*p.xy*0.3).&lt;br /&gt;&lt;br /&gt;The shader is tiny and produces a much richer feel to the image.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-1882810035119086779?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/1882810035119086779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/tiny-distortion-shader.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1882810035119086779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1882810035119086779'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/tiny-distortion-shader.html' title='Tiny Distortion Shader'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xl45__0O0dM/Rwzb0e_dLyI/AAAAAAAAAAc/V8MF26NGtR4/s72-c/nodistort.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-5509933179119237077</id><published>2007-10-09T07:01:00.000+02:00</published><updated>2007-10-10T13:55:18.288+02:00</updated><title type='text'>Quick NPOTs</title><content type='html'>Most cards today support Non Power of Two Textures (NPOTS). In the old days textures had to be 64x32 or 256x512 or some such but screen resolutions are typically 800x600 or 1024x768 - non power of two. I know my card (x600) supports NPOTs but I had trouble getting them to work fast so I guess others may too. I wanted to&lt;br /&gt;&lt;ul&gt;&lt;li&gt;render the scene to the back buffer (800x600)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;copy into a texture (also 800x600)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use the texture in a distortion shader&lt;/li&gt;&lt;/ul&gt;The third step could be anything of course. The key is I needed this in real time.  The problem is although NPOTs are supported on cards, they can be incredibly slow. The trick is setting them up correctly. First here is the code to read the screen and copy it into a texture:&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);font-size:100%;" &gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void grabScreen(unsigned int tnum, GLubyte *p){&lt;br /&gt;  createTexture(tnum,p);&lt;br /&gt;  glCopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, 0,0,800,600,0);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;So I call a function to create a texture and then copy the whole back buffer into it. Nothing surprising here, its here for completeness. The real trick comes in the &lt;span style="color: rgb(0, 153, 0);"&gt;createTexture()&lt;/span&gt; routine. Here is where you can foul up pretty easily.&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);font-size:100%;" &gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void createTexture (unsigned int tnum, GLubyte *p) {&lt;br /&gt;   glBindTexture (GL_TEXTURE_2D, tnum);&lt;br /&gt;   //commenting out any of these means it runs slow as hell&lt;br /&gt;   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);&lt;br /&gt;   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);&lt;br /&gt;   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);&lt;br /&gt;   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);&lt;br /&gt;   glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,800,600,0,GL_RGB,GL_UNSIGNED_BYTE,p);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;You can see the whole trick is explicitly telling OpenGL that it never needs to worry about wrapping of texels across the border. Instead, explicitly clamp the edge of the texture. Its obvious why if you think about it. If the texture wrapped, a modulo maths step is required to find the right texel. For powers of two this is a mask and a shift but is far more complex for non-power of two.&lt;br /&gt;&lt;br /&gt;So now its possible to capture the whole screen at real-time rates and use that for...next article.&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 204);font-size:78%;" &gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-5509933179119237077?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/5509933179119237077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/quick-npots.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5509933179119237077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/5509933179119237077'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/quick-npots.html' title='Quick NPOTs'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4124421301687405748.post-1929396158981826525</id><published>2007-10-08T17:37:00.001+02:00</published><updated>2007-10-17T16:22:36.406+02:00</updated><title type='text'>The Beginning</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/RwpPwu_dLwI/AAAAAAAAAAM/ZFMaJQdSTUI/s1600-h/32225.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_xl45__0O0dM/RwpPwu_dLwI/AAAAAAAAAAM/ZFMaJQdSTUI/s320/32225.jpg" alt="" id="BLOGGER_PHOTO_ID_5118991625126489858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;A quick note to say this Blog is open for business. Over the coming months I'll be posting bizarre and obscure ideas for intro coding: super small graphics programs. The example image is from  "&lt;a href="http://www.pouet.net/prod.php?which=32225"&gt;Spheres Dream&lt;/a&gt;" which is just 4k ..4096 bytes. 4 scenes, music and synthesiser in 4k. It requires pixel shaders 2.0 and a fast graphics card (series 6 Nvidia or x600 onwards from ATi). The graphics are mine and the synth is by Pohar of the demogroup Rebels.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4124421301687405748-1929396158981826525?l=sizecoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sizecoding.blogspot.com/feeds/1929396158981826525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sizecoding.blogspot.com/2007/10/beginning.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1929396158981826525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4124421301687405748/posts/default/1929396158981826525'/><link rel='alternate' type='text/html' href='http://sizecoding.blogspot.com/2007/10/beginning.html' title='The Beginning'/><author><name>auld</name><uri>http://www.blogger.com/profile/16928804561853814668</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_xl45__0O0dM/RwpPwu_dLwI/AAAAAAAAAAM/ZFMaJQdSTUI/s72-c/32225.jpg' height='72' width='72'/><thr:total>1</thr:total></entry></feed>
