tag:blogger.com,1999:blog-41244213016874057482024-03-14T08:29:52.205+01:00Graphics Size CodingMore Graphics, less code.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comBlogger74125tag:blogger.com,1999:blog-4124421301687405748.post-61581854045197994282012-12-30T12:17:00.000+01:002012-12-30T12:17:07.760+01:00C64 Cool maze Generator (sort of)<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/m9joBLOZVEo?feature=player_embedded' frameborder='0'></iframe></div>
<br />
As demonstrated by Casey Reas at the Eyeo Festival, June 2011,
Minneapolis, Minnesota, a random maze generation program in one line of
Commodore 64 Basic. The program uses the PETSCII character set,
specifically the line character code of 205.5, plus a random occurrence
of 1 or 0, which alternates between the / and \ characters, and then
repeats without causing line breaks. This small program is shown running
inside of the Vice emulator on Ubuntu. The recording was made with glc
and compiz.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com0tag:blogger.com,1999:blog-4124421301687405748.post-69663219828415794442012-02-02T17:45:00.000+01:002012-02-02T17:45:02.667+01:00Point in Polygon.Sometimes size coding is about small powerful snippets of code. Few better examples exist than this <a href="http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html#The%20C%20Code">point in polygon code by Randolph Franklin</a>.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com0tag:blogger.com,1999:blog-4124421301687405748.post-73610092634066390382010-10-30T21:11:00.002+02:002010-10-30T21:12:49.627+02:00Qoob added to GeeXLab<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/_xl45__0O0dM/TMxt9JgYdKI/AAAAAAAAAP4/FenJy7vSWfs/s1600/qoobgeexlab.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://2.bp.blogspot.com/_xl45__0O0dM/TMxt9JgYdKI/AAAAAAAAAP4/FenJy7vSWfs/s400/qoobgeexlab.jpg" width="400" /></a></div>JeGX has added Qoob 1.0.2 support to his graphics quick prototyping tool GeeXLab.There is already a demo out. <a href="http://qoob.weebly.com/1/post/2010/10/geexlab-adds-qoob-support.html">More about Qoob in GeeXLab and how to download</a>.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com0tag:blogger.com,1999:blog-4124421301687405748.post-61242921469673529552010-10-25T23:34:00.001+02:002010-10-25T23:35:49.335+02:00Qoob added to ZGEVill Krumlinde has added Qoob 1.0.2 support to the <a href="http://www.zgameeditor.org/">ZGameEditor (ZGE)</a>. See the full details at the news section at the Qoob website as well as a link to the first ZGE demo containing qoob...<br />
<br />
<a href="http://qoob.weebly.com/news.html">http://qoob.weebly.com/news.html</a>auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com0tag:blogger.com,1999:blog-4124421301687405748.post-4911801993993418452010-10-24T00:31:00.001+02:002010-10-24T00:34:06.607+02:00Qoob libs Released and Modeller Upgraded<div class="separator" style="clear: both; text-align: center;"><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;"><img border="0" height="251" src="http://2.bp.blogspot.com/_xl45__0O0dM/TMNhejkusVI/AAAAAAAAAP0/Cpa6-W16jsg/s320/shot_125.jpg" width="320" /></a></div><br />
<br />
<br />
<br />
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.<br />
<br />
Check it out at<a href="http://www.blogger.com/goog_1716766997"> </a><a href="http://qoob.weebly.com/">http://qoob.weebly.com </a>auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com2tag:blogger.com,1999:blog-4124421301687405748.post-76673638390585482792010-10-16T11:18:00.002+02:002010-10-16T11:24:21.855+02:00Benoit Mandelbrot Dead<div class="separator" style="clear: both; text-align: center;"><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;"><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" /></a></div><div class="separator" style="clear: both; text-align: center;"><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;"><br />
</a></div><div style="text-align: center;">Rest in peace, sir.</div>auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com0tag:blogger.com,1999:blog-4124421301687405748.post-22537591208932818182010-10-15T09:01:00.008+02:002010-10-15T09:08:55.224+02:00Simple Code to Calculate normals for a Quad MeshI'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.<br />
<br />
Here is some tiny <b> pseudo-code</b> to calculate both the vertex and face normals of a mesh made of quads. It is pseudo-code because your mesh structure will not be the same as mine. The idea is based on<a href="http://www.iquilezles.org/www/material/breakpoint2007/bp2007.pdf"> iqs idea in his Breakpoint presentation.</a><br />
<blockquote><span style="font-size: x-small;"> <span style="font-size: small;">for ( i=0; i</span></span><span style="font-size: x-small;"><numberofquads; i++) {</span><br />
<span style="font-size: x-small;"><nmberofquads; ++)="" i=""><numberofquads; i++)="" {=""> for (uint k=0; k<4; k++) cross ( &quad[i].v[k], &quad[i].v[(k+1)&3], &facenormals[i] );<br />
for (uint k=0; k<4; k++) add ( &facenormals[i], &vertexnormals[&quad[i].v[k]]);<br />
}</numberofquads;></nmberofquads;></span></blockquote>Now this neat and easy to read and incredibly small for such power. Essentially it is:<br />
<blockquote>for each quad<br />
for each edge in quad<br />
accumulate crossproduct of edge vertices into face normal<br />
for each vertex in quad<br />
add face normal </blockquote><br />
One subtle trick here in the code is that <b>cross product is redefined</b> thus:<br />
cross(v1,v2,v3) :: v3 = v3 + crossproduct (v1,v2)<br />
Add is as you expect:: <br />
add(v1,v2):: v2=v2+v1;<br />
<br />
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.<br />
<br />
N.B.: Assumes facenormals and vertexnormals contain zero values before calling this function.<br />
The normals are not normalised (leave that to shaders or GL_NORMALIZE).auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com1tag:blogger.com,1999:blog-4124421301687405748.post-56242454058689288092010-10-15T08:29:00.001+02:002010-10-20T16:06:17.103+02:00Qoob moved to its own websiteSo that this blog can get back to non-qoob stuff, qoob has been moved to <a href="http://qoob.weebly.com/">http://qoob.weebly.com</a><br />
The whole package including .h and .o to link against will be out (this weekend) ermm not quite.. real soon now.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com0tag:blogger.com,1999:blog-4124421301687405748.post-72923598826241414642010-10-03T16:18:00.001+02:002010-10-03T16:27:24.394+02:00Qoob (OpenGL version) final results<div class="separator" style="clear: both; text-align: center;"><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;"><img border="0" height="200" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiLyx80I0I/AAAAAAAAAOM/vI7xXg0nhH4/s200/shot_129.jpg" width="158" /></a><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;"><img border="0" height="151" src="http://3.bp.blogspot.com/_xl45__0O0dM/TKiL02aSPrI/AAAAAAAAAOU/Eu7mQxSZW5c/s200/shot_73.jpg" width="200" /></a></div><div class="separator" style="clear: both; text-align: center;"><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;"><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" /></a></div><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><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;"><img border="0" height="157" src="http://4.bp.blogspot.com/_xl45__0O0dM/TKiL2X9JYeI/AAAAAAAAAOY/dsABNAODJrw/s200/shot_81.jpg" width="200" /></a><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;"><img border="0" height="146" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL3lOlkrI/AAAAAAAAAOc/xYhTE9ZlFLo/s200/shot_84.jpg" width="200" /></a><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;"><img border="0" height="214" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL4-CgtUI/AAAAAAAAAOg/C53OdNKoRgE/s400/shot_91.jpg" width="400" /></a></div><br />
<br />
<div class="separator" style="clear: both; text-align: center;"></div><br />
<div class="separator" style="clear: both; text-align: center;"><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;"><img border="0" height="200" src="http://4.bp.blogspot.com/_xl45__0O0dM/TKiL5g6CLTI/AAAAAAAAAOk/ZV8GhUDn8h4/s200/shot_93.jpg" width="138" /></a><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;"><img border="0" height="200" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL6TMOWpI/AAAAAAAAAOs/V-B93ZvAS5Q/s200/shot_99.jpg" width="176" /></a></div><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><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;"><img border="0" height="156" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL7ItRAeI/AAAAAAAAAOw/FCM3RpNjPHc/s200/shot_100.jpg" width="200" /></a><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;"><img border="0" height="156" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL8tulu0I/AAAAAAAAAO4/LeUf19yFnDQ/s200/shot_107.jpg" width="200" /></a><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;"><img border="0" height="156" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL8OooYxI/AAAAAAAAAO0/Or88wN4spuQ/s200/shot_101.jpg" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"></div><br />
<div class="separator" style="clear: both; text-align: center;"></div><br />
<div class="separator" style="clear: both; text-align: center;"><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;"><img border="0" height="149" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL9aRUpAI/AAAAAAAAAO8/HXegFfX-3Fg/s200/shot_112.jpg" width="200" /></a><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;"><img border="0" height="156" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiMcPs_UWI/AAAAAAAAAPc/dakGn2EolwY/s200/shot_103.jpg" width="200" /></a><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;"><img border="0" height="251" src="http://3.bp.blogspot.com/_xl45__0O0dM/TKiL-IgA3JI/AAAAAAAAAPE/SHvxKND-944/s320/shot_121.jpg" width="320" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><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;"><img border="0" height="320" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL9pKUzMI/AAAAAAAAAPA/GracGlDYS6E/s320/shot_120.jpg" width="230" /></a><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;"><img border="0" height="320" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiMchHuIuI/AAAAAAAAAPg/FksMSwGnRRQ/s320/shot_95.jpg" width="130" /></a></div><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><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;"><img border="0" height="175" src="http://2.bp.blogspot.com/_xl45__0O0dM/TKiL_AWDOMI/AAAAAAAAAPM/9n2k2TOZt9U/s200/shot_124.jpg" width="200" /></a><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;"><img border="0" height="200" src="http://4.bp.blogspot.com/_xl45__0O0dM/TKiMAkuGoSI/AAAAAAAAAPY/JWwZHPr8Ujc/s200/shot_128.jpg" width="198" /></a><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;"><img border="0" height="200" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiL-p7ragI/AAAAAAAAAPI/Wn2d5ed529o/s200/shot_123.jpg" width="198" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><br />
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.<br />
<br />
The final size using crinkler 1.1 with settings : <br />
<span style="font-size: x-small;">/CRINKLER /COMPMODE:SLOW /ORDERTRIES:3000 /UNSAFEIMPORT /REPORT:report.html /TRANSFORM:CALLS </span><br />
is <b>2165 bytes</b>.<br />
<br />
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.<br />
<br />
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.<br />
<br />
If you want to play with the qoob modeller (opengl), send me an email on my gmail account chris <dot> thornborrow and I'll release it to you. Especially if you are a 3d modeller used to wings3d - I'd like feedback.</dot><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_xl45__0O0dM/TKiSwuXPs7I/AAAAAAAAAPo/36dyScXuO4U/s1600/ghead.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="287" src="http://1.bp.blogspot.com/_xl45__0O0dM/TKiSwuXPs7I/AAAAAAAAAPo/36dyScXuO4U/s320/ghead.jpg" width="320" /></a></div>auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com6tag:blogger.com,1999:blog-4124421301687405748.post-50891521495449809782010-08-11T00:29:00.001+02:002010-08-11T00:29:52.106+02:003d Modelling : the challenges for CompressionQuick 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: <br />
<ol><li>The size of the qoob library with the modelling commands code</li>
<li>Storing modelling commands in a compact way</li>
<li>Picking and selection compression</li>
</ol><b>The Size of the Library</b><br />
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:<br />
<ul><li>use DX maths and subdivision</li>
<li> reduce the modelling options and target abstract objects ONLY</li>
<li>use default values for all functions so storing a model means storing only a series of commands - no parameters.</li>
</ul>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!<br />
<br />
<b>Storing Modelling Commands</b><br />
<br />
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<b> </b>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.<br />
<br />
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.<br />
<b><br />
</b><br />
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.<b></b><br />
<b><br />
</b><br />
<b>Selection Compression</b><br />
<br />
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.<br />
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.<br />
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.<br />
<br />
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.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-53595268780371215002010-08-09T12:17:00.000+02:002010-08-09T12:17:04.528+02:00Simple Algebraic Surfaces ReferenceSerious 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:<br />
<br />
<a href="http://www.freigeist.cc/gallery.html">http://www.freigeist.cc/gallery.html</a>auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-69305056764143089952010-07-19T23:49:00.007+02:002010-07-20T08:09:58.144+02:00Qoob Matures<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/TETJkjbYmsI/AAAAAAAAANs/F81p2TvPtms/s1600/shot_84.jpg"><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" /></a><br /><br />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. <br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TETJY3D12zI/AAAAAAAAANk/EHIMBU6-27c/s1600/shot_83.jpg"><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" /></a><br /><br />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.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TETKIRbTAyI/AAAAAAAAAN0/tRH1NFeMcBg/s1600/shot_90.jpg"><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" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TETKb7po_oI/AAAAAAAAAN8/pJL0gFmzYtI/s1600/shot_91.jpg"><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" /></a><br /><br />But a burning question is - how big is the Qoob library? Whats the overhead?<br />Here is a test I performed.<br />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 <2k is the Qoob overhead. <br /><br />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. <br /><br />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.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-35858280040349686482010-07-19T14:54:00.005+02:002010-07-19T15:02:18.606+02:00Shorter code for Point in IntervalNice 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.<br /><a href="http://www.strchr.com/checking_if_point_belongs_to_interval"><br />Neat trick</a><br /><br />It resolves down to this macro:<br /><br />#define InRange(ch, a, b) (unsigned((ch) - (a)) <= (b) - (a))<br /><br />.coolauldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-732270505733444182010-07-18T14:34:00.004+02:002010-07-18T15:00:30.669+02:00Qoob Character modelling<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/TEL2zq8Cd5I/AAAAAAAAANc/gOVwkXJMNI0/s1600/shot_89.jpg"><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" /></a><br />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.<br /><br />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.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TEL11Cq14eI/AAAAAAAAANU/MlvKPnS0GhI/s1600/character.jpg"><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" /></a><br /><br />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:<br />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.<br />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.<br />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.<br />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.<br />5. Restrict picking to be pick + grow pick. This would help with large groups of polys but the modeller would go nuts.<br /><br />... hmm need to think more, none of the above convince me.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-59099348323317732612010-07-10T09:51:00.007+02:002010-07-10T12:22:43.277+02:003d Modelling thoughts.<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TDhJ5UquXTI/AAAAAAAAANM/lXhBUKWtZkI/s1600/shot_82.jpg"><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" /></a><br /><span style="font-size:85%;"><span style="font-size:100%;">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 <a href="http://pouet.net/prod.php?which=25850">benetoite</a> and, more impressively, 64ks such as <a href="http://pouet.net/prod.php?which=18340">Flight666</a>. The maths for modelling with arbitrary extrusions is quite large (>500 bytes) and adds a lot of bytes to Qoob which is already growing in size.<br /><br />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:<br />select p1<br />select p2<br />select p3<br />... 50 selections<br />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.<br /><br />Size wise then, I'm struggling now: selections and extrusions add lots of bytes. ONe to the lib and one to the models. <span style="font-weight:bold;">Suggestions are welcome.</span><br /><br />However, on the bright side, Qoob <span style="font-weight:bold;">could</span> 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. <br /><br />In the mean time, some screenies of what can be done without such functions:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TDgqhSeLP1I/AAAAAAAAAM0/kLn_1FbFuDI/s1600/shot_79.jpg"><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" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/TDgq2b6okxI/AAAAAAAAAM8/6k7ki5X4Cew/s1600/shot_80.jpg"><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" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/TDgrHKDJ36I/AAAAAAAAANE/lF6__Ce1tRk/s1600/shot_81.jpg"><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" /></a><br /><br /></span><br />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 <a href="http://pouet.net/prod.php?which=52938">elevated</a> races toward 500 thumbs on Pouet. </span>auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-75089490634603779152010-07-06T11:32:00.008+02:002010-07-07T18:33:07.335+02:00Catmull Clark Subdivision Musings<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TDL6e9hn-OI/AAAAAAAAAMM/mjiT6LqEr5I/s1600/125539461.jpg"><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" /></a><br /><span style="font-size:85%;"><span style="font-weight: bold;">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.</span></span><br /><br />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.<br /><br />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, <a href="http://www.iquilezles.org/www/material/breakpoint2007/bp2007.pdf">Tricks and techniques for RGBAs Past and Future Intros</a>.<br /><br /><span style="font-size:78%;">(By the way his normal a mesh trick in that presentation is without doubt the best piece of size coding I've seen.</span>)<br /><br />Firstly <a href="http://en.wikipedia.org/wiki/Catmull%E2%80%93Clark_subdivision_surface">wikipedia has a description of the algorithm. </a>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 :-).<br /><br />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.<br /><pre><br /><span style="font-size:78%;">Vert disp[MAXSIZE]; // displacements<br />uint val[MAXSIZE]; // valences<br /><br />void subdObj (Object *ob, uint smooth) {<br />Vert tmp,ep,fp;<br />uint eid[4],cni; //indices for new vertices, edges and centre<br />uint onq = ob->nq;<br />uint onv = ob->nv;<br /><br />ZeroMemory(disp,MAXSIZE*sizeof(Vert));<br />ZeroMemory(val,MAXSIZE*sizeof(uint));<br />for (uint iq=0; iq < onq; iq++ ) {<br /> centroid (ob, iq, &fp); <br /> cni=addVert(ob,&fp); <br /> for (uint v=0; v<4; v++ ) { // for each vertex in each quad quad<br /> lerp(&(QV(ob,iq,v)), &(QV(ob,iq,(v 1)&3)), 0.5f, &ep); <br /> copy(&ep,&tmp); <br /> if (smooth) smul(&tmp,0.5f); <br /> eid[v]=addVert(ob,&tmp); // orignal vertices of edge/4.0 <br /> // add contrib of face points to displacement for new edge points <br /> smadd (&fp,0.25f, &(disp[eid[v]]), &(disp[eid[v]]) ); // add fp/4 to edge vector <br /> // add face points to displacement for original point<br /> add (&fp, &(disp[ob->q[iq][v]]),&(disp[ob->q[iq][v]]) );<br /> // add 2x edge points to disp for original points<br /> smadd (&ep, 2.0f, &(disp[ob->q[iq][v]]),&(disp[ob->q[iq][v]]) );<br /> val[ob->q[iq][v]] ; // add up valences<br /> }<br /> // now construct four new quads<br />for (uint k=0;k<4;k++ ) addQuad (ob, ob->q[iq][k], eid[k], cni, eid[(k-1)&3], selected(iq));<br />}<br />// now displace all vertices...face points will be unaffected<br />if (smooth) for (uint v=0; v <q->nv; v++ ) {<br /> if (v < onv) { // this must be an original point <br /> smul (&(disp[v]), 1.0f/val[v]); // average the displacement values <br /> smadd (&(ob->v[v]), val[v]-3.0f, &(disp[v]), &(ob->v[v]) ); // correct for extraordinary vertex<br /> smul (&(ob->v[v]), 1.0f/val[v]); // divide through by valence<br /> } else add (&(ob->v[v]), &(disp[v]), &(ob->v[v]));<br />}<br />for (uint iq=0; iq<onq; iq++ ) delQuad(ob,0);<br />}</span><br /></pre><br />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.<br /><br />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.<br /><br />Coding style sucks. Happy with result so thought I'd publish it.<br /><br />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.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-52608176622332056352010-07-01T01:42:00.003+02:002010-07-01T01:46:12.456+02:00Qoob ProgressingMy modeller is progressing. Heres a screen shot:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xl45__0O0dM/TCvWqusTbWI/AAAAAAAAAME/boNqBRklOsY/s1600/shot_76.jpg"><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" /></a><br /><br />The model in the picture takes about 30 bytes to store. Smoothing is next up.<br />Organic stuff is escaping me right now but I'll work on that.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-35313896914620208612010-06-30T00:00:00.009+02:002010-06-30T13:25:23.975+02:00stupid idea 247: worlds smallest vector maths libraryHere is a tiny 3d vector maths library:<br /><pre><span style=";font-family:verdana;font-size:85%;" ><span style="font-family:courier new;">typedef float vec3[3];</span></span><span style=";font-family:verdana;font-size:85%;" ><br />vec3 *vec(vec3 *v, float x) {v[0]=v[1]=v[2]=x;return v;}</span><span style=";font-family:verdana;font-size:85%;" ><br />float *mav(vec3 *v1,vec3 *v2,vec3 *v3,vec3 *v4,vec3 *v5){</span><span style="font-size:85%;"><br /><span style="font-family:courier new;"> <span style="font-family:verdana;"> for (int i=0; i!=3; i++) v3[i]=v1[i]*v4[i]+v2[i]*v5[i];</span></span></span><span style=";font-family:verdana;font-size:85%;" ><br /> return v3[0]+v3[1]+v3[2];</span><span style=";font-family:verdana;font-size:85%;" ><br />}</span><span style="font-size:78%;"><span style="font-family:verdana;"><span style=";font-family:verdana;font-size:85%;" ><br />vec3 VZERO={0,0,0};</span><span style=";font-family:verdana;font-size:85%;" > vec3 VONE={1,1,1};</span><span style=";font-family:verdana;font-size:85%;" > vec3 VMONE={-1,-1,-1};</span><span style="font-family:verdana;"><br /></span></span></span><br /></pre><span style="font-size:100%;"><span style="font-family:arial;">Thats it. It can do zero, set, add, sub, length2, dotprod, negate, lerp, centroid. e.g add is :</span><br /><span style="font-family:arial;">mav(&v1, &v2, &v3, &VONE, &VONE ); // v3=v2+v1</span><br /><br />Lerp means that centroid (the centre vertex of a quad) can be found without a division by using two lerps.<span style="font-family:arial;"> For a moment it seems cool until you realise the calls to it dont compress all that well.</span><br /><span style="font-family:arial;">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.<br /></span></span>auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-68600552690809728532010-06-16T18:03:00.001+02:002010-06-16T18:04:56.867+02:00Very .cool<a href="http://www.ctrl-alt-test.fr/?page_id=7">GLSL Minifier.</a><br /><br />"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."<br /><br />Very .coolauldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-80678533009982863622010-06-14T08:32:00.008+02:002010-06-14T09:29:31.489+02:003d modelling for Intros ? qoob.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.<br /><br />This image fo a dragon was done using this technique and the result (with crinkler, shader, mesh and mesh code) was just over 2k...<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TBXV-VYNfcI/AAAAAAAAALk/05ezBsGoRXI/s1600/dragon.jpg"><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" /></a><br /><a href="http://www.pouet.net/topic.php?which=4679&page=1&x=22&y=11">Theres a good read about meshes in intros at Pouet.</a><br /><br />I once did a <a href="http://www.pouet.net/prod.php?which=31632">1k with several curved "lathe" objects</a>, 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 <span style="font-weight: bold;">models were just 8 bytes</span> 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.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/TBXSuuQj-jI/AAAAAAAAALc/iQOBBX-IMA0/s1600/shot_72.jpg"><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" /></a>But Lathes are limited.<br /><br />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.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xl45__0O0dM/TBXWumyf_cI/AAAAAAAAALs/Bla3OVZ7pd0/s1600/shot_3.jpg"><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" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xl45__0O0dM/TBXXKQeLMwI/AAAAAAAAAL0/2wFPWttILHs/s1600/organic3.jpg"><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" /></a><br /><br />You can see the last one live in the second half of the awesomely coloured :-) 4k intro <a href="http://pouet.net/prod.php?which=33677">Fruit of the Loop.</a><br /><br />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:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_xl45__0O0dM/TBXZrKmWgRI/AAAAAAAAAL8/Z9Rcp-syfl0/s1600/shot_71.jpg"><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" /></a><br /><br />The idea remains right though: this is the modelling equivalent of a texture builder.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-35149131284669536822009-11-05T00:46:00.004+01:002009-11-05T01:18:54.011+01:00FRequency To the Road of Ribbon in 1k for win32Instead of producing my own stuff, I've spent time crunching down the original <a href="http://www.pouet.net/prod.php?which=53939">Linux 1k from Frequency</a>. 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.<br /><br />During the crunching it became obvious I'd have to make a few compromises:<br /><ul><li>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.</li><li>Clock is less accurate and resets, causing a jump to a new viewpoint. This is not as good as the original.<br /></li><li>View angle is smaller - caused by a new method of calculating view vectors. Not a big issue.</li></ul>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.<br /><br />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.<br /><br /><span style="font-size:130%;"><a style="font-weight: bold;" href="http://scener.neostrada.pl/demos/FreqRtoRibbon1kwin32.zip">Here is the source code and an exe to try out</a></span>. 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!!<br /><br />Respect to FRequency from auld^titan.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-43523898500499936022009-11-01T09:56:00.005+01:002009-11-01T16:28:10.084+01:00Frequencies To The Road of Ribbon ReactivatedFrequency did a really great Linux 1k recently. <a href="http://www.pouet.net/prod.php?which=53939">To the Road of the Ribbon</a> 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.<br /><br />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? <a href="http://scener.neostrada.pl/Main.cpp">You can get my C version here</a>, with a much compressed shader. Its around 1070 bytes using crinkler.<br /><br />There are some nice tricks in this intro. I like the hi-res clock passed in through glColor4ubv:<br /><br />t=timeGetTime();<br />glColor4ubv((unsigned char *)(&t));<br /><br />and then in the shader (my version):<br /><br />float w=dot(vec3(gl_Color),vec3(256/256,256,256*256))*.256;<br /><br />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.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-20053056359472255562009-10-21T22:53:00.003+02:002009-10-21T22:56:14.437+02:00Bad intro yearI 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.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-69482607340858202862009-01-20T23:37:00.006+01:002009-01-20T23:51:51.673+01:00GLSL Shader Creation: Geometry, Vertex and FragmentTo 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.<br /><pre><br />GLuint ShaderCompile(const char *gs, const char *vs, const char *fs) {<br />GLuint p,s;<br /> p = ((PFNGLCREATEPROGRAMPROC)(wglGetProcAddress("glCreateProgram")))();<br /> if (gs!=NULL) { <br /> //if there is a geom shader...<br /> s=((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_GEOMETRY_SHADER_EXT);<br /> ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &gs, NULL);<br /> ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);<br /> ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);<br /> }<br /> if (vs!=NULL) { <br /> //if there is a vertex shader...<br /> s=((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_VERTEX_SHADER);<br /> ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &vs, NULL);<br /> ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);<br /> ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);<br /> }<br /> s=((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_FRAGMENT_SHADER); <br /> ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &fs, NULL);<br /> ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);<br /> ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);<br /> ((PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"))(p);<br /> return p;<br />}<br /></pre><br /><br />(I'll return to DirectX and OpenGL next post.)auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.comtag:blogger.com,1999:blog-4124421301687405748.post-1812117586593878762009-01-12T12:47:00.009+01:002009-01-13T18:28:02.971+01:00How to Use D3Dx and OpenGL together : Part 1I 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.<br /><br />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. <br /><br /><pre><br />LPDIRECT3D9 pD3D;<br />LPDIRECT3DDEVICE9 pd3dDevice;<br /><br />void initD3D(HWND hWnd) <br />{<br />D3DPRESENT_PARAMETERS d3dpp;<br /><br /> pD3D = Direct3DCreate9 (D3D_SDK_VERSION);<br /> d3dpp.Windowed = TRUE;<br /> d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;<br /> pD3D->CreateDevice( 0, D3DDEVTYPE_HAL, hWnd,<br /> D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice );<br />}<br /></pre><br />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.<br /><br />Now we need some code to initialise windows and opengl and use this routine to initialise D3D:<br /><br /><pre><br />static PIXELFORMATDESCRIPTOR pfd={<br />0, // Size Of PFD... BAD coding, saves bytes<br />1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 0, 0, 0, 0, 0, 0, <br />0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0 <br />};<br /><br />void WINAPI WinMainCRTStartup()<br />{<br /> HWND hWnd = CreateWindow( "EDIT", NULL, WS_POPUP|WS_VISIBLE|WS_MAXIMIZE, <br /> 0, 0, 0, 0, 0, 0, 0, 0 );<br /> initD3D(hWnd);<br /> HDC hDC = GetDC( hWnd );<br /> SetPixelFormat ( hDC, ChoosePixelFormat ( hDC, &pfd) , &pfd );<br /> wglMakeCurrent ( hDC, wglCreateContext (hDC) );<br /> ShowCursor(FALSE);<br /> .<br /> .<br />}<br /></pre><br />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.<br /><br />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.auldhttp://www.blogger.com/profile/16928804561853814668noreply@blogger.com