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&#8217;t appear drunk</li> <li>I don&#8217;t reveal intra-company communications</li> <li>I show off the full gamut of socialbeat&#8217;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&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /> <embed src="http://vimeo.com/moogaloop.swf?clip_id=2139958&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;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&amp;sec=2139958">Introducing SocialBeat</a> <p>If you are behind the times &#8211; 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 &#8211; just switch the data around from <span class="caps">BGRA</span> to <span class="caps">RGBA</span>&#8230;</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&#8217;t quite mastered imlib2 &#8211; note the resize hack to get the correct format. If anyone has any suggestions I&#8217;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>