tag:www.rhnh.net,2008:/opengl
Opengl - Xavier Shay's Blog
2008-11-03T20:02:52Z
Enki
Xavier Shay
notreal@rhnh.net
tag:www.rhnh.net,2008:Post/788
2008-11-03T20:02:00Z
2008-11-03T20:02:52Z
Introducing SocialBeat (screencast)
<p>Here is a screencast of <a href="http://github.com/xaviershay/socialbeat/tree/master">socialbeat</a> in which you will note:</p>
<ol>
<li>I don’t appear drunk</li>
<li>I don’t reveal intra-company communications</li>
<li>I show off the full gamut of socialbeat’s awesomeness in under 3 minutes</li>
</ol>
<p>In these ways you may find it superior to other screencasts you may have seen on the matter.</p>
<object width="400" height="300"> <param name="allowfullscreen" value="true" /> <param name="allowscriptaccess" value="always" /> <param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=2139958&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" /> <embed src="http://vimeo.com/moogaloop.swf?clip_id=2139958&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object><br /><a href="http://vimeo.com/2139958?pg=embed&sec=2139958">Introducing SocialBeat</a>
<p>If you are behind the times – socialbeat is some code that lets you live code OpenGL visualizations to <span class="caps">MIDI</span> tracks.</p>
tag:www.rhnh.net,2008:Post/770
2006-04-20T23:43:00Z
2008-05-03T11:40:13Z
OpenGL Text with Imlib2
<p>Getting text into your openGL apps is simple with the use of the imlib2 library (developed by the <a href="http://www.enlightenment.org">enlightenment</a> team). If you have the good fortune of working on a debian system, the libraries are in apt:</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">sudo apt-get install libimlib2-ruby<tt>
</tt></pre></td>
</tr></table>
<p>The examples at the <a href="http://www.pablotron.org/software/imlib2-ruby/">ruby bindings webpage</a> show the basics of loading an image and writing text, all that remains is converting an Imlib2::Image into an OpenGL texture – just switch the data around from <span class="caps">BGRA</span> to <span class="caps">RGBA</span>…</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="r">class</span> <span class="cl">Imlib2::Image</span><tt>
</tt> <span class="c"># Convert data to format compatible with OpenGL</span><tt>
</tt> <span class="r">def</span> <span class="fu">rgba_data</span><tt>
</tt> new_data = <span class="co">Array</span>.new(data.size)<tt>
</tt> i = <span class="i">0</span><tt>
</tt> <span class="r">for</span> i <span class="r">in</span> (<span class="i">0</span>..data.size/<span class="i">4</span><span class="i">-1</span>)<tt>
</tt> new_data[i*<span class="i">4</span>] = data[i*<span class="i">4</span><span class="i">+2</span>] <tt>
</tt> new_data[i*<span class="i">4</span><span class="i">+1</span>] = data[i*<span class="i">4</span><span class="i">+1</span>]<tt>
</tt> new_data[i*<span class="i">4</span><span class="i">+2</span>] = data[i*<span class="i">4</span><span class="i">+0</span>]<tt>
</tt> new_data[i*<span class="i">4</span><span class="i">+3</span>] = data[i*<span class="i">4</span><span class="i">+3</span>]<tt>
</tt> <span class="r">end</span><tt>
</tt> <span class="r">return</span> new_data.pack(<span class="s"><span class="dl">'</span><span class="k">C*</span><span class="dl">'</span></span>)<tt>
</tt> <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></table>
<p>... and you can pass it straight into GL::TexImage2D. Follows is the <code>TextMananger</code> class I wrote tonight. Still haven’t quite mastered imlib2 – note the resize hack to get the correct format. If anyone has any suggestions I’m all ears.</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt>15<tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt>25<tt>
</tt>26<tt>
</tt>27<tt>
</tt>28<tt>
</tt>29<tt>
</tt><strong>30</strong><tt>
</tt>31<tt>
</tt>32<tt>
</tt>33<tt>
</tt>34<tt>
</tt>35<tt>
</tt>36<tt>
</tt>37<tt>
</tt>38<tt>
</tt>39<tt>
</tt><strong>40</strong><tt>
</tt>41<tt>
</tt>42<tt>
</tt>43<tt>
</tt>44<tt>
</tt>45<tt>
</tt>46<tt>
</tt>47<tt>
</tt>48<tt>
</tt>49<tt>
</tt><strong>50</strong><tt>
</tt>51<tt>
</tt>52<tt>
</tt>53<tt>
</tt>54<tt>
</tt>55<tt>
</tt>56<tt>
</tt>57<tt>
</tt>58<tt>
</tt>59<tt>
</tt><strong>60</strong><tt>
</tt>61<tt>
</tt>62<tt>
</tt>63<tt>
</tt>64<tt>
</tt>65<tt>
</tt>66<tt>
</tt>67<tt>
</tt>68<tt>
</tt>69<tt>
</tt><strong>70</strong><tt>
</tt>71<tt>
</tt>72<tt>
</tt>73<tt>
</tt>74<tt>
</tt>75<tt>
</tt>76<tt>
</tt>77<tt>
</tt>78<tt>
</tt>79<tt>
</tt><strong>80</strong><tt>
</tt>81<tt>
</tt>82<tt>
</tt>83<tt>
</tt>84<tt>
</tt>85<tt>
</tt>86<tt>
</tt>87<tt>
</tt>88<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">require <span class="s"><span class="dl">'</span><span class="k">imlib2</span><span class="dl">'</span></span><tt>
</tt> <tt>
</tt><span class="r">class</span> <span class="cl">OpenGLTextManager</span><tt>
</tt> <span class="r">def</span> <span class="fu">initialize</span><tt>
</tt> <span class="iv">@textures</span> = <span class="co">Hash</span>.new<tt>
</tt> <tt>
</tt> blank_filename = <span class="s"><span class="dl">'</span><span class="k">res/img/blank.png</span><span class="dl">'</span></span> <span class="c"># 1x1 png image</span><tt>
</tt> <span class="iv">@blank</span> = <span class="co">Imlib2</span>::<span class="co">Image</span>::load(blank_filename)<tt>
</tt> <tt>
</tt> <span class="c"># Probably better to copy the font locally and load it from there</span><tt>
</tt> <span class="co">Imlib2</span>::<span class="co">Font</span>::add_path <span class="s"><span class="dl">'</span><span class="k">/usr/share/fonts/truetype/ttf-bitstream-vera</span><span class="dl">'</span></span><tt>
</tt> fontname = <span class="s"><span class="dl">'</span><span class="k">Vera/10</span><span class="dl">'</span></span><tt>
</tt> <tt>
</tt> <span class="iv">@font</span> = <span class="co">Imlib2</span>::<span class="co">Font</span>.new(fontname)<tt>
</tt> <span class="r">end</span><tt>
</tt> <tt>
</tt> <span class="r">def</span> <span class="fu">render</span> text, x, y<tt>
</tt> texture = <span class="iv">@textures</span>[text]<tt>
</tt> texture = create_texture(text) <span class="r">if</span> texture == <span class="pc">nil</span><tt>
</tt> <tt>
</tt> <span class="c"># Draw a quad with the text texture</span><tt>
</tt> <span class="c"># Looks best with Ortho 1:1 projection</span><tt>
</tt> <span class="co">GL</span>::Enable(<span class="co">GL</span>::<span class="co">TEXTURE_2D</span>);<tt>
</tt> <span class="co">GL</span>::LoadIdentity();<tt>
</tt> <span class="co">GL</span>.BindTexture(<span class="co">GL</span>::<span class="co">TEXTURE_2D</span>, texture.ogl);<tt>
</tt> <span class="co">GL</span>::Begin(<span class="co">GL</span>::<span class="co">QUADS</span>);<tt>
</tt> <span class="co">GL</span>::TexCoord(<span class="fl">0.0</span>, <span class="fl">0.0</span>); <span class="co">GL</span>::Vertex(x, y)<tt>
</tt> <span class="co">GL</span>::TexCoord(<span class="fl">0.0</span>, <span class="fl">1.0</span>); <span class="co">GL</span>::Vertex(x, texture.height + y)<tt>
</tt> <span class="co">GL</span>::TexCoord(<span class="fl">1.0</span>, <span class="fl">1.0</span>); <span class="co">GL</span>::Vertex(texture.width + x, texture.height + y)<tt>
</tt> <span class="co">GL</span>::TexCoord(<span class="fl">1.0</span>, <span class="fl">0.0</span>); <span class="co">GL</span>::Vertex(texture.width + x, y)<tt>
</tt> <span class="co">GL</span>::End()<tt>
</tt> <span class="r">end</span><tt>
</tt> <tt>
</tt> <span class="r">def</span> <span class="fu">create_texture</span> text<tt>
</tt> fw, fh = <span class="iv">@font</span>.size(text)<tt>
</tt> <tt>
</tt> <span class="c"># This is a hack</span><tt>
</tt> <span class="c"># Image.new doesn't have the right color format (or something),</span><tt>
</tt> <span class="c"># so just resize a preloaded png</span><tt>
</tt> image = <span class="iv">@blank</span>.clone<tt>
</tt> image.crop_scaled! <span class="i">0</span>,<span class="i">0</span>,image.width, image.height, fw, fh<tt>
</tt> image.fill_rect [<span class="i">0</span>,<span class="i">0</span>], [image.w, image.h], <span class="co">Imlib2</span>::<span class="co">Color</span>::<span class="co">RgbaColor</span>.new(<span class="i">0</span>,<span class="i">0</span>,<span class="i">0</span>,<span class="i">255</span>)<tt>
</tt> <tt>
</tt> image.draw_text <span class="iv">@font</span>, text, <span class="i">0</span>, <span class="i">0</span>, <span class="co">Imlib2</span>::<span class="co">Color</span>::<span class="co">WHITE</span><tt>
</tt> <tt>
</tt> texture = <span class="co">TextTexture</span>.new<tt>
</tt> texture.ogl = <span class="co">GL</span>::GenTextures(<span class="i">1</span>)[<span class="i">0</span>];<tt>
</tt> <span class="co">GL</span>.BindTexture(<span class="co">GL</span>::<span class="co">TEXTURE_2D</span>, texture.ogl);<tt>
</tt> <span class="co">GL</span>.TexParameteri(<span class="co">GL</span>::<span class="co">TEXTURE_2D</span>, <span class="co">GL</span>::<span class="co">TEXTURE_WRAP_S</span>, <span class="co">GL</span>::<span class="co">CLAMP</span>);<tt>
</tt> <span class="co">GL</span>.TexParameteri(<span class="co">GL</span>::<span class="co">TEXTURE_2D</span>, <span class="co">GL</span>::<span class="co">TEXTURE_WRAP_T</span>, <span class="co">GL</span>::<span class="co">CLAMP</span>);<tt>
</tt> <span class="co">GL</span>.TexParameteri(<span class="co">GL</span>::<span class="co">TEXTURE_2D</span>, <span class="co">GL</span>::<span class="co">TEXTURE_MAG_FILTER</span>,<span class="co">GL</span>::<span class="co">LINEAR</span>);<tt>
</tt> <span class="co">GL</span>.TexParameteri(<span class="co">GL</span>::<span class="co">TEXTURE_2D</span>, <span class="co">GL</span>::<span class="co">TEXTURE_MIN_FILTER</span>,<span class="co">GL</span>::<span class="co">LINEAR</span>);<tt>
</tt> <span class="co">GL</span>.TexImage2D(<span class="co">GL</span>::<span class="co">TEXTURE_2D</span>, <span class="i">0</span>, <span class="co">GL</span>::<span class="co">RGBA</span>, image.width,<tt>
</tt> image.height, <span class="i">0</span>, <span class="co">GL</span>::<span class="co">RGBA</span>, <span class="co">GL</span>::<span class="co">UNSIGNED_BYTE</span>, image.rgba_data);<tt>
</tt> texture.width = image.width<tt>
</tt> texture.height = image.height<tt>
</tt> image.delete!<tt>
</tt> <span class="iv">@textures</span>[text] = texture<tt>
</tt> <span class="r">return</span> texture<tt>
</tt> <span class="r">end</span><tt>
</tt> <tt>
</tt> <span class="r">def</span> <span class="fu">get_texture</span> text<tt>
</tt> texture = <span class="iv">@textures</span>[text]<tt>
</tt> texture = create_texture(text) <span class="r">if</span> texture == <span class="pc">nil</span><tt>
</tt> texture<tt>
</tt> <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt> <tt>
</tt><span class="r">class</span> <span class="cl">TextTexture</span><tt>
</tt> attr_accessor <span class="sy">:ogl</span><tt>
</tt> attr_accessor <span class="sy">:width</span><tt>
</tt> attr_accessor <span class="sy">:height</span><tt>
</tt><span class="r">end</span><tt>
</tt> <tt>
</tt><span class="r">class</span> <span class="cl">Imlib2::Image</span><tt>
</tt> <span class="c"># Convert data to format compatible with OpenGL</span><tt>
</tt> <span class="r">def</span> <span class="fu">rgba_data</span><tt>
</tt> new_data = <span class="co">Array</span>.new(data.size)<tt>
</tt> i = <span class="i">0</span><tt>
</tt> <span class="r">for</span> i <span class="r">in</span> (<span class="i">0</span>..data.size/<span class="i">4</span><span class="i">-1</span>)<tt>
</tt> new_data[i*<span class="i">4</span>] = data[i*<span class="i">4</span><span class="i">+2</span>] <tt>
</tt> new_data[i*<span class="i">4</span><span class="i">+1</span>] = data[i*<span class="i">4</span><span class="i">+1</span>]<tt>
</tt> new_data[i*<span class="i">4</span><span class="i">+2</span>] = data[i*<span class="i">4</span><span class="i">+0</span>]<tt>
</tt> new_data[i*<span class="i">4</span><span class="i">+3</span>] = data[i*<span class="i">4</span><span class="i">+3</span>]<tt>
</tt> <span class="r">end</span><tt>
</tt> <span class="r">return</span> new_data.pack(<span class="s"><span class="dl">'</span><span class="k">C*</span><span class="dl">'</span></span>)<tt>
</tt> <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></table>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"># Usage</span><tt>
</tt><span class="c"># ... Inside draw loop ...</span><tt>
</tt><span class="co">GL</span>::MatrixMode(<span class="co">GL</span>::<span class="co">PROJECTION</span>);<tt>
</tt><span class="co">GL</span>::LoadIdentity()<tt>
</tt><span class="co">GL</span>::Ortho(<span class="i">0</span>,<span class="iv">@viewport</span>.x,<span class="iv">@viewport</span>.y,<span class="i">0</span>,<span class="fl">-1.0</span>,<span class="fl">1.0</span>)<tt>
</tt> <tt>
</tt><span class="co">GL</span>::MatrixMode(<span class="co">GL</span>::<span class="co">MODELVIEW</span>);<tt>
</tt><span class="co">GL</span>::LoadIdentity()<tt>
</tt><span class="co">GL</span>::Disable(<span class="co">GL</span>::<span class="co">LIGHTING</span>);<tt>
</tt><span class="co">GL</span>::Disable(<span class="co">GL</span>::<span class="co">DEPTH_TEST</span>);<tt>
</tt> <tt>
</tt><span class="co">GL</span>::Color(<span class="fl">1.0</span>, <span class="fl">1.0</span>, <span class="fl">1.0</span>, <span class="fl">0.7</span>);<tt>
</tt><span class="co">OpenGLTextManager</span>.new.render <span class="s"><span class="dl">'</span><span class="k">hello</span><span class="dl">'</span></span>, <span class="i">0</span>, <span class="i">0</span><tt>
</tt></pre></td>
</tr></table>