<?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-7608222</id><updated>2011-04-21T22:07:11.935+02:00</updated><title type='text'>Emporte Une Vache !!!</title><subtitle type='html'>Vinaigritude Inside ("tu tu tu tu tu")</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7608222.post-116285225940721769</id><published>2006-11-06T23:28:00.000+01:00</published><updated>2006-11-06T23:32:45.443+01:00</updated><title type='text'>Farewell Blogger, here I come dotclear (ouf)</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: trebuchet ms;font-size:85%;" &gt;J'ai enfin l'occasion (le temps) de migrer mon "blog" ailleurs, en un endroit plus sûr, mien, moins pénible et moins lourd...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: trebuchet ms;font-size:85%;" &gt;Me voila ainsi à l'adresse suivante désormais : &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.touisteur.info/dotclear"&gt;&lt;span style="font-family: trebuchet ms;font-size:85%;" &gt;http://www.touisteur.info/dotclear&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: trebuchet ms;font-size:85%;" &gt;au plaisir...&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.touisteur.info/dotclear" style="font-family: trebuchet ms;"&gt;&lt;/a&gt; &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-116285225940721769?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/116285225940721769/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=116285225940721769' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/116285225940721769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/116285225940721769'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2006/11/farewell-blogger-here-i-come-dotclear.html' title='Farewell Blogger, here I come dotclear (ouf)'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-115764302662738349</id><published>2006-09-07T17:14:00.000+02:00</published><updated>2006-09-07T17:33:26.880+02:00</updated><title type='text'>Touisteur au Caire</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;&lt;font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);font-family:trebuchet ms;font-size:85%;"  &gt;&lt;font&gt;&lt;font&gt;Retour sur Cairo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;J’ai repris l’Ada, après 6 mois de travaux forcés en Java (il faut bien travailler pour son diplôme). En jetant un regard neuf sur mon travail en Ada, je me suis rendu compte que j’avais pris de mauvaises approches pour beaucoup de projets… J’ai donc décidé de reprendre mes activités sur :&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;li&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;Cairo-Ada et l’intégration GtkAda&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;Un générateur de binding OpenGL/Ada automatisé&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;Mon parseur iCalendar&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/ul&gt;&lt;div style="text-align: justify; color: rgb(0, 0, 0);"&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Et je me suis laissé tenter par beaucoup d’idées que j’ai commencé à implémenter avec plus ou moins de succès : binding Qt4, générateur automatique de binding C/C++… Sujets d’autres posts.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p  style="color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="text-align: justify; color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Le progrès le plus important pour l’instant est au niveau de Cairo, et son intégration à GtkAda. A l’époque j’utilisais gtkcairo, un widget C trouvé dans l’arbre de sources de cairo… où l’on pouvait récupérer une surface Cairo et dessiner dessus. J’avais bindé ce widget comme indiqué dans la documentation de GtkAda et j’étais assez satisfait du résultat. Mais il était totalement non portable, et surtout impossible à compiler sous windows… Et non maintenu. C’était une impasse, mais je m’en satisfaisais. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="text-align: justify; color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;L’autre solution, celle explicitée dans &lt;a href="http://gnomejournal.org/article/34/writing-a-widget-using-cairo-and-gtk28"&gt;cet article dans le GNOME Journal&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-GB"  style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;est qu’en GTK+ 2.8 il suffit d’appeler gdk_cairo_create pour récupérer une surface Cairo et dessiner dessus à l’intérieur d’un widget… Mais GtkAda était lié à la version 2.4 de GTK+…&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt;&lt;span style="font-weight: bold;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Du nouveau sur GtkAda !&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="text-align: justify; color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Récemment, j’ai appris que GtkAda était passé à la version 2.8, et bindait désormais la version 2.8.* de GTK+. Un grand pas pour l’humanité. J’ai donc facilement bindé les fonctions gdk_cairo* dans un package &lt;span style="font-family:courier new;"&gt;Gtk.Cairo_Integration&lt;/span&gt;. Ainsi, on peut désormais reprendre l’article et implémenter sans problème la partie Cairo et au lieu d’appeler en C :&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;    gdk_cairo_create()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;On notifiera au début de notre paquetage qu’on veut utiliser le package Gtk.Cairo_Integration :&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;    with Gtk.Cairo_Integration;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;     &lt;span style=""&gt; &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Et pour récupérer la surface (dans le handler de l’événement Expose), il nous faudra déclarer une constante (une variable fera aussi l’affaire) de type Gdk_Window et récupérer le Gdk_Window du widget courant (l’exemple est sur Gtk_Drawing_Area) :&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;    &lt;span style=";font-family:courier new;font-size:85%;"  &gt;    Win : constant Gdk_Window : Gtk.Drawing_Area.Window(Widget);&lt;br /&gt;    Cr : Cairo.Cairo_Object;         &lt;br /&gt;begin&lt;br /&gt;    Cr := Gtk.Cairo_Integration.Cairo_Create(Win);                     &lt;br /&gt;    -- do your drawing stuff&lt;br /&gt;                 -- ...&lt;br /&gt;    Cairo.Destroy(Cr);&lt;/span&gt;                    &lt;span  lang="EN-GB" style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;/span&gt;&lt;/span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="text-align: justify; color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Rien de bien compliqué, et aucun dépaysement pour les développeurs Cairo/GTK+ existants. La même chose, dans un vrai langage :-D. Vrai, c’est un peu verbeux, mais Gtk.Cairo comme nom de package entrait en conflit avec Cairo (tout court), le nom du package du binding Cairo...&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;p  style="text-align: justify; color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Le package Cairo_Integration est un binding du fichier &lt;a href="http://developer.gnome.org/doc/API/2.0/gdk/gdk-Cairo-Interaction.html"&gt;gdkcairo.h&lt;/a&gt; et toutes les fonctions s’y trouvant sont bindées. Je travaille encore pour intégrer tout cela à la chaîne de compilation de GtkAda, afin de produire un patch utilisable. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p  style="text-align: justify; color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Le gros problème désormais reste de nettoyer le binding Cairo… Il reste beaucoup de fonctions mal ou pas bindées, et surtout toute l’API est en un seul package/fichier… difficile à maintenir, mais je réfléchis à un découpage similaire à celui de la &lt;a href="http://www.cairographics.org/manual/"&gt;documentation&lt;/a&gt; mais j’ai encore quelques soucis avec la gestion des types et des packages enfant... Une solution viendra peut-être. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; color: rgb(0, 0, 0);"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;p  style="text-align: justify; color: rgb(0, 0, 0);font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Une fois ce découpage effectué et les fonctions bindées correctement (il manque le binding des fonctions concernant SVG et libsvg par exemple…), je vais faire un patch pour les sources de GtkAda (je ferais un checkout avant) et verrais bien si Act le prend =o).&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p  style="text-align: justify;font-family:trebuchet ms;" class="MsoNormal"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Mon grand espoir est de parvenir à porter la &lt;a href="http://macslow.thepimp.net/?p=35"&gt;fameuse horloge de MacSlow&lt;/a&gt; ou de produire un widget de qualité graphique comparable.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;   &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&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/7608222-115764302662738349?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/115764302662738349/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=115764302662738349' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/115764302662738349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/115764302662738349'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2006/09/touisteur-au-caire_07.html' title='Touisteur au Caire'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-115757694062325386</id><published>2006-09-06T22:32:00.000+02:00</published><updated>2006-09-06T23:10:30.380+02:00</updated><title type='text'>Outils de travail avec Ada.</title><content type='html'>&lt;p class="MsoNormal"&gt;&lt;span style=";font-family:&amp;quot;;font-size:10;"  &gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;&lt;span style="color: rgb(51, 204, 0);"&gt;Note : cet article date de Mathusalem et je doutais un peu de son intérêt, mais ça fait toujours du bien de rappeler qu'il y a des excellents outils en Ada et qu'il s'agit d'un langage extrêmement ouvert.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="text-align: justify;" class="MsoNormal"&gt;&lt;span style=";font-family:&amp;quot;;font-size:10;"  &gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: trebuchet ms;"&gt;En réponse à une remarque désobligeante, voire trollesque, d’un ex-ema-C-sien qui perd la boule à faire du Cpp, je tiens à dire que les outils disponibles pour Ada sont nombreux.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: trebuchet ms;font-family:&amp;quot;;font-size:85%;"  &gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;&lt;span style="font-weight: bold;"&gt;Tout d’abord au niveau des éditeurs et IDE&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;On a d’abord Gnat Programming System (GPS), distribué par AdaCore. Environnement de développement tout intégré, il permet, au-delà de l’édition de code de bonne facture, de gérer des projets, de débugger en ligne, de visualiser les dépendances entre paquetages, entre types, etc… Il est extensible en python (il me semble) et dispose déjà d’un certain nombre d’extensions.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;On a aussi &lt;span style="font-weight: bold;"&gt;XEmacs&lt;/span&gt;, l’outil presque ultime pour tout faire. Il dispose d’un mode Ada : coloration syntaxique, templates pour coller des blocs de code, indentation correcte, commentaires… Et j’en oublie sûrement, et je ne m’en sers sûrement pas assez bien pour savoir tout ce dont il est capable. Au-delà de ce mode Ada, on dispose de toutes les fonctionnalités d’emacs : recherche, remplace, buffer de compilation, des milliers d’options, découpage de l’écran à souhait (C-x 1 ou 2 ou 3). De même je suis sûr de passer à côté de certaines options. Mais l’environnement emacs est extrêmement riche pour le développeur, et le logiciel en lui-même est très stable, et je n’ai jamais aucune crainte de perdre des sources non enregistrées à cause d’un crash d’emacs.&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;On peut même trouver, et j’ignore si c’est installé de façon générique, un mode qui transforme emacs en IDE pseudo-GPS, avec plusieurs fenêtres à gauche de l’écran (parcours de répertoires, buffers ouvert, listes des fonctions/types/paquetages/tasks d’un fichier…). Cela s’appelle ecb il me semble. Très pratique quand un fichier source commence à gonfler en taille et qu’on n’a pas forcément envie de le découper « mieux » tout de suite…&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;Pour les malades du poignet et ceux qui veulent éviter un syndrôme du canal carpien et au passage perdre aussi en productivité (feeding the trolls), il y a aussi un mode Ada pour &lt;span style="font-weight: bold;"&gt;vim&lt;/span&gt; fonctionne bien aussi avec Ada, et il me semblait qu’à une époque KDevelop proposait vaguement de créer des projets Ada… &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;&lt;o:p&gt;Aonix et Act, deux des plus grands acteurs du monde Ada se sont lancés dans la course au plug-in pour Eclipse. J'avoue être tenté aussi, bien que ce soit du Java... Mais ça me remettrait un peu dans les cours de compilation... hum... changeons de sujet...&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-size:85%;" &gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;&lt;o:p&gt;En réalité, un éditeur avec coloration syntaxique est en général suffisant avec Ada, car la pièce maîtresse de la chaîne de développement Ada est pour moi le compilateur GNAT (je ne connais pas les autres). J'avais déjà fait l'apologie de ce compilateur, mais il ne cesse de m'étonner. Le refactoring n'est d'aucune difficulté avec GNAT. Modifiez, compilez, notez les erreurs, reportez les modifs au lignes où les erreurs ont été découvertes. 95% du temps c'est suffisant. Je ne travaille pas avec des projets de 1,5 millions de lignes de code, mais on m'a affirmé qu'avec un projet bien découpé et la compilation séparée (suprématie d'Ada !), c'était tout aussi agréable et simple. L'outil bienvenu serait plutôt lié à la complétion =o) mais là encore XEmacs fait un travail honorable.&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;Les quelques petites fonctionnalités supplémentaires valent-elle le bloat monstrueux d'Eclipse et l'investissement de 5000USD pour un simple plug-in ?&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-size:85%;" &gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;&lt;span style="font-weight: bold;"&gt;Les outils de compilation et test&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;GNAT est un excellent compilateur. Il passe les tests ACATS, est maintenu par certains des meilleurs experts en compilation et Ada (grand fan de Robert Dewar, ses explications sont toujours rayonnantes de concision et de richesse... ok je m'emporte mais quand même, chapeau), et supporte déjà une très grande partie des fonctionnalités d’Ada 2005, en avance.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;Par contre, GNAT est désormais GPL (et non plus GMGPL) pour qui ne paie pas le support Act. Cela signifie qu’à moins d’utiliser une version Gnat Pro récupérée ou un Gnat-GCC. (GMGPL veut encore dire que le code est libre, donc copiable, récupérable, diffusable… c’est juste que &lt;st1:personname productid="la GPL" st="on"&gt;la GPL&lt;/st1:personname&gt; rend GPL le code qu’on compile avec le runtime. GMGPL, ou la licence runtime de gcc veut dire que le runtime peut être utilisé sans causer le passage d’un code qui l’appelle en GPL.&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;Au-delà ce ça, Act livre aussi une version de gdb qui tourne avec GNAT. Avant GCC4.0 et le passage à Ada2005, on pouvait encore travailler avec le gdb de base de gcc, semble-t-il. En attendant que la transition soit terminée, on peut utiliser le gdb fourni par Act, ainsi donc que les outils graphiques qui vont bien, ddd et gvd.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;Pour les tests de performance, gprof fonctionne bien avec GNAT, et oprofile est très pratique et peut annoter du code Ada (extrêmement pratique). J'ai déjà fait l'apologie de KCachegrind sur ce blog, alors je me retiendrai.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-weight: bold; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;Les bibliothèques&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;On trouvera en Ada tout ce qu'il faut pour créer des &lt;a href="https://libre2.adacore.com/GtkAda"&gt;interfaces graphiques&lt;/a&gt;, &lt;a href="https://libre2.adacore.com/xmlada/"&gt;lire/écrire du XML&lt;/a&gt;, &lt;a href="https://libre2.adacore.com/aws/"&gt;intégrer&lt;/a&gt; (oui &lt;span style="font-style: italic;"&gt;intégrer&lt;/span&gt;) un serveur/client HTTP, client POP/Jabber/LDAP, et pour peu qu'on soit intéressé par des applications distribuées, on a le choix : &lt;a href="https://libre2.adacore.com/polyorb/"&gt;l'annexe E&lt;/a&gt; d'Ada95 (génial) et un &lt;a href="https://libre2.adacore.com/polyorb/"&gt;ORB CORBA&lt;/a&gt; (on aime ou n'aime pas, mais c'est disponible). Tout cela de façon portable, partout où GNAT est disponible.&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;Je passe sur les capacités de liaison vers les langages C, C++, Cobol, qui permettent de récupérer des anciennes bibliothèques et de les réutiliser (mot-clé en Ada), ou de se binder aux dernières nouveautés (Cairo par exemple, ou encore Qt4).&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Ce qu'il manque&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;Ce n'est ici qu'un avis.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;Je suis d'abord très très tenté par un &lt;span style="font-style: italic;"&gt;générateur automatique de bindings&lt;/span&gt;. J'ai regardé et codé pendant quelques heures pour une sortie Ada et Swig paraît un bon point de départ. De mon côté je me penche sur une solution plus simpliste pour le C et le C++ (encore un projet perso jamais commencé jamais fini =oD).&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; font-family: trebuchet ms;" class="MsoNormal"&gt;&lt;span style=";font-size:85%;" &gt;Un &lt;span style="font-style: italic;"&gt;plug-in Eclipse avancé&lt;/span&gt; avec complétion intéressante, intégrée à GNAT et ses conseils =o), liaison avec le C/C++ automatisée et transparente (il suffit de cliquer-déposer un .so avec les .h correspondants par exemple... aucune idée précise), des capacités de refactoring à la java, une gestion avancée du développement temps-réel embarqué, des assistants de code puissants permettant d'effectuer les opérations pénibles en un clin d'oeil. Et des aides pour l'utilisation de PolyOrb, l'intégration "transparente" de GNADE et tous ces outils qui font d'Eclipse un vrai environnement intégré dont on supporte la lenteur parce qu'il apporte tellement... Ah, &lt;span style="font-style: italic;"&gt;évidemment&lt;/span&gt; open-source ce plug-in =oD. Que la communauté Ada puisse exprimer ses besoins en les développant =oD.&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-115757694062325386?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/115757694062325386/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=115757694062325386' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/115757694062325386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/115757694062325386'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2006/09/outils-de-travail-avec-ada.html' title='Outils de travail avec Ada.'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-115757233892507900</id><published>2006-09-06T21:40:00.000+02:00</published><updated>2006-09-06T22:31:43.390+02:00</updated><title type='text'>Cairo-Ada-Gtk... doesn't talk about beer</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="color: rgb(51, 204, 0); font-style: italic;font-size:85%;" &gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Note &lt;/span&gt;: j'ai écrit cet article en février mais jamais pris le temps de le publier. Comme j'en prépare un autre sur Cairo, je me suis dit qu'un peu de contexte ferait du bien ^^.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Récemment (depuis 3-4 mois) je me suis intéressé à &lt;a href="http://cairographics.org"&gt;Cairo&lt;/a&gt;, parce que j’ai vu que GTK+/Gnome avait déjà migré dessus, et que les exemples pour faire des dessins étaient jolis et simple ET ressemblaient énormément à OpenGL. En plus - et c’est surtout ça qui m’enthousiasmait – Cairo était prévu pour être accéléré par la carte graphique et grâce à Glitz, être « posé » par-dessus OpenGL, un peu (mais pas exactement) à la façon de MacOS X (dites Ten, comme dirait un certain enseignant hype que je ne citerai pas).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Travail sur Cairo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;L’API ayant l'air très simple à binder, j’ai voulu travailler en Ada, dans un environnement qui me plaisait (pas de C, pitié). J’ai réussi rapidement à binder toutes les fonctions nécessaires pour « porter » les snippets d’exemples disponibles dans la documentation de Cairo.    Le binding est on ne peut plus simpliste, j’ai pris les types C, ai transposé les pointeurs en records nulls… et c’est tout. J’aurai pu (et du) aller plus loin, et proposer comme pour PyCairo ou rCairo, ou même Gtkmm (C++), une implémentation « orientée objet », mais la flemme et l’envie de coder par-dessus mon binding ont pris le dessus. Ce sera pour plus tard...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;L’utilisation la plus courante de Cairo aujourd’hui est dans les interfaces graphiques (il est quasiment fait pour ça). Le problème étant que l’implémentation d’une UI à partir de Cairo la plus courante est GTK+. Du C. Et pas du C classique, « normal » et « assembleur de haut niveau »-like. Non, du C qui émule des fonctionnalités objet. Via les GObjects et autres jolies fonctionnalités. J’avoue qu’on finit par s’y habituer, mais lire le code source de GTK+, ce n’est pas une sinécure pour un débutant et/ou médiocre en C. Comme disait un de mes anciens collègues &lt;span style="font-style: italic;"&gt;« c’est le genre de trucs qui doit bien marcher selon la doc et dans lequel tu dois pas à avoir à mettre les mains »&lt;/span&gt;. Les macros sont assez difficiles à suivre intuitivement (sans lire la documentation détaillée), et j’ai vite eu la tête qui explosait.&lt;br /&gt;&lt;br /&gt;Pourquoi si dur, alors que tous les programmeurs Gnome et GTK+ y arrivent sans problème. Mais c’est que je n’ai pas dépareillé de mon idée de faire ce projet Cairo en Ada. Il fallait donc que j’insère Cairo dans GtkAda… La voie la plus simple eut été que GtkAda ait suivi l’API Gdk (on va dire une sous-couche de Gtk+), là où est implanté le lien Cairo. A priori, les développeurs de GtkAda sont restés à Gtk+2.6 ou inférieur, et Cairo a été ajouté à la 2.8.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Un widget maison...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;Tant pis, dommage, recherche d’une autre piste. Avant de l’intégrer dans GTK, Cairo avait fait l’objet d’une implémentation dans un widget nommé GtkCairo, trouvable en fouillant sur le site de Cairo (décidemment, beaucoup de « Cairo » dans ce post…).    Ne connaissant absolument rien de la façon d’écrire un widget en Gtk+ et encore moins en GtkAda, j’ai lu la doc et le code source de plusieurs widget GtkAda, et ai fini, par tâtonnements et segfaults successives (oui ça a beau être de l’Ada, quand on lie avec du C…) par obtenir     :&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;un widget fonctionnel, sous la forme d’une horloge. Le fond provenant de l’article sur le GNOME Journal à propos de Cairo : &lt;a href="http://www.touisteur.com/proto/gtkwidget/gtkada_cairo_gnome_journal_clock1.png"&gt;Screenshot&lt;/a&gt;, &lt;a href="http://gnomejournal.org/article/34/writing-a-widget-using-cairo-and-gtk28"&gt;Article&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;puis une autre horloge (provenant du tutoriel Cairo de GTKmm). &lt;a href="http://www.touisteur.com/proto/gtkwidget/gtkada_cairo_gtkmm_tutorial_clock.png"&gt;Screenshot&lt;/a&gt;, &lt;a href="http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/ch15s07.html"&gt;Article&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;et enfin d’un widget d’animation d’attente infinie… alla MacOsX mais de loin… de Très Loin… &lt;a href="http://www.touisteur.com/proto/gtkwidget/gtkada_cairo_macos_wait_clock.png"&gt;Screenshot&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Plusieurs problèmes alors : c’est LENT ! et ça prend toutes les ressources ! Et le code est pénible et lourd (pas factorisé, peu de fonctions, beaucoup de copier-coller « pour que ça marche »).&lt;br /&gt;&lt;br /&gt;Au fur et à mesure que ma connaissance de GTK+ s’améliore, je mets un timeout bien plus raisonnable et apprends à ne redessiner que lorsqu’on a besoin… Et les horloges semblent beaucoup plus rapides. Tout va pour le mieux.&lt;br /&gt;&lt;br /&gt;J’ai ainsi continué de m’enfoncer dans l’API Cairo et de la binder au fur et à mesure. Trop d’un coup et le découragement serait venu. Je ne bindais que ce dont je me servais (et en général, toutes les fonctions qui étaient autour).  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Prémices d'appli de calendrier&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Fort de mon « expérience » joyeuse et fier d’avoir implémenté un widget Cairo en Ada – pour être modeste « bindé du code C », j’ai commencé à développer ce qui m’intéressait. Un widget de calendrier/emploi du temps…&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;j’étais, et suis toujours impressionné par &lt;a href="http://www.apple.com/macosx/features/ical/"&gt;iCal&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;j’ai utilisé assez longtemps les journaux de KOrganizer/Kontact/KPim pour avoir décidé d’implémenter un début de lecteur iCalendar en Ada (sujet d’un futur post ?).&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;C’est simple à dessiner et à modéliser, et c’est très graphique et inspirant.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J’avais déjà quelques « mock-ups » d’interface… vraiment basiques et laids. Je les partage… Si quelqu’un arrive à en tirer autre chose qu’&lt;a href="http://www.touisteur.com/proto/proto1.svg"&gt;un&lt;/a&gt; &lt;a href="http://www.touisteur.com/proto/proto2.svg"&gt;bon&lt;/a&gt; &lt;a href="http://www.touisteur.com/proto/proto3.svg"&gt;rire&lt;/a&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Après quelques heures/soirées de code, j’avais obtenu un premier jet, ressemblant peu à mes mockups… Je dirais presque "heureusement"      La progression en quelques jours :            &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Le &lt;a href="http://www.touisteur.com/proto/gtkwidget/gtkada_calendar_20060113.png"&gt;tout début&lt;/a&gt; : la grille, et les débuts d’eventbox. On voit les dégradés partout, l’alpha-blending et l’anti-aliasing en pleine action…&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;a href="http://www.touisteur.com/proto/gtkwidget/gtkada_calendar_20060114.png"&gt;un jour plus tard&lt;/a&gt;, changé d’avis sur les dégradés trop poussés dans les event-boxes, ajouté des titres avec une couleur différente et un dégradé sur la police&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;a href="http://www.touisteur.com/proto/gtkwidget/gtkada_calendar_20060114-Better.png"&gt;quelques heures après&lt;/a&gt;, fait en sorte que les textes des titres rentrent toujours dans le titre des event-boxes (dommage que l’hyphénation ne soit pas gérée toute seule =o)). Désolé pour le blasphème, les paroles d’un morceau que j’écoutais à ce moment…&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;a href="http://www.touisteur.com/proto/gtkwidget/gtkada_calendar_20060115.png"&gt;un meilleur choix de couleurs&lt;/a&gt;, encore un effort sur les polices (peu visible), et surtout refactoring important (la nuit dessus)...&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;10 jours plus tard, après une pause « aaaah je suis allé super loin dans un projet pour une fois, aaaaaah… » de découragement, j’ai décidé d’ajouter une méthode pour dessiner des info-boxes, pour décrire en contexte les événements… Pas si évident qu’il y parait. En fonction des coordonnées pointées, on doit choisir la base de la flèche, et une largeur sympa et éviter les angles droits… Bref, au bout de 3-4 heures d’arrachage de cheveux (manque de concentration surtout), on obtenait &lt;a href="http://www.touisteur.com/proto/gtkwidget/gtkada_calendar_20060126.png"&gt;ce genre de petites boites&lt;/a&gt;.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;En pause &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;J’ai mis le projet en pause depuis, entre autre par fainéantise, et aussi parce qu’un de mes camarades &lt;a href="http://yogiaoxford.blogspot.com"&gt;codeur fou&lt;/a&gt;  s’est mis lui aussi à coder un calendrier en Qt… Très vite, très très très vite. Du genre à rendre mes progrès « fulgurants » de 2-3 semaines comme 20 minutes de travail pour lui =o). C'était vraiment du beau travail, avancé et joli... Du coup, j’ai reporté mon attention sur d’autres projets. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;D’autres projets dont je parlerai peut-être plus tard. =o).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Mais, en attendant, j’ai continué d’implémenter &lt;a href="http://www.touisteur.com/proto/gtkwidget/gtkada_aMazed_20060306.png"&gt;mon infobox vide&lt;/a&gt;, et sur un de ces autres projets jamais finis, ça donne quand même envie.&lt;br /&gt;&lt;br /&gt;Le prochain article à propos de Cairo parlera des nouveautés et progrès au niveau du binding =o).&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-115757233892507900?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/115757233892507900/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=115757233892507900' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/115757233892507900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/115757233892507900'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2006/09/cairo-ada-gtk-doesnt-talk-about-beer.html' title='Cairo-Ada-Gtk... doesn&apos;t talk about beer'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-115755449298557410</id><published>2006-09-06T16:50:00.001+02:00</published><updated>2006-09-06T18:33:52.620+02:00</updated><title type='text'>Six mois de cours^Wtorture (1/2)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Long Time No See&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Je n'avais pas posté ici depuis 1/2 siècle , le moment est venu de recommencer un peu. J'ai entre temps brouillonné quelques articles plus ou moins intéressants et je ne vais pas les jeter. Mais avant de poster tout cela, parlons un peu de mon activité durant ces 6 derniers mois...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Mon stage s'est plutôt bien terminé, mon travail a été considéré comme très satisfaisant et ma connaissance des shaders et des technologies 3D a fait un bond conséquent, ainsi que mes compétences en matière de développement, de réflexion et de conception... Le chemin reste long bien sûr. Pour ne rien gâcher, j'ai été très bien noté et rémunéré. Un très, très bonne expérience donc, et cerise sur le gâteau, en Ada...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Je m'étais promis de continuer le développement des projets que j'avais commencés en entreprise et personnellement en Ada : un binding OpenGL et un binding Cairo/GTK+. Le second recevra les honneurs de plusieurs articles très bientôt (le temps de la mise en page) et le premier un peu plus tard. Malheureusement, comme d'habitude mon enthousiasme a été quelque peu écrasé sous la masse de travail des études qui ont repris. J'ai rapidement mis de côté le plaisir du développement Ada personnel pour la "joie" du développement Java forcé.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Parce que voila, le dernier langage pour la pédagogie et pour simplifier les corrections d'exercices, c'est Java. Le thème global des trois projets Java à rendre était cependant toujours frais dans ma tête : Graphisme et Visualisation d'Information étaient à base d'OpenGL. L'un était un exercice de modélisation du campus de la fac' où j'étudie, et les deux autres consistaient en deux applications/composants de visualisation d'informations.&lt;br /&gt;&lt;br /&gt;Je vais me contenter de parler du projet de Graphique, et continuerai au prochain article sur la Visu...&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;&lt;b&gt;Le projet Graphique&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; La consigne était de modéliser un minimum de bâtiments de mon campus, les voies de circulation, des voitures pour s'y déplacer, un ciel et un sol, et des buttes à l'aide de courbes de béziers, une caméra qui va bien et quelques optimisations (graphe de scène...). Jusque-là, rien de bien pénible ou de surprenant. Le hic, c'est qu'il fallait utiliser Java pour s'interfacer avec OpenGL, via le désormais fameux JOGL. Ce dernier est une usine à gaz et a rendu le développement de ce projet extrêmement pénible et laborieux. La lenteur, la complexité induite par Java/Swing par rapport à une application Ada ou C++ correspondante a rendu le travail sur ce projet une corvée. Pour ma part j'en ai effectué le moins possible graphiquement, me contentant d'aider mes trois courageux (http://blog.gmo-web.info/) binômes (http://jbamassy.blogspot.com) dans leur quête vers la compréhension d'OpenGL et des petites absurdités, incompatibilités, incohérences quotidiennes... &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Je m'étais affecté aux tâches de gestion de caméra et de la partie optimisation. &lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;La caméra&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote face="trebuchet ms"&gt; &lt;/blockquote&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; J'ai mis un temps fou à créer une caméra qui au final ne fonctionnait pas correctement, mais permettait de se déplacer simplement dans la scène. Dans la recherche du Graal de la caméra j'ai découvert les joies de la gestion de la pile de matrice OpenGL, et ai beaucoup joué avec pour obtenir des mouvements et transformations de façon plus intuitives et pratiques que les transformations classiques. Ainsi, au lieu de reprendre un code de quaternions que je ne comprenais qu'à moitié, j'ai préféré implémenter une caméra un peu originale. Au final, elle était plus que compliquée à réutiliser et absolument inmaintenable, mais ce que j'ai appris ici m'a beaucoup servi pour la phase optimisation.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; L'idée était qu'au lieu de donner (position + 3 angles d'Euler) ou un quaternion pour décrire la position et direction de la caméra, j'ai utilisé le contexte courant et appliquait mes transformations directement sur la matrice de caméra courante. Pour ceux qui l'ignorent, dans OpenGL quand on applique une transformation (glRotate, glTranslate, etc.) celle-ci est considérée comme la première transformation effectuée, à l'origine... Donc si vous vous éloignez de l'origine et que vous appliquez une rotation ensuite, OpenGL va d'abord faire la rotation, puis la translation. Pour un débutant en Graphique c'est parfois rebutant, mais j'ai l'habitude depuis le temps. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Le problème est que je souhaitais que la transformation soit effectuée &lt;i&gt;à partir de l'endroit et de l'orientation où se trouvait la caméra&lt;/i&gt;. Je voulais l'opération habituelle dans le sens opposé (la multiplication de matrices n'est pas commutative). Après bien des batailles contre le systèmes de matrices d'OpenGL (que j'ai quasiment toutes perdues), j'ai découvert par exemple que les matrices y sont stockées dans le sens différent du sens commun (en maths (en france)): en colonnes/lignes... Ensuite j'ai du appliquer mes magnifiques capacités de calcul et de repérage dans l'espace pour rater complètement toutes les transformations que je tentais, jusqu'à ce que me vienne l'idée (bien tard) de m'imaginer la caméra comme un objet, un point... J'ai fini par trouver des solutions, à grands coups de glLoadMatrix, glMultMatrix, glGetfv()... Bien sûr, Java/JOGL n'aidait pas dans ce capharnaüm, avec sa grande verbosité et son abstraction trop poussée. Et dire qu'un des "grands" arguments contre Ada est sa verbosité...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Les premières implémentations avaient des effets de bords désastreux, car personne dans le projet n'utilisait les glPushMatrix() glPopMatrix() avant de faire joujou avec la transformation courante... Et ensuite je me suis redécouvert un très vieux problème que j'avais rencontré quand j'avais développé à partir de zéro une toute petite bibliothèque de rendu 2D/3D logicielle pour de la stéréoscopie : la précision des nombres à virgule flottante. Usant et abusant des glMultMatrix(), l'erreur ou l'imprécision de chaque opération se répercutait extrêmement vite, en particulier lors des rotations. On voyait progressivement mais très vite l'horizon se pencher alors qu'il s'agissait d'une rotation dans le plan de l'horizon. Le passage à des calculs en précision double a un peu amélioré la situation. Et j'ai laissé le tout tel quel, en priant pour que l'examinateur ne s'en rende pas compte.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Au final je ne suis pas du tout satisfait de ce code, horrible, mais ce qui comptait c'était qu'il fonctionne, pour que je puisse me consacrer à la partie vraiment, &lt;i&gt;vraiment&lt;/i&gt; intéressante du projet et qui n'avait plus besoin d'approcher JOGL et consistait majoritairement en de l'algorithmique et de ce fameux &lt;i&gt;number crunching&lt;/i&gt; (gros calculs brutaux) dont Java se dit capable de rivaliser avec le C aujourd'hui.&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;Quatre pommes &lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote face="trebuchet ms"&gt; &lt;/blockquote&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;Lors de ma soutenance de stage, lorsque j'ai présenté mon travail sur OpenGL et la recherche de performances maximales, via Pixel Buffer Objects, des mécanismes utilisant des textures rectangles, des FrameBuffer Objects  pour l'écriture texture-to-texture... Un professeur dans le jury m'a demandé si j'avais recherché des optimisations de plus haut niveau, algorithmiques, en particulier dans le domaine du partitionnement de l'espace (Kd-Tree et autres friandises). Etant un ignare total dans le domaine, j'ai regretté de ne pas m'être penché plus tôt sur ce genre d'idées. Il me fallait corriger mon ignorance au plus tôt.&lt;br /&gt;&lt;br /&gt;Je cherchais donc via ce projet à implémenter un algorithme intéressant permettant de réduire le nombre d'objets à afficher dans une scène. On avait survolé rapidement les &lt;a href="http://en.wikipedia.org/wiki/Binary_space_partitioning"&gt;BSP&lt;/a&gt; en cours et je voyais poindre la lourde, peu originale et surtout peu adaptée  implémentation basique d'un tel engin... En recherchant d'autres solutions, j'ai découvert les &lt;a href="http://en.wikipedia.org/wiki/Octree"&gt;Oct-tree&lt;/a&gt; et les &lt;a href="http://en.wikipedia.org/wiki/Quadtree"&gt;Quad-tree&lt;/a&gt;. En résumé, il s'agit d'algorithmes très simples de découpage récursifs de l'espace. Ceux-ci sont beaucoup plus adaptés à la modélisation de bâtiments, car leur forme  "carrée" simplifie énormément les calculs et leur structure rigide y rend la recherche extrêmement efficace.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; L'idée était de gérer le &lt;a href="http://en.wikipedia.org/wiki/Frustum_culling"&gt;frustum-culling&lt;/a&gt; avec un algorithme de détection de collision via un quadtree. Le frustum était projeté sur le sol (ses 6 faces l'étaient), et on utilisait ces quadrilatères pour vérifier la collision avec d'autres objets présents dans la scène.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Le problème premier et pénible était de récupérer le frustum, c'est à dire les coordonnées de ses 8 sommets. Il fallait faire ça à partir de la matrice de caméra. Heureusement j'avais déjà dépensé beaucoup de temps de cerveau à jouer avec les matrices et j'ai rapidement trouvé comment récupérer la position et l'orientation de la caméra, pour ensuite récupérer les 8 sommets à coup de géométrie simplette =oD.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Ensuite et enfin &lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;(j'aime garder le plus agréable pour la fin)&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;, j'ai implémenté l'algorithme de quadtree en 2 journées (de 22h) et ai optimisé la recherche ainsi que l'occupation mémoire comme j'ai pu, et ai fini de le débugger un autre soir. C'était vraiment agréable d'enfin développer quelque chose qui soit simple, relativement élégant dans le principe, sans la lourdeur pénible des abstractions d'interface graphique... Et surtout de pouvoir tester cet outil directement et de façon interactive avec une petite application Java2D (temps de développement compris dans l'implémentation de l'algorithme :-)) qui a plus tard été intégrée à l'interface finale. Elle sert de radar pour montrer quels objets statiques sont présents dans la scène et montre les frustum et les objets qu'il contient ou coupe, et donc les objets qui sont dessinés et ceux qui ne le sont pas. On visualise le résultat de l'algorithme d'optimisation, à défaut de pouvoir le constater. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; En effet, les trois quarts de fonction géométriques que j'ai utilisées, je les ai recodées à la main, à partir de formules pas optimisées du tout. La recherche dans un cas bouclait infiniment et je n'avais pas réussi à reproduire cet &lt;a href="http://fr.wikipedia.org/wiki/Heisenbug"&gt;Heisenbug&lt;/a&gt;. Quelques autres erreurs de conceptions ralentissaient encore ce code, mais priorité a été donnée au bouclage du projet. L'optimisation ralentissait en fait l'application :-D. Etant donnée la complexité de l'algorithme il aurait fallu avoir un nombre conséquent d'objets pour y trouver son compte :-).&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;Bile-an&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote face="trebuchet ms"&gt; &lt;/blockquote&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt; Au final, ce projet étalé sur 2 mois m'aura rappelé que j'aime toujours si peu le Java, et que seul Eclipse qui m'a maintes fois sauvé de la dépression, en fait un langage de travail passable. J'aurai tout de même découvert beaucoup d'éléments intéressants, fait beaucoup (beaucoup !) d'erreurs, et donc appris énormément mais que le rapport :&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: left;"&gt;&lt;div style="text-align: center;"&gt;&lt;span style="color: rgb(255, 0, 0);font-family:trebuchet ms;" &gt;Apprentissage / PITA&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;était proche de 0.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ce projet nous a quand même valu la &lt;span style="font-weight: bold; font-style: italic;"&gt;meilleure note de la promo&lt;/span&gt;... comme quoi...&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;blockquote&gt; &lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-115755449298557410?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/115755449298557410/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=115755449298557410' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/115755449298557410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/115755449298557410'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2006/09/six-mois-de-courswtorture-12.html' title='Six mois de cours^Wtorture (1/2)'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-113302912515103575</id><published>2005-11-26T18:35:00.000+01:00</published><updated>2005-11-27T00:07:37.030+01:00</updated><title type='text'>I --------- Love  --------- This ---------  Compiler !</title><content type='html'>&lt;div  style="text-align: justify; font-family: trebuchet ms;font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Je suis un grand, grand fan d'Ada. J'adore travailler avec ce langage. J'ai l'impression de coder, et non de passer mon temps à comprendre quelle stupidité basique j'aurais oublié.&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Introduction, Vite Fait&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Oui, ce langage fortement typé, plutôt verbeux, pseudo-limitatif.&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Pour le typage fort, ça facilite la détection des erreurs à la compilation, entre autres. En Ada je passe moins de temps à déverminer et plus de temps à coder. Et même si en général on écrit plus de code en Ada qu'en C/C++, on en écrit beaucoup moins qu'en Java. L'API n'est pas aussi complète quye celle de Java, bien qu'on puisse trouver de quoi faire pas mal de choses sur &lt;a href="http://yogiaoxford.blogspot.com/2005/10/enfin.html"&gt;Teh Intarwaybe&lt;/a&gt;. Des bindings et des bibliothèques développées from scratch.&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Les outils de debugging et de profiling que vous utilisez en C ou pas (c.f mon article sur KCacheGrind) sont utilisables avec Ada.&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;En plus ! La norme Ada 2005 est en phase de finalisation. Elle apporte pas mal de modifications pour simplifer un peu la vie du programmeur Ada.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;Entre autres sucreries :&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Des nouveaux profils temps-réel&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;La possibilité d'avoir des inclusions circulaires de packages (oui c'était un petit souci avec Ada95)&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Des containers (liste, vector, sets, maps)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Du pseudo héritage multiple via interface&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;La notation pointée (pour les vieux critiques qui disaient "tu peux pas faire comme en Java mon_instance.ma_methode()")...&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Les access anonymes :  de fonctions/procédures ou de types. Très pratiques, car plus besoin de créer &lt;/span&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;à chaque fois&lt;/span&gt;&lt;span style="font-size:85%;"&gt; un type pointeur&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;div  style="text-align: justify; font-family: trebuchet ms;font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Le but de cet article ? Montrer pourquoi, comme &lt;a href="http://yogiaoxford.blogspot.com/2005/11/paranoa_16.html"&gt;google le fut&lt;/a&gt;, le compilateur Ada est votre ami. Petite compilation des erreurs que renvoie le compilateur GNAT (celui qui est libre et plus ou moins intégré à GCC). Je les aime, et je suis sûr que &lt;a href="http://kotoajena.blogspot.com/2005/10/taf.html"&gt;ça peut faire des jaloux&lt;/a&gt;.&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;La compil'&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Confondu Ada, SQL et VB6 ?&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;framebuffer_object.adb:79:42: "&lt;&gt;" should be "/="&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Aide-moi pour la visibilitée et la gestion de portée&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: trebuchet ms;font-family:courier new;font-size:85%;"  &gt;&lt;/span&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;/span&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;framebuffer_object.adb:79:42: operator for type "gl_uint" defined at opengl-types.ads:20 is not directly visible&lt;br /&gt;framebuffer_object.adb:79:42: use clause would make operation legal&lt;br /&gt;&lt;br /&gt;simple_video_handler_types.adb:95:33: "Void_Const_Access" is not visible&lt;br /&gt;simple_video_handler_types.adb:95:33: non-visible declaration at opengl-types.ads:28&lt;/span&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;/span&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Variable non modifiée, en faire une constante ?&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;span style=""&gt;framebuffer_object.adb:106:07: warning: "Attachment_Type" is not modified, could be declared constant&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Pas les bons types pour chaque opérande de l'opérateur "/="&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;framebuffer_object.adb:367:42: invalid operand types for operator "/="&lt;br /&gt;framebuffer_object.adb:367:42: left operand has type "gl_int" defined at opengl-types.ads:16&lt;br /&gt;framebuffer_object.adb:367:42: right operand has type "gl_uint" defined at opengl-types.ads:20&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Une fonction fonction() qui fait return(function));&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;span style=""&gt;framebuffer_object.adb:412:14: warning: possible infinite recursion&lt;br /&gt;framebuffer_object.adb:412:14: warning: Storage_Error may be raised at run time&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;J'adore celle là (corrige mon orthographe)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;span style=""&gt;framebuffer_object.adb:369:71: "Ct_Gl_Frame_Buffer_Ext" not declared in "constants"&lt;br /&gt;framebuffer_object.adb:369:72: possible misspelling of "ct_GL_FRAMEBUFFER_EXT"&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Comment ça mieux que le C ?&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;hello_gpgpu.adb:107:22: "=" should be ":="&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Oublié d'importer un package&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;span style=""&gt;simple_video_handler_types.adb:36:16: missing with for "Ada.Text_Io" &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;script&gt;!-- D(["mb","hu hu hu c\'est subtil... et le compilo n\'aide pas vraiment -- là : on ne peut&lt;br /&gt;pas avoir un type tagged en argument d\'une primitive d\'un autre type tagged.&lt;br /&gt;A moins que l\'argument soit mis en&lt;br /&gt;-- type\'class... et qu\'il soit converti explicitement à l\'utilisation =o/&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:28:04: warning: no primitive operations for&lt;br /&gt;&amp;quot;T_Radial_Struct&amp;quot; after this line&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:34:14: this primitive operation is declared too&lt;br /&gt;late&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:56:14: operation can be dispatching in only one&lt;br /&gt;type&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:60:14: operation can be dispatching in only one&lt;br /&gt;type&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:62:14: operation can be dispatching in only one&lt;br /&gt;type&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:72:04: warning: no primitive operations for&lt;br /&gt;&amp;quot;T_Radial&amp;quot; after this line&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:74:49: expected type &amp;quot;T_Radial_Struct&amp;quot; defined&lt;br /&gt;at line 15&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:74:49: found an access type&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:80:13: this primitive operation is declared too&lt;br /&gt;late&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:81:13: this primitive operation is declared too&lt;br /&gt;late&lt;br /&gt;simple_video_handler_types.ads&lt;wbr&gt;:134:13: operation can be dispatching in only&lt;br /&gt;one type&lt;br /&gt;--&lt;br /&gt;simple_video_handler_types.adb&lt;wbr&gt;:307:29: &amp;quot;aliased&amp;quot; should be before &amp;quot;constant&amp;quot;&lt;br /&gt;-- pour avoir la paix avec le compilateur quand on est en train de coder et&lt;br /&gt;qu\'on veut juste vérifier que &amp;quot;jusqu\'à ce point une fonction -- compile&amp;quot;, on&lt;br /&gt;peut utiliser la pragma unreferenced... mais si on l\'oublie après avoir tout&lt;br /&gt;codé, le compilo le voit... =o)&lt;br /&gt;simple_video_handler_types.adb&lt;wbr&gt;:410:55: warning: pragma Unreferenced given for&lt;br /&gt;&amp;quot;Data&amp;quot;&lt;br /&gt;-- oublié de mettre &amp;quot;body&amp;quot; pour désigner un corps de package...&lt;br /&gt;buffer_lines_list.adb:1:08: keyword &amp;quot;body&amp;quot; expected here [see file name]&lt;br /&gt;buffer_lines_list.adb:1:08: missing &amp;quot;body&amp;quot;&lt;br /&gt;-- génial : j\'ai mis Const à la place de constant :&lt;br /&gt;video_runner.adb:43:23: illegal abbreviation of keyword &amp;quot;constant&amp;quot;&lt;br /&gt;-- &lt;&gt; à la place de /=&lt;br /&gt;simple_video_handler_types.adb&lt;wbr&gt;:928:27: &amp;quot;&lt;&gt;&amp;quot; should be &amp;quot;/=&amp;quot;&lt;br /&gt;&lt;br /&gt;",0] ); &lt;/script&gt;&lt;ul  style="font-style: italic; font-family: trebuchet ms;font-family:trebuchet ms;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Multiple dispatching&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Une autre erreur fort sympathique à propos de dispatching... hu hu hu c'est subtil... Là, on ne peut pas avoir un type tagged en argument d'une primitive d'un autre type tagged. A moins que l'argument soit mis en -- type'class... et qu'il soit converti explicitement à l'utilisation =o/&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-style: italic; font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="font-family: trebuchet ms;font-family:trebuchet ms;"  id="mb_0"&gt;&lt;span style="font-size:85%;"&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:28:04: warning: no primitive operations for "T_Radial_Struct" after this line&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:34:14: this primitive operation is declared too late&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:56:14: operation can be dispatching in only one type&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:60:14: operation can be dispatching in only one type&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:62:14: operation can be dispatching in only one type&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:72:04: warning: no primitive operations for "T_Radial" after this line&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:74:49: expected type "T_Radial_Struct" defined at line 15&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:74:49: found an access type&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:80:13: this primitive operation is declared too late&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:81:13: this primitive operation is declared too late&lt;br /&gt;simple_video_handler_types.ads&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;:134:13: operation can be dispatching in only one type&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Ordre des opérateurs&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;simple_video_handler_types.adb&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;:307:29: "aliased" should be before "constant"&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Pragma unreferenced&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Pour avoir la paix avec le compilateur quand on est en train de coder et qu'on veut juste vérifier que "jusqu'à ce point une fonction compile", on peut utiliser la pragma unreferenced... Mais si on l'oublie après avoir tout codé, le compilo le voit... =o)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;simple_video_handler_types.adb&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;:410:55: warning: pragma Unreferenced given for "Data"&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Oublié de mettre "body" pour désigner un corps de package...&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;buffer_lines_list.adb:1:08: keyword "body" expected here [see file name]&lt;br /&gt;buffer_lines_list.adb:1:08: missing "body"&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Génial : j'ai mis Const à la place de constant&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;video_runner.adb:43:23: illegal abbreviation of keyword "constant"&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;&lt;&gt; à la place de /=&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;simple_video_handler_types.adb&lt;/span&gt;&lt;wbr  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;:928:27: "&lt;&gt;" should be "/="&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ma vie est belle&lt;/span&gt;, grâce aux gens de &lt;a href="http://www.gnat.com/"&gt;AdaCore/Act&lt;/a&gt;. Merci :-D&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&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/7608222-113302912515103575?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/113302912515103575/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=113302912515103575' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/113302912515103575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/113302912515103575'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2005/11/i-love-this-compiler.html' title='I --------- Love  --------- This ---------  Compiler !'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-113113424565064904</id><published>2005-11-04T20:23:00.000+01:00</published><updated>2005-11-27T11:22:09.286+01:00</updated><title type='text'>KCacheGrind, killer-tool...</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J'en avais parlé récemment, et je viens juste de récupérer mes screenshots de kCacheGrind.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Quoi qu'est-ce ?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;a href="http://kcachegrind.sourceforge.net/"&gt;KCacheGrind&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt; est un outil de visualisation des résultats de l'outil callgrind. Callgrind est un outil de &lt;a href="http://en.wikipedia.org/wiki/Profiling"&gt;profiling&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt; qui permet de savoir dans quelles fonctions votre programme passe son temps.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Comme j'ai la flemme de détailler la technique et que google et le man page de callgrind regorgent d'informations, je vais plutôt poster mes screenshots de KCacheGrind, pour montrer à quel point ce logiciel est pratique et&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt; agréable.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Après avoir lancé callgrind sur l'exécutable de mon projet, je lance kcachegrind sur le fichier résultat. Et voila l'application qui se lance :&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6068/476/1600/callgrind%20roxor.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/6068/476/400/callgrind%20roxor.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Intrigué, je cherche à comprendre à quoi tout ceci correspond. C'est facile. Les noms des fonctions sont dans les cases du dessin à droite, et dans la liste des fonctions à gauche. Le dessin qu'on voit, c'est en fait une sorte de partition du temps passé dans le programme, entre toutes les fonctions... Comme les fonctions en elles-même en appellent d'autres, on se retrouve avec des poupées russes. C'est très intéressant et même ludique. Je me suis vite pris au jeu de clic-cliquer partout sans trop savoir quoi faire.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je me rappelle que je suis là pour savoir où se trouvent les goulets d'étranglements de mon application. Je clic-clique donc sur les plus gros carrés et clic-clique encore jusqu'à trouver les endroits où ça coince.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Le Boulet...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Là, surprise, je trouve un énorme (!) goulet d'étranglement, qui me saute aux yeux. (Evidemment je n'ai pas pris de screenshot tellement la honte était grande).&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Explication : dans mon projet, pour faire du rendu 3d, j'utilise des shaders OpenGL (programmes exécutés par la carte vidéo). Pour les mettre en oeuvre, je me suis contenté de reprendre un package d'exemple présent dans le code que mon tuteur de stage m'avait donné au début du stage. J'ai rajouté des fonctions et des fonctions à ce package, jusqu'à ce qu'aujourd'hui il soit devenu totalement imbitable. Enfin dans Emacs, et sans le mode ECB.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Supposant qu'il s'agissait d'un code ultra-fonctionnel tout bien pensé, je ne me suis pas posé de question. Mais en fait j'ai eu tort. La bêtise que j'ai découverte c'est que je demandais l'index des variables uniformes et des attributs des programmes... &lt;span style="font-style: italic;"&gt;A chaque fois !&lt;/span&gt; Pour être clair, tout au long de la vie d'un fragment/vector program, les variables uniform et attribute sont accessibles et modifiables. Mais pour y accéder - en général, 99% du temps , pour les définir (écrire dedans) - il faut disposer de leur &lt;span style="font-style: italic;"&gt;numéro d'argument&lt;/span&gt;. Oui OpenGL c'est du très bas niveau. Tous les objets qu'on utilise sont définis par des indices.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Ces indices des arguments ne varient pas, ne changent pas, à moins qu'on recompile les programmes... Et mon programme d'exemple, ainsi que mon package de shaders, demandaient &lt;span style="font-style: italic;"&gt;à chaque utilisation&lt;/span&gt; à OpenGL de nous donner le numéro des variables...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Comme je le disais récemment, en général, les commandes OpenGL sont asynchrones. Ce n'est pas le cas du tout pour les opérations de lecture. Ainsi, mon programme forçait un flush du pipeline OpenGL à chaque modification des variables de shaders...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Tout cela grâce au dessin en boîte. =o)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Quand on ne peut plus... &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Ensuite, j'ai trouvé quelques autres idioties sans grandes répercussions sur les performances. Et j'ai fini par me trouver limité par 2 facteurs et j'ai (encore !) eu un surprise.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt; &lt;/div&gt; &lt;ul style="text-align: justify;"&gt;   &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Toutes les parties que j'aurais pu optimiser ne constituaient que 5 à 6% du temps d'exécution du programme. Il était totalement stupide de chercher à optimiser ces parties que je croyais critiques, avant de mesurer...&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;   &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je ne pouvais pas faire mieux. Dans le screenshot plus bas, la fonction qui prend presque 13% du temps (Get_Area_Index) n'est qu'une fonction de translation d'adresse. Cette fonction est la routine de base de l'architecture que j'ai implémentée dans ce programme. Et elle ne fait qu'une ligne : une conversion et une division. Et le compilateur l'inline déjà automatiquement (si je me rappelle bien, Gnat permet de sortir une version précompilée du code, où il on peut voir tous les checks, les instanciations silencieuse, les opérations implicites explicitées, et les fonctions inlinées indiquées). Au cas où c'était l'inline qui posait problème (en augmentant la taille du code), j'ai vérifié sans option d'optimisation, le résultat est pire.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;/ul&gt; &lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6068/476/1600/callgrind%20roxor%202.0.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/6068/476/400/callgrind%20roxor%202.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Où donc que ça coince ? &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;L'image ci-dessous montre juste en haut à gauche le temps passé dans chacun des &lt;a href="http://en.wikipedia.org/wiki/Executable_and_Linkable_Format"&gt;objets ELF&lt;/a&gt; en jeu pendant l'exécution de mon programme.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6068/476/1600/callgrind%20roxor%203.0.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/6068/476/400/callgrind%20roxor%203.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Comme on peut le voir (en haut à gauche) Mon programme passe son temps dans l'API que j'ai codée. Ou en tout cas, il y a énormément plus d'appels à des fonctions de mon API pour la gestion des données à afficher que pour l'affichage même (libGL.so, libGLCore.so). C'est une surprise, je pensais que le facteur limitant serait le GPU, et que c'était à cause de lui que ça ramait... En fait, le GPU va très bien, c'est dans la mémoire système et sur le CPU qu'on travaille beaucoup trop. Avec un peu de recul, le pourquoi du comment est évident.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;On casse tout et...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Ainsi, à la recherche des fonctions primitives qui prennent plus de 10% du temps, je n'ai pas pu en trouver une seule dans l'API qui puisse être regroupée, factorisée, améliorée, et qui en vaille la peine. Je n'ai pas trouvé comment faire mieux. Mais l'idée que mon programme passe plus de temps sur le CPU que le GPU me turlupinait, alors j'ai mis en cause toute mon architecture.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;/div&gt; &lt;ul style="text-align: justify;"&gt;   &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je pensais devoir stocker toutes les données pour connaître l'état exact à l'instant T des informations que je venais de dessiner&lt;br /&gt; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;   &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;je pensais aussi devoir avoir différents niveaux de granularités et j'avais axé la performance sur la granularité la plus petite. Ainsi pour dessiner un gros paquet d'informations (la majorité des arrivées... mais je l'ignorais) cela me prenait 4 à 5 fois plus de travail - recherche, translation d'adresse, mise à jour mémoire application &lt;span style="font-style: italic;"&gt;puis &lt;/span&gt;mémoire vidéo - que ce que je pouvais faire en fait. Mais le problème était que mon architecture était &lt;span style="font-style: italic;"&gt;de base&lt;/span&gt; trop prévue pour être flexible.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;/ul&gt; &lt;div style="text-align: justify;"&gt; &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Toute cette réflexion je l'ai remâchée à un collègue qui m'a expliqué qu'on s'en foutait en général de la petite granularité et, que la majorité du temps on recevait des gros chunks de données. Bon.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J'ai donc décidé de tout casser il y a de ça une semaine. Je change totalement la structure des données, et axe désormais mes traitements sur les gros chunks, pousse le maximum d'informations vers la carte vidéo (quitte à faire les fonctions bien chiantes pour la relecture et le débug...).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;C'est pour ça que j'ai porté le code de gpgpu.org en Ada, pour avoir les outils et m'entraîner avec ces techniques.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Mais sinon, KCacheGrind ?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Tout de même fasciné par l'outil j'ai continué à m'en servir, ne serait-ce parce que je le trouve sympa, et que la procrastination est une tentation à laquelle il est difficile de résister =oD...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je me suis intéressé aux petites fonctionnalités et à une autre, beaucoup plus &lt;span style="font-style: italic;"&gt;cool&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Les listes des &lt;span style="font-style: italic;"&gt;callees&lt;/span&gt; et de &lt;span style="font-style: italic;"&gt;callers&lt;/span&gt; avec leurs statistiques assorties, permettent de naviguer dans les &lt;span style="font-style: italic;"&gt;poupées russes&lt;/span&gt; de haut en bas, et de bas en haut sans trop repasser par le graphiques des boîtes imbriquées qui sont parfois trop denses et ne contiennent pas de &lt;span style="font-style: italic;"&gt;statistiques globales d'une fonction&lt;/span&gt; par exemple&lt;span style="font-style: italic;"&gt;. &lt;/span&gt;Voila ce que ça peut donner :&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6068/476/1600/callgrind%20roxor%204.0.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/6068/476/400/callgrind%20roxor%204.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Et puis j'ai découvert, &lt;span style="font-style: italic;"&gt;LE&lt;/span&gt; truc qui fait la différence et qui rend l'outil plus qu'utile, mais &lt;span style="font-style: italic;"&gt;fun&lt;/span&gt;. C'est l'affichage du &lt;span style="font-style: italic;"&gt;VRAI&lt;/span&gt; callgraph (graphe d'appel) sous forme de graphe &lt;span style="font-style: italic;"&gt;noeud-&gt;liens&lt;/span&gt;. Si le système de &lt;span style="font-style: italic;"&gt;poupées russes&lt;/span&gt; est très intuitif pour les performances des différents blocs, on trouvera utile le graphe d'appel pour savoir qui conduit à quoi, en quelle proportion, et si on a des cycles, des fonctions "globales"...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je pense qu'une ou deux images feront plus court ici que des pages d'explications (et puis je fatigue). Voila ce qu'on peut obtenir à partir du même code et du même exécutable (et du même log il me semble).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6068/476/1600/callgrind%20roxor%205.0.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/6068/476/400/callgrind%20roxor%205.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;On peut voir la représentation &lt;span style="font-style: italic;"&gt;verticale&lt;/span&gt; du graphe d'appel.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Quelques notes :&lt;/span&gt;&lt;br /&gt;&lt;/span&gt; &lt;/div&gt; &lt;ul style="text-align: justify;"&gt;   &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;La fonction qu'on a sélectionné pour être le &lt;span style="font-style: italic;"&gt;centre d'intérêt&lt;/span&gt; du graphe est un peu ombrée.&lt;br /&gt; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;   &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;On a une carte générale du graphe et une vue un peu plus zoomée.&lt;br /&gt; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;   &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;On peut changer l'inclinaison du graphe :&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;   &lt;ul&gt;     &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;de gauche à droite&lt;br /&gt;   &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;     &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;du haut vers le bas (le screenshot ci-dessus)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;     &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;le mode &lt;span style="font-style: italic;"&gt;circulaire&lt;/span&gt; (le screenshot ci-dessous)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;   &lt;/ul&gt;   &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;On peut réduire le graphe en sélectionnant des fonctions plus bas dans le graphe.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;   &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;On peut continuer à parcourir le graphe d'appel, toutes les informations se mettent en correspondance. Si, par exemple, on choisit un élément dans le graphe d'appel, les &lt;span style="font-style: italic;"&gt;poupées russes&lt;/span&gt; vont se mettre sur la fonction sélectionnée.&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/6068/476/1600/callgrind%20roxor%206.0.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/6068/476/400/callgrind%20roxor%206.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Petit détail un peu ennuyeux&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J'ai découvert la fonctionnalité des jolis graphes assez tard (quand ils ne m'étaient plus vraiment utiles). KCacheGrind me disait que si je voulais pouvoir les afficher, il fallait dot et graphviz... J'avais occulté ce problème car l'outil me contentait. Et quand j'ai finalement voulu l'essayer je me suis retrouvé face à ce petit problème : graphviz, qui est un outil qui m'a l'air assez connu, n'est pas packagé par la communauté fedora linux, ou en tout cas ne se trouve pas dans leur repository de base.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Le problème s'est vite résolu, car sur le site de graphviz, on peut trouver tous les paquets rpm pour Fedora Core 4 (la bonne en plus) dont on a besoin. Ils s'installent sans problème et KCacheGrind fonctionne très bien ensuite, aucun problème.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;C'est juste dommage, ceux qui n'ont pas &lt;span style="font-style: italic;"&gt;Teh Intarwayb&lt;/span&gt; au boulot toute la journée, ou qui ont seulement accès à un miroir Fedora, sont condamnés à se priver d'une fonctionnalité de cet outil, pourtant si agréable. =o)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Rien de bien méchant, n'est-ce pas ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-weight: bold;"&gt;Conclusion &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Cet outil, il est bien, stable, intuitif et simple. Que demander de plus ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Si vous avez encore un doute, c'est un outil KDE, donc derrière c'est du Qt. Voila qui devrait aider à convaincre &lt;a href="http://yogiaoxford.blogspot.com/"&gt;le dernier récalcitrant blond un peu frisé au fond&lt;/a&gt; :-D&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-113113424565064904?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/113113424565064904/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=113113424565064904' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/113113424565064904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/113113424565064904'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2005/11/kcachegrind-killer-tool.html' title='KCacheGrind, killer-tool...'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-113076148340693319</id><published>2005-10-31T12:57:00.000+01:00</published><updated>2005-11-03T23:44:57.606+01:00</updated><title type='text'>General Purpose GPU</title><content type='html'>&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Il y a certains temps, je parlais ici d'OpenGL et des shaders, des progrès effectués ces dernières années et de mon impatience à voir d'autres applications émerger.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Gpgpu Didactique&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Les gens de &lt;a href="http://www.gpgpu.org/"&gt;gpgpu.org&lt;/a&gt; travaillent dans ce sens. Le site dispose d'un nombre important d'articles, résumés de recherches, ou encore présentations (ppt/pdf) concernant l'utilisation d'un GPU pour des calculs plus "généraux" que &lt;span style="font-style: italic;"&gt;juste&lt;/span&gt; du dessin 3D.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Bien qu'il faille quelque peu fouiller pour trouver les meilleurs articles, les présentations sont très didactiques et complètes, introduisent à l'architecture des cartes video de façon bien plus didactique et "généraliste" que la plupart des articles de programmeurs de jeux video que j'ai pu lire (et j'en ai lu des dizaines).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Une fois toute l'architecture des cartes video digérée, on peut passer très vite à la pratique, en utilisant les classes mises à disposition sur leur site, en C++/OpenGL. Le code est extrêment clair, simple, et didactique, commenté à profusion et une connaissance quasiment nulle du C++ (comme la mienne) permet tout de même de comprendre sans aucun problème &lt;span style="font-style: italic;"&gt;comment faire&lt;/span&gt; !&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Parce qu'en général, en ayant fait un peu de 3d, on a des structures assez rigides dans la tête et même si on voit des possibilités se dégager avec les Shaders, on a pas forcément l'intuition pour comprendre les concepts de base de GpGPU. Par exemple, le rendu multi-passe était pour moi un vrai casse tête sans nom, ainsi que le render-to-texture, ou encore leur notion de kernel ou de stream. (noyau et flux me semblent des traductions fort appropriées =o)).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Maintenant, avec leur présentation, remâchée, relue plusieurs fois, je peux définir :&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt; - un &lt;span style="font-weight: bold;"&gt;stream&lt;/span&gt; : un ensemble de données séparées, traitables en parrallèle, et n'ayant aucune dépendance interne.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt; - un &lt;span style="font-weight: bold;"&gt;kernel&lt;/span&gt; : une opération qu'on applique sur un élément d'un flux.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;On a de plus en plus besoin d'effectuer un rendu vers une texture, afin de pouvoir réutiliser le résultat de ce rendu pour dans d'autres calculs. La méthode est simple, et repose sur quelques concepts :&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;div style="font-family: trebuchet ms;"&gt; &lt;/div&gt;   &lt;ol style="text-align: justify; font-family: trebuchet ms;"&gt; &lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Texture = Array&lt;/span&gt; : Une texture correspond au concept de tableau dans la programmation "classique". On alloue une texture pour faire tenir nos données.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Fragment Program = Computational Kernel : &lt;/span&gt;un programme de fragment peut-être pensé comme un petit kernel de calcul qui est appliqué en parrallèle à plusieurs fragments (éléments d'un stream) en même temps.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;One-to-one Pixel to Texel Mapping&lt;/span&gt;:&lt;/span&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Data-Dimensioned Viewport&lt;/span&gt; : On a besoin (en général) d'un mapping "bijectif" de un pixel vers un &lt;a href="http://fr.wikipedia.org/wiki/Texel_%28Image_Num%C3%A9rique%29"&gt;texel&lt;/a&gt;. Ceci afin de s'assurer que l'on a effectué le calcul demandé sur &lt;span style="font-style: italic;"&gt;chaque&lt;/span&gt; élément de la texture. En configurant notre viewport avec les dimensions de notre texture "destination" et en dessinant un Quad (rectangle en OpenGL) ajusté à la taille de l'écran, on s'assure que chaque pixel de notre texel (=o)) est généré et traité dans le fragment program... (oui, on dirait une traduction google mais non, je suis juste nul en anglais).&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Orthographic Projection : &lt;/span&gt;On définit en général un matrice de projection orthogonale avec un repère [-1;1] sur les axes X et Y. Ca permet d'avoir une correspondance simple entre les pixels et les texels.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li style="font-weight: bold;"&gt;&lt;span style="font-size:85%;"&gt;Viewport-Sized Quad = Data Stream Generator : &lt;span style="font-weight: normal;"&gt;pour pouvoir exécute des fragments programs, on a besoin de générer des pixels. Dessiner un Quad de la taille du viewport génère un fragment pour chaque pixel de notre texture de destination. Chaque fragment est traité identiquement par le fragment program. &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="font-weight: bold;"&gt;&lt;span style="font-size:85%;"&gt;Copy To Texture = feedback : &lt;span style="font-weight: normal;"&gt;nous avons juste invoqué notre calcul en appliquant un fragment program sur une quad de la taille du viewport. Les résultats sont maintenants dans le framebuffer. Pour les stocker, on copie les données du framebuffer dans une texture. Ainsi on peut réutiliser ces résultats comme source pour l'affichage ou pour d'autres calculs.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt; &lt;/ol&gt;    &lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Ce code C++ est d'une simplicité et d'une clarté telle que la conversion en Ada m'a pris une après-midi seulement (en codant propre).&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Et non, seulement le code est clair mais il est &lt;span style="font-style: italic;"&gt;didactique&lt;/span&gt;. Il reprend dans l'ordre toutes les étapes nécessaires pour dessiner quelque chose avec OpenGL, plaquer une texture, charger/compiler/linker un shader... Et on voit même où poser nos propres améliorations pour faire ce qu'on veut.&lt;br /&gt;&lt;br /&gt;En plus, le code est gavé de commentaires. Et bien qu'il y en ai presque un par ligne, ce ne sont pas des commentaires ASM. Leurs commentaires permettent presque de comprendre le code sans le lire =o).&lt;br /&gt;&lt;br /&gt;Bref, pour ma part, rien de trop, rien ne manque. Chapeau.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Great expectations&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Les drivers 80.x de NVidia sont sortis récemment pour windows. Apparemment, la nouveauté que j'attendais le plus est implémentée et a l'air de fonctionner (pas trop vu de plaintes sur les forums NVidia).&lt;br /&gt;&lt;br /&gt;Il s'agit de drivers OpenGL multithreadés. Oui, c'est une nouveauté, aussi étonnant que ça peut paraître. OpenGL est basé sur un modèle de machine à état. On pourrait imaginer que les fonctions de l'API sont des fonctions statiques du contexte OpenGL. Les états sont globaux.&lt;br /&gt;&lt;br /&gt;Plus clair, un exemple. Quand on veut sélectionner une texture à appliquer, on lie le contexte courant à un numéro de texture (réservé plus tôt). On est contraint de faire ceci pour que le serveur sache que le client souhaite utiliser cette ressource. Les Texture Objects, les Vertex Buffer Objects, Pixel Buffer Objects, et Framebuffer Objects sont en général des objets serveurs. Cela évite le transfert client-&gt;serveur quand on veut s'en servir. Donc quand on veut sélectionner un Vertex Buffer, il faut appeler glBindBuffer. Tous les threads appelant du programme appelant OpenGL partageront cet état.&lt;br /&gt;&lt;br /&gt;A priori, NVidia avait commencé à travailler sur ce problème avec leur bibliothèque tls (thread local s*). Mais j'ai essayé plusieurs fois avec les tâches Ada (qui sont codées par dessus les pthreads dans Gnat sous Linux), et j'arrivais toujours à provoquer une erreur OpenGL voire de gros plantages.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Asynchrone&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Si leur bibliothèque est désormais bien multitâches (et donc que je vais pouvoir utiliser l'hyper-threading de mon P4 et les fonctionnalités de parallélisme d'Ada), j'espère aussi qu'ils ont rendu certaines commandes totalement asynchrones.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;span style="font-family: trebuchet ms;font-size:85%;" &gt;&lt;br /&gt;&lt;/span&gt; &lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;En réalité, la majorité des commandes OpenGL sont asynchrones. Lorsqu'on appelle une commande, celle-ci est envoyée au serveur (ou à l'api client) et en général la fonction rends la main tout de suite, et le programme continue. Les commandes sont exécutées dans l'ordre donné, mais on n'a pas le contrôle absolu du moment de leur exécution. La seule chose qu'on peut faire pour &lt;span style="font-style: italic;"&gt;forcer&lt;/span&gt; les commandes à être exécutées, c'est d'appeler glFlush() qui va demander l'exécution des commandes encore dans le pipeline. On peut aussi, pour être vraiment sûr que TOUTES les commandes sont exécutées, utiliser l'appel bloquant glFinish(), mais c'est peu conseillé.&lt;br /&gt;&lt;br /&gt;Mais certaines fonctions malheureusement ne renvoient pas ou ne permettent pas de continuer pendant qu'elle s'exécutent. Par exemple, glReadPixels est une commande assez lourde (lecture de pixels, transfert, grosse utilisation de ressources et de bande passante). Avec une extension récente, glReadPixels() a été rendue asynchrone, grâce aux possibilités de DMA (dites ce que vous voulez transférer, et partez faire ailleurs). Cela fait gagner un temps fou quand on fait du rendu multi-passe, sur des ensembles différents. Le tout est d'éviter de mapper (rendre accessible en lecture/écriture aléatoire) une zone serveur.&lt;br /&gt;&lt;br /&gt;Comme je dois travailler sur énormément d'éléments assez petits (qui ne rempliraient pas le cache de vertex/fragment processing de façon efficace), j'ai 2 solutions : tout casser mon code pour coder une sorte d'algo d'allocation pour utiliser le cache au maximum (sans même être sûr que c'est le point limitant) ou alors laisser OpenGL s'occuper de remplir son cache en me voyant appeler 600 fois le même programme sur différentes zones.&lt;br /&gt;&lt;br /&gt;Bref, un peu d'espoir de pouvoir essayer bientôt de faire joujou avec ces nouvelles "features".&lt;br /&gt;&lt;br /&gt;En attendant, je me prends la tête pour mon truc de rendu multi-passe en pensant pouvoir faire exploser les 320 millions de points par seconde de mon ancien moteur. Ou au moins rendre l'archi plus propre, en évitant la tonne de calculs inutiles que je faisais jusque là =o).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Auto-Conversation, Never-starting-projects&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Je viens juste de commencer à travailler sur un petit module Ada pour lire/écrire du &lt;a href="http://www.ietf.org/rfc/rfc2245.txt"&gt;iCalendar&lt;/a&gt;. Juste un peu de lecture du format et une petite idée sur une architecture simple pour implémenter le parseur... Passer par Aflex-Ayacc serait bien mais trop lourd, et je ne comprends rien à &lt;a href="http://unicoi.kennesaw.edu/ase/ase02_02/tools/usafa/adagoop/"&gt;AdaGOOP&lt;/a&gt;... Alors en attendant, je vais tester les &lt;a href="http://www.infeig.unige.ch/support/ada/gnatlb/g-spitbo.html"&gt;expressions régulières de GNAT&lt;/a&gt; qui ont l'air de ressembler de loin à &lt;a href="http://www.dmitry-kazakov.de/match/match.htm"&gt;Snobol&lt;/a&gt; (que je ne connais pas mieux), et voir ce qu'on peut en sortir. Et si un jour ma motivation est grande je regarderai du côté de AdaGOOP (qui manque furieusement d'exemples didactiques à mon sens).&lt;br /&gt;&lt;br /&gt;Bah, le bon gros vrai projet intéressant et technique, ce serait un xslt-processor en Ada... Mais bon... Depuis quand je sais coder ? Il me suffirait peut-être de regarder le code d'un parseur simple, basé sur SAX... Sans trop de récursivité-mal-de-crâne...&lt;br /&gt;&lt;br /&gt;Si ça se trouve je vais même prendre goût aux bindings C et au Python et porter plein de trucs vers Ada, tellement c'était pas trop dur avec OpenGL. =o)&lt;br /&gt;&lt;br /&gt;Comment ça &lt;span style="font-style: italic;"&gt;digression&lt;/span&gt; ?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Edit - Pour Jb&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jb, (dit aussi Monsieur Borborygme dans les milieux huppés du vinaigre Puget(tm)) m'a posé une question intéressante (je déforme à peine le propos histoire de nettoyer les erreurs de grammaire les plus grossières)...&lt;br /&gt;&lt;/span&gt;&lt;blockquote style="color: rgb(153, 153, 255);"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Est-ce que j'ai bien compris : les rendus multi-passes pourront se faire en parallèle ? Mais si elles sont dépendantes ces passes ?&lt;br /&gt; &lt;br /&gt;&lt;span style="color: rgb(204, 255, 255);"&gt;T'as vu je fais bien le mec qui suit et qui est un peu au courant mais complètement à côté de la plaque (ma question est toutefois vrai)&lt;br /&gt;&lt;br /&gt;Je ne vais pas mettre de Cokpit, ce serait mal placé. Dr Lionel et Mr Twouisteux, je m'en doutais un peu. A bientôt sur une autre passerelle de Massy...&lt;br /&gt;&lt;br /&gt;Hé oui. A digression, digression et demi (quoiqu'il s'agisse plus de hors-sujet durable de ma part que d'un refus de te prendre au sérieux).&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:85%;"&gt;Pour te répondre, si on a besoin de travailler avec des passes dépendantes, il faut appliquer une bonne partie des cours théoriques de système qu'on a vu en 3ème année de FIIFO. Parallélisme maximal, dépendances des données (pas de dépendances de processeur/registres... le parrallélisme du GPU est un parallélisme des données), conflits... Tout ça.&lt;br /&gt;&lt;br /&gt;J'avoue que d'avoir réalisé &lt;span style="font-style: italic;"&gt;avec brio =o) &lt;/span&gt;le projet de rattrapage de système aide un peu =o).&lt;br /&gt;&lt;br /&gt;Venez voir &lt;a href="http://www.graphicshardware.org/presentations/heirich-presentation-gh05.pdf"&gt;ce document&lt;/a&gt; (pdf) pour des informations plus détaillées et plus poussées sur le rendu multi-passes avec des passes dépendantes.&lt;br /&gt;&lt;br /&gt;N'hésitez pas pour les questions.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-113076148340693319?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/113076148340693319/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=113076148340693319' title='4 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/113076148340693319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/113076148340693319'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2005/10/general-purpose-gpu.html' title='General Purpose GPU'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-112984234740218427</id><published>2005-10-20T22:40:00.004+02:00</published><updated>2005-10-21T00:12:43.853+02:00</updated><title type='text'>Python : first sight</title><content type='html'>&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Cela fait presque une semaine maintenant que je travaille sur un binding OpenGL avec les derniers drivers nVidia.&lt;br /&gt;&lt;br /&gt;Jusque-là je travaillais sur d’anciens headers datant de 2003, qui me donnaient entière satisfaction, car j’ignorais l’avancée récente des technologies graphiques. Avec la découverte de &lt;a href="http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt"&gt;gl_framebuffer_object&lt;/a&gt; et &lt;a href="http://oss.sgi.com/projects/ogl-sample/registry/ARB/pixel_buffer_object.txt"&gt;gl_pixel_buffer_object&lt;/a&gt;, et autres sucreries, il m’a fallu me remettre en cause.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Un binding OpenGL ?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;En C pour travailler avec OpenGL il « suffit » de faire #include &lt;gl  style="font-family:trebuchet ms;"&gt; et à la rigueur la même chose pour le header de glut quand on travaille avec Glut.&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-size:85%;" &gt;&lt;gl  style="font-family:trebuchet ms;"&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-size:85%;" &gt;&lt;gl  style="font-family:trebuchet ms;"&gt;Les choses ses corsent quand on veut faire la même chose en Ada. On ne peut pas faire #include &lt;blabla.h&gt;. On ne peut pas appeler une fonction C sans au préalable l’avoir déclarée, avec les types corrects et avoir déclaré qu’il s’agissait d’une fonction importée d’un autre langage…&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-size:85%;" &gt;&lt;gl  style="font-family:trebuchet ms;"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-size:85%;" &gt;&lt;gl  style="font-family:trebuchet ms;"&gt;&lt;blabla.h&gt;En gros, si on a une fonction dans une DLL (j’ignore si ça marche aussi avec une bibliothèque statique) il faut procéder ainsi :&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl  style="font-family:trebuchet ms;"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style="font-family: trebuchet ms;font-family:trebuchet ms;" &gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt; Supposons qu’en C on ait la fonction : &lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: center; font-family: trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt; unsigned char cEstCoolTaVie(int genre, float crari);&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;&lt;ul  style="font-family:trebuchet ms;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;En Ada on déclarera (si on le fait à la main) :&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;&lt;div style="text-align: center;"&gt;&lt;span style=";font-size:85%;" &gt;&lt;gl&gt;&lt;blabla.h&gt;function C_Est_Cool_Ta_Vie(Genre : Integer ; Float : Crari) &lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-size:85%;" &gt;&lt;gl&gt;&lt;blabla.h&gt;return Interfaces.C.unsigned_char;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul  style="font-family:trebuchet ms;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt; Il faudra ensuite écrire dans le source Ada&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: center; font-family: trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;Pragma Import (C, C_Est_Cool_Ta_Vie, "cEstCoolTaVie");&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: trebuchet ms;font-size:85%;" &gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify; font-family: trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;span style="font-style: italic;"&gt;A propos de la taille du code&lt;/span&gt; (le double de lignes ici) : Ada est un langage plus verbeux, c’est sûr. Mais en général, comme on a moins de vérifications à ajouter dans le code en permanence – beaucoup sont faites par défaut par le langage – le code est souvent plus court et concis.&lt;br /&gt;&lt;br /&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;span style="font-style: italic;"&gt;A propos de la notation&lt;/span&gt;, qui est critiquable (majuscule &lt;span style="font-style: italic; font-weight: bold;"&gt;ET&lt;/span&gt; underscore ?) : c’est une convention de style du langage ou du compilateur. On est pas obligé de la suivre (la casse n’a aucune importance en Ada), mais la plupart des développeurs Ada y sont habitués, et les IDE Ada font le passage en majuscule automatiquement. On peut aussi utiliser gnatpp (pp pour pretty print), outil en ligne de commande assez configurable.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Les problèmes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;Bien, maintenant si vous voulez regarder un instant un header &lt;a href="http://oss.sgi.com/projects/ogl-sample/ABI/glext.h"&gt;glext.h&lt;/a&gt; sur lequel je travaille en ce moment.&lt;br /&gt;&lt;br /&gt;Il fait plus de 5000 lignes et c’est un header C, avec les sympathiques instructions au préprocesseur pour définir des constantes et garder du code ou pas… Vraiment du code &lt;span style="font-style: italic;"&gt;comme je l’aime&lt;/span&gt; : efficace - cà ! en performance c’est sûr… -, et compréhensible.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;Ce qu’on peut voir c’est que « globalement », on a 3 parties intéressantes dans chaque header gl.h et glext.h :&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;des redéfinitions de types C (typedef), préfixés en GL, collé. &lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;span style="font-style: italic;"&gt;Par exemple&lt;/span&gt; : GLint, GLuint, GLubyte, GLfloat…&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;des définitions de constantes « en dur » à l’aide de #define. Cela veut dire qu’en C ou en C++, à la précompilation le nom des constantes qu’on aurait pu insérer dans notre code sera remplacé « textuellement » par la valeur définie. Les constantes ont pour charte d’être entièrement en majuscules et les mots sont séparés par des caractères underscore ‘_’. &lt;span style="font-style: italic;"&gt;Par exemple&lt;/span&gt; : GL_TRUE, GL_FALSE, GL_STREAM_DRAW.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;des fonctions. Préfixées en &lt;/span&gt;&lt;span style=";font-size:85%;" &gt;gl&lt;/span&gt;&lt;span style="font-size:85%;"&gt; (minuscule) et ensuite avec un style « dromadaire ».&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt; &lt;span style="font-style: italic;"&gt;Par exemple&lt;/span&gt; : glDrawBuffers, glCreateShaderProgram.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;Si on suppose qu’on veut séparer les fonctions OpenGL de base des extensions, on se retrouve avec &lt;span style="font-style: italic;"&gt;4 catégories d’éléments&lt;/span&gt;.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl face="trebuchet ms"&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;Mon job cette semaine, après avoir analysé et tergiversé sur les fonctionnalités récentes que j’allais utiliser pour multiplier la vitesse de l’appli OpenGL sur laquelle je travaille, c’est de transformer tout ce fatras de headers C de façon à pouvoir utiliser OpenGL en Ada, y compris les dernières extensions. Et, bien sûr il faut que l’expérience soit reproductible : les headers changent en fonction des constructeurs et des versions et des extensions…&lt;br /&gt;&lt;br /&gt;Il faut donc que le processus de génération du binding soit automatisé au maximum.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;gl&gt;&lt;blabla.h&gt;Première étape : le gros outil pas terrible&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;Pour écrire un binding vers du C en Ada, en général on se pédale les signatures de fonction à la main, ainsi que les pragma import.&lt;br /&gt;&lt;br /&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;Mais ici, vu la taille du header, même pas la peine d’y penser. Alors j’ai cherché s’il existait des solutions, si possible « éprouvées ». J’étais très enthousiaste, car mon tuteur m’avait dit que le header qu’il m’avait passé, et dont je me servais depuis un mois, et qui fonctionnait très bien à quelques retouches près, avait été généré avec un « logiciel » appelé c2ada.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;Mon enthousiasme s’est vite dégonflé. Le makefile de base, pour compiler c2ada, est assez mal fait et il faut un peu mettre la main au cambouis. Ensuite une fois qu’on a son exécutable – non sans des dizaines de warning à la compilation et même à l’édition de liens – il faut encore bidouiller $PYTHONPATH pour arriver à le lancer pour la première fois. J’ai essayé chez moi sous Windows, c’est encore pire… Bon, un après-midi perdu comme ça…&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;Le résultat fourni par c2ada est plutôt décevant. D’abord il lui faut inclure toutes les dépendances et donc en générer des sources Ada. Ainsi, glext.h faisant référence à des variables et types définis dans gl.h, il faut faire un petit script pour ajouter #include "gl.h" au début du fichier.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;Les fonctions dans le header C sont déclarées (avec des APIENTRYP WINGDI et GLAPI…), puis plus tard dans le fichier on trouve leur signature. Bien sûr, c2ada ne retrouve pas ça tout seul. A priori, on dirait presque qu’il traduit ligne par ligne. Il faut donc encore un script pour retrouver les correspondances et virer les APIENTRYP et autres joyeusetés dédiées au préprocesseur, dont on a rien à faire en Ada.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;Résultat, après avoir bataillé sec, on se retrouve avec plusieurs fichiers Ada, même pas compilables et bien sales.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;Il faut donc se contenter du résultat. Bon en réalité je résume, parce que j'ai essayé au maximum d'utiliser les fonctionnalités &lt;span style="font-style: italic;"&gt;proposées&lt;/span&gt; par c2ada, pour limiter la casse.&lt;br /&gt;&lt;br /&gt;Mais encore une fois, il va être nécessaire de passer un script, mais sur du code Ada cette fois-ci.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;gl&gt;&lt;blabla.h&gt;Deuxième étape : l’outil puissant&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;En partant de ce code Ada tout pourri généré par c2ada, il me faut arriver à 4 « beaux » paquetages, contenant chacun les éléments qu’il faut.&lt;br /&gt;&lt;br /&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;Il faut aussi que soit respectée la Convention_De_Nommage_Ada, ce qui met en conflit les types, les fonctions, et les constantes, très proches "graphiquement". D’où l’intérêt des paquetages séparés.&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;br /&gt;Bien sûr les types ne sont pas convertis comme il faut par défaut. Il faut virer la dépendance à stddef.h&lt;stddef.h&gt; et changer les ptrdiff_t pour ce que ça peut représenter… Les types contenus dans gl.h et glext.h peuvent se recouvrir, il faut les fusionner pour ne pas avoir de déclaration en double.&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;J’en passe et des meilleures...&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Alors je me lance dans l’écriture d’&lt;span style="font-weight: bold;"&gt;un script Python&lt;/span&gt; pour faire tout ça. Oui, &lt;span style="font-weight: bold;"&gt;Python&lt;/span&gt;. En général je n’aime pas trop les langages de script. Pas typés statiquement, trop "je code à l’arrache et on verra" (mais on ne voit jamais en fait) et lents.&lt;br /&gt;&lt;br /&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Mais la &lt;span style="font-style: italic;"&gt;sagesse populaire&lt;/span&gt; dit : chaque langage a son utilité. Ou plutôt chaque type de langage a son champ d’utilité.&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Or, pour ce que j’ai à faire j’avais besoin :&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;d’un bon système pour détecter les expressions régulières&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;de pouvoir faire relire le code =o)&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt; de pouvoir coder assez vite sans avoir besoin de la vérification apportée par le typage&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt; de fonctions de traitement de chaînes de caractères et d’entrées-sorties, simples et directes&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Alors je suis parti d’un script qu’avait déjà commencé à coder mon collègue pour « Adaifier » les fonctions… J’avais sous la main le bouquin « Introduction à Python » et l’aide en ligne Python. Et j’avais cet exemple de code qui faisait la majorité de ce que j’aurais à faire :&lt;br /&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;compilation d’une regex&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;parcours du fichier source&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;match de la regex&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;reformatage ou autre&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Passée la première phase de bidouille, j'ai très vite et très facilement compris comment ça foncitonne. Du coup en une journée j'adapté mes regex à mon code, fait des expressions « récursives » - terme bien pompeux par rapport à la réalité : il s’agissait juste de matcher des expressions dans des expressions dans des expressions, en appelant successivement des regex différentes… - testé, recommencé, ajouté encore des regex, encore des conditions, encore des fonctionnalités. On est loin des grammaires...&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Ca allait &lt;span style="font-style: italic;"&gt;très vite&lt;/span&gt; et j’ai pris plaisir à coder aussi simplement. Tout ce dont j’avais besoin était sous la main : liste, map, expressions régulières, traitement de chaînes flemmard-friendly, fichiers, et je pouvais très vite tester, regarder, modifier, tester, regarder, modifier…&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Encore avant hier, j’étais un peu effrayé par la simplicité apparente du langage, alors j’avais vaguement lu quelques notions de syntaxe Python et c’est tout. Voyant les codes bizarres que mes camarades pythonistes postaient de temps en temps sur IRC (la vraie vie), je me disais qu’en fait il s’agissait plus d'un perl bis/beurkque d'un « bon langage simple ». Je m’étais trompé. Une fois de plus ça m’apprendra à penser/supposer sans tester.&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;J’avais déjà fait du « script » assez longtemps et pensais avoir fait le tour. Franchement vbs (Microsoft ASP) et vba (Microsoft Office) et javascript (dans les DOM HTML et SVG) étaient vite devenus pour moi des boulets plutôt que des outils appréciables qui auraient du faire gagner du temps, avec lesquels je n’ai que rarement apprécié coder. Et encore Javascript restait *relativement* intéressant parce qu’on pouvait manipuler le DOM SVG assez facilement.&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Alors qu’en Python, j’ai l’impression que tout est simple, déjà là. Au point même que j’avais du mal à m’enlever de la tête la question suivante : « à part pour les applications de performances très très pointues ou encore pour des applications sûres, à quoi peuvent servir les autres langages après Python ? ». Peut-être qu’on fait trop de développement « simples » en C ou C++ juste « parce que ».&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Le même argument vaut pour Ada ou Eiffel : j’ai l’impression que peu de décideurs et de développeurs se posent la question « le bon outil pour le bon job ». Je connais peu C++ mais est-on obligé de l’utiliser PARTOUT ? Si je veux écrire un logiciel de façon ultra-structurée, sûre (éviter trop d’overflow) ; passer mon temps à coder (après la phase de conception bien sûr) plutôt qu’à débugger ; avoir immédiatement le multi-tâches, des moniteurs en 3 lignes de code, des objets protégés… Gérer la mémoire finement via Storage Pool et ne pas trop m’inquiéter pour les fuites mémoire… Si je veux tout ça, je me tournerai vers Ada.&lt;br /&gt;&lt;br /&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Si je veux de l’ouverture, pouvoir utiliser toutes les bibliothèques C++ du marché, organiser mon code un peu comme je veux... J’utiliserai C++.&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Peut-être qu’en avançant plus dans le Stroustrup, d’autres arguments de choix me viendront…&lt;br /&gt;&lt;br /&gt;En tout cas, l'argument "je n'arrive pas à recruter des programmeurs Ada qualifiés" est franchement fallacieux. L'apprentissage d'Ada est très rapide. En 2 semaines on est formé à l'essentiel. Et ensuite, des revues de code, quelques petits projets simples proches du sujet du travail. En général c'est plus que suffisant. Ada et Eiffel sont, par leurs contraintes et la qualité de leurs compilateurs, des langages qui s'apprennent presque "tout seul". En tout cas, très rapidement.&lt;br /&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;A quand une front/backend &lt;a href="http://www.swig.org"&gt;Swig&lt;/a&gt; pour Ada, ou encore un binding maison pour intégrer Python dans une application Ada ? Je vais regarder du côté de &lt;a href="http://www.adacore.com/gnattools_gps_ide.php"&gt;GPS&lt;/a&gt;.&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Conclusion : une très bonne expérience&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Ainsi, à la fin de cette journée, il me reste une impression de grand plaisir à coder, comme après une bonne journée de codage Ada.&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Le script n’est pas fini, il fait déjà 400 lignes et fait déjà énormément de travail. Je l’ai étendu avec plein de regex (expressions régulières), et des conditions des plus en plus compliquées, et ça fonctionne encore sans que mon cerveau n’explose ou que je ressente le besoin de « partitionner » ou ranger le code (je commente bien sûr).&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Seule remarque : malgré tout je trouve que l’indentation pour les blocs, même si c’est une idée intéressante, c’est &lt;span style="font-weight: bold;"&gt;PITA&lt;/span&gt; =o).&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;En deux jours j’ai réussi à améliorer/nettoyer mon binding généré de 90%. J’en suis même au point que le code généré compile sans même un warning.&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;Comme on dit par chez moi :&lt;br /&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:130%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;YaY !&lt;br /&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:78%;"&gt;et non pas LOLJesus ou encore LMAOZedong...&lt;/span&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;gl&gt;&lt;blabla.h&gt;&lt;stddef.h&gt;&lt;/stddef.h&gt;&lt;/blabla.h&gt;&lt;/gl&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-112984234740218427?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/112984234740218427/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=112984234740218427' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112984234740218427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112984234740218427'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2005/10/python-first-sight_112984234740218427.html' title='Python : first sight'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-112957650496994447</id><published>2005-10-17T20:49:00.000+02:00</published><updated>2005-10-20T22:39:34.156+02:00</updated><title type='text'>Shaders, Terre Promise...</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je travaille aujourd'hui en permanence pour essayer de tirer un maximum de points de ma carte vidéo ces derniers temps, et je tombe en admiration profonde devant les capacités des cartes vidéo.&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Petite Différence :&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:100%;"&gt;J'ai fait une comparaison entre les capacités de la &lt;a href="http://nvidia.com/page/geforce_6600.html"&gt;NVidia Geforce 6600GT&lt;/a&gt; du travail (en PCI-Express s'il vous plaît) et mon &lt;a href="http://ati.com/products/radeon9600/radeon9600pro/specs.html"&gt;ATI Radeon 9600&lt;/a&gt; (remerciez ATI pour ne pas avoir mis de chiffres sur leur spec, j'ai du fouiller...), &lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;AGP8X &lt;span style="font-size:78%;"&gt;&lt;span style="font-style: italic;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic; font-family: arial;font-size:78%;" &gt;Rajoutez vous-même les ©™®, merci)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;table  style="text-align: left; margin-left: auto; margin-right: auto; width: 307px; height: 88px;font-family:trebuchet ms;"&gt;&lt;tbody&gt;&lt;tr style="font-weight: bold;"&gt;&lt;td  style="font-style: italic;font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Carte&lt;/span&gt;&lt;/td&gt;&lt;td  style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Radeon 9600&lt;/span&gt;&lt;/td&gt;&lt;td  style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Geforce 6600GT&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td  style="font-weight: bold;font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Pixel Fillrate&lt;/span&gt;&lt;/td&gt;&lt;td  style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;1.3 Gpixels&lt;/span&gt;&lt;/td&gt;&lt;td  style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;4.0 Gpixels&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td  style="font-weight: bold;font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;Geometry Rate&lt;/span&gt;&lt;/td&gt;&lt;td  style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;325 MTriangles&lt;/span&gt;&lt;/td&gt;&lt;td  style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;375 MTriangles&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Loin de leur capacité à coûter cher, je me suis intéressé aux statistiques et  benchs de ces 2 cartes distantes d’une génération seulement, et je vois qu’en  matière de pixel/fragment shader, la NVidia (plus récente) est 2 fois plus  "puissante" que l’ATI (ainsi que la Geforce FX 5900). Bien sûr, ça a l’air  ridicule comme augmentation, on se dit que les CPU doivent augmenter en  puissance bien plus vite.&lt;br /&gt;Que nenni. Les cartes 3D voient leur puissance  multipliée par 2 tous les 9 mois, soit comme j’ai lu dans un article, la loi de  Moore au cube, alors que les fondeurs de processeurs x86 rament pour suivre  cette dernière loi, et sont quasiment obligés d'ajouter des coeurs =o)…&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;A  ajouter à cela qu’il ne s’agit pas forcément d’une course à la fréquence, les  chips tournant au maximum autour de 500MHz, avec une mémoire très très rapide  (NVRAM ou autre GDDR2 ?), mais plutôt d’une conception architecturale  complètement différente.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Les processeurs vidéo exécutent majoritairement  des instructions SIMD. SIMD pour Single Instruction on Multiple Data. Une  instruction peut-être exécutée en même temps sur plusieurs données en parallèle.  On dit aussi qu’il s’agit d’une architecture vectorisée. En fait pour donner une  image, les optimisations consistent à réfléchir de cette façon : « une  multplication de 2 variables float est aussi rapide qu’une multiplication de 2  matrices(4x4) ».&lt;br /&gt;Ainsi 1 multiplication est effectuée aussi vite que 16  multiplications ! (Après il s’agit sûrement d’un peu de marketing-talk, mais  c’est assez souvent repris par les experts).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Virtuellement,  l’architecture de shading nous incite à penser que chaque vertex ou fragment  dispose d’un processeur, et que tous ces processeurs tournent en parallèle.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;En réalité ces processeurs sont capables d’exécuter plusieurs shaders «  en même temps » sur différentes données, parce qu’elles sont restreintes, que  l’environnement d’exécution est restreint, et qu’on a très peu de dépendances  par rapport à un traitement généraliste. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;C’est l’avantage et  l’inconvénient du shader : on a très peu de notion de l’environnement extérieur.&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:100%;"&gt;Le vertex processor&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;On prend en entrée du vertex processor un  vertex, sur lequel on applique un traitement identique à tous ceux qui sont dans  le même appel de dessin. Bien sûr on peut avoir des paramètres pour chaque  vertex et donc appeler à chaque vertex dessiné la fonction de définition  d’attribut, ce qui en général, rend l’application très utilisatrice d’appel de  fonctions OpenGL, et donc surchargée d’appels API… On appelle ça API bounded ou  API limited dans la langue de John Carmack.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;On peut aussi grouper les  définitions de paramètres et ainsi définir un paramètre pour un gros nombre de  vertices, comme par exemple une couleur, une position de départ, une direction,  des coordonnées de texture…&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Il peut arriver qu’on ait besoin de  définir un tableau d’attributs qui peut être mis en correspondance avec un  tableau de vertices. On trouve ici une utilisation pratique supplémentaire des  tableaux de vertices -Vertex Array - et aujourd’hui des Vertex Buffer Objects.  On peut se servir de ces tableaux pour stocker des vertices (comme l’indique  leur nom), mais aussi pour stocker des tableaux d’attributs. Je ferais sûrement  un post sur les Vertex Buffer Objects).&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;Dans le vertex processor, on peut agir sur la géométrie d’un vertex, sur sa couleur (ses couleurs avant et  arrière), sur son illumination… On peut effectuer toutes les computations qu’on  souhaite en gardant bien à l’esprit que l’on est dans un architecture où tous  les vertices sont « censés » être traités en même temps, et donc qu’on ne peut  savoir où se trouve le vertex voisin ou le vertex N. On n’a qu’un notion «  atomique » du vertex.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;font&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div  style="text-align: left; font-family: trebuchet ms;font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Le fragment processor&lt;/span&gt;&lt;font&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: trebuchet ms;font-family:trebuchet ms;font-size:85%;"  &gt;&lt;span style="font-weight: bold;"&gt;&lt;font&gt;&lt;font&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;span style="font-family: trebuchet ms;font-size:85%;" &gt;La sortie du vertex  processor est généralement envoyée au fragment processor. Entre les 2  processeurs, on a une étape dite de « rastérisation ». Il s’agit en fait  d’interpoler les paramètres « varying » entre les différents vertex dont on  demande le dessin. Un paramètre varying est défini dans le vertex processor et  est passé au fragment processor, mais interpolé suivant la matrice de projection  en place.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;&lt;font&gt;&lt;font&gt;Si on dessine d’un triangle, on va donner trois vertices, avec  chacun un attribut de couleur, et qu’on fait passer ces couleurs en varying dans  le fragment processor, on aura des couleurs interpolées sur tous les pixels  (autrement dit tous les fragments) que forment la surface de dessin du  triangle.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;br /&gt;&lt;br /&gt;Bien sûr le fragment shader permet d’effectuer des traitements  bien plus lourds que le vertex processor. Il est en général beaucoup plus  puissant en calcul, peut « regarder » des textures (ce que le vertex processor  ne peut faire que depuis très peu de temps) et effectuer des calculs pour  changer la couleur d’un pixel dessiné. C’est ainsi que des graphistes  parviennent à créer des textures dites procédurales. Ils recréent avec un  fragment shader des objets qu’on pourrait avoir en texture autrement. L’exemple  de base du fragment shader est la « brique », où l’on recrée un « pattern »  simple de brique dans un shader, c’est-à-dire qu’on dessine certaines lignes en  blanc et le reste en rouge de façon périodique.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;En général, on fait  effectuer au fragment processor ce que le vertex processor ne peut pas faire. On  peut modifier les couleurs dans le vp (vertex processor), mais on n’aura pas le  niveau de détail et de finesse du fp (fragment processor).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Si vous  avez compris quelque chose, et que vous vous demandez si on est au sommet des  fonctionnalités et de ce qu’on voudrait faire avec la carte vidéo, la réponse  est non. Au delà de ces merveilleuses fonctionnalités, on se rend compte que les  shaders deviennent les briques de base de toute une classe d’applications. Et  paradoxalement, les utilisations les plus intéressantes des cartes graphiques ne  sont plus les jeux vidéo mais celles qui n’ont strictement rien à voir. Toutes  ces nouvelles applications poussent les cartes vidéo au maximum, montrent leurs  limitations, et font miroiter qu’en investissant dans un tel pari, on peut  doubler les performances de ses applications de calcul lourd tous les 9 mois  =o).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Enthousiasmant &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Ainsi, en flânant sur gpgpu.org , on peut trouver une certain nombre  d’articles assez techniques pour, entre autres, &lt;a href="http://www.gpgpu.org/s2005/slides/govindaraju.DatabaseOperations.ppt"&gt;implémenter  un moteur de base de données&lt;/a&gt; (désolé c’est au format PowerPoint) sur la carte  vidéo en utilisant à la fois les shaders mais aussi les fonctions 3d habituelles  à des fins totalement différentes. C’est absolument fascinant.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;On  trouvera aussi des travaux de recherche sur des algorithmes de tri  ultraperformants, rendus encore plus rapides par les capacités de traitement et  l’architecture des shaders.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Et si on fouille un peu, on trouve de la  documentation sur les limitations des shaders et les nouvelles architectures  mises en place pour y pallier, dont je parlerai dans un prochain  post.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;Conclusion : déjà 2 ans ?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Cela fait plus de deux ans que toutes  ces merveilles sont disponibles dans des cartes vidéo grand public. Et je  découvre seulement aujourd'hui toute la puissance de ce monde =o). Et encore  quand je dis 2 ans, c’est de cette époque que datent les headers OpenGL que  j’utilisais récemment encore pour développer mon appli. J’imagine le progrès  depuis =o).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-112957650496994447?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/112957650496994447/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=112957650496994447' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112957650496994447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112957650496994447'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2005/10/shaders-terre-promise.html' title='Shaders, Terre Promise...'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-112933310023382122</id><published>2005-10-15T01:06:00.000+02:00</published><updated>2005-10-15T02:07:40.770+02:00</updated><title type='text'>Frsit Bgol</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;N'ayant pas bloggué depuis un mois, j'ai un certain nombre de choses à raconter... Je pense que je vais faire plusieurs billets jusqu'à trop sommeil.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Mais je pense que je m'étais un peu éloigné de l'idée du blog quand je l'ai créé. Je ne voulais pas le montrer (j'hésite toujours) et je voulais plus en faire une archive de journal ou un truc qu'on pourrait garder de moi quand je serais mort ou quelque chose de similaire, plutôt qu'une façade "racontage de vie".&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je n'aime pas vraiment les blogs. Au delà des skyblogs, c'est juste l'aspect je-raconte-ma-vie-personnelle-sur-le-web qui m'ennuie. Parce que je m'en fiche comme de l'an 68, et aussi parce que les gens devraient garder un peu de pudeur, cacher un peu leur vie. Que diable que deviendra l'illusion de deuxième chance dans la vie quand tout le monde pourra vous dire &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;font-size:85%;"  &gt;"ON A LES LOGS !!!1One".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Que &lt;/span&gt;&lt;a style="font-family: trebuchet ms;" href="http://kotoajena.blogspot.com/"&gt;Jean-Patrick le semi-chauve-semi-skin&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt; aie mangé des saucisses allemandes pour la première fois et les décrive en détail et explique même la meilleure façon de les régurgiter pour mieux les digérer (indice : le vinaigre est un acide), c'est cool.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;Qu'une bande gays lurons fasse un journal de leur &lt;/span&gt;&lt;a style="font-family: trebuchet ms;" href="http://66.249.93.104/search?q=cache:_60PEo_iPs8J:www.kiad.org/paris-etretat-vtt/+olivier+vincent+david+etretat&amp;hl=fr"&gt;vadrouille vers Etretat&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt;, tant mieux.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;Qu'un &lt;/span&gt;&lt;a style="font-family: trebuchet ms;" href="http://jbamassy.blogspot.com/"&gt;expatrié à Massy&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt; ressente un besoin d'étaler un peu de vinaigre sur la Touâhle, fort bien.&lt;br /&gt;Mais par pitié, pas de blogs "zva coman m lyf est dr, m su fé lrdé pr lott'e tasp".&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;Cà ! par pitié épargnez-moi aussi et surtout les "oui j'adore le prozac(tm)(c) la vie est belle les oiseaux chantent et les ordinateurs quantiques c'est trop cool-génial" (traduction plus qu'approximative à partir de belge), ou &lt;/span&gt;&lt;a style="font-family: trebuchet ms;" href="http://ecate.blogspot.com/2005/10/lordinateur-quantique.html"&gt;affiliés&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt; (quoique, merci pour la crise de rire). De toute façon je ne les lis pas.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;div style="text-align: center;"&gt; &lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Ainsi, comme bonne discipline commence par soi (ou approchant), je n'aurai qu'un lien vers l'extérieur du monde :&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a style="font-family: trebuchet ms;" href="http://yogiaoxford.blogspot.com/"&gt;Non ne riez pas c'est pas sa faute s'il est blond&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="text-align: left;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Soit, c'est dit, je n'écris pas ce truc pour qu'il soit lu. Ceci juste ma psychanalyse techno-hebdomadaire, le petit besoin de flusher mes petites intuitions ou pensées, mes grosses idioties ou maladresses, ou encore des visions qui m'ont touché (pas les miennes donc) et qui ont changé la face du monde. Et si j'ai envie de me taper un article de 145 pages sur l'intérêt de telle extension OpenGL, ben euh... comment répondre avec un maximum d'humilité et de maturité... Ah, j'ai :&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:180%;"&gt;Na !&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-family: trebuchet ms;"&gt;Edit :&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt; j'ai trop la flemme pour continuer ce soir. Ca commence bien.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-112933310023382122?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/112933310023382122/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=112933310023382122' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112933310023382122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112933310023382122'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2005/10/frsit-bgol.html' title='Frsit Bgol'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-112701305955134770</id><published>2005-09-18T03:13:00.000+02:00</published><updated>2005-09-28T22:42:49.043+02:00</updated><title type='text'>OpenGL, la 3D</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je viens d'arrêter mon job d'été (SVG/ASP je bloguerai sûrement un jour là-dessus) pour commencer un autre stage.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Il s'agit d'un stage plutôt technique où je dois refaire un système d'affichage un peu vieillot en utilisant OpenGL et le dernières techniques d'affichage. Par dernières techniques, disons depuis la 2ème génération de cartes 3D Geforce, depuis l'apparition des &lt;/span&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;vrais GPU&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;span style="font-weight: bold;"&gt;Expériences avec la programmation 3D&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Personnellement mon expérience avec OpenGL se limitait à des bidouilles peu optimisées, où j'avais des milliers de vertices que j'envoyais un par un (j'avais quand même une idée de ce qu'étaient les displaylists) et que je faisais transformer par les fonctions OpenGL que tout le monde utilisait... En gros, ma connaissance d'OpenGL devait s'arrêter à la version 1.1. Pas bien fameux.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J'ai essayé Direct3D ensuite aussi, à l'époque de DirectX7 je crois... Une expérience sympa. Même si j'ai des mauvais souvenirs avec C++/COM...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J'ai découvert Java3D ensuite, dans le cadre d'un projet Java de 2ème année à la FIIFO. Très enthousiasmant, à la première approche. En un week-end j'avais construit un package de classes pour la manipulation d'un personnage composé de sphères "rotatées, scalées, et translatées" =o). Tout allait très vite. Je découvrais Eclipse en même temps. Je n'avais jamais pris autant de plaisir à coder (je devrais bloguer sur Eclipse un jour...). Les performances étaient bien pauvres mais suffisantes pour animer une vingtaine de sphères texturées. Le projet s'est bien passé et j'ai eu un bon résultat.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Ensuite j'ai acheté un bouquin sur OpenGL 1.4, et j'ai découvert les vertex arrays, me suis un peu amusé avec les fonctionnalités de textures avancées (le bus AGP s'améliorant toutes les 2 semaines :-)). Rien de bien fameux. Le problème était toujours le même. Dès que j'essayais de faire la moindre chose un peu &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;sympa&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt; la masse de modifications à appliquer sur un code déjà pas terrible me décourageait très, très vite. Et évidemment, chaque modification rendait l'application horriblement lente... Bref, j'ai laissé tomber.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Et pendant 2 ans j'ai vu les nouveaux jeux, les nouvelles cartes, entendu les nouveaux buzzwords "pixel/vertex shaders", "tesselation", "HLSL", "Cg", "Vertex unit"... On aurait dit que les performances brutes avaient explosé, que les CPU des machines avaient aussi explosé. En voyant la complexité des scènes des jeux vidéos récents, je me suis dit qu'ils avaient multiplié par 150 les capacités d'affichage de génération en génération... &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;C'est bien ce qu'il s'est passé =o) (quoique 150 c'est peut-être un peu en-dessous de la réalité). Mais cela ne suffit pas. Si la carte vidéo peut transformer 150 milliards de vertices à la seconde, il faut bien les produire quelque part ces vertices. Je ne comprenais pas le "progrès" et l'enthousiasme pour les cartes 3D... &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;&lt;span style="font-size:100%;"&gt;La programmabilité du GPU&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Le sujet de mon stage concerne l'utilisation de "shaders OpenGL". J'avais une vague idée ce que c'était. Quand je dis vague, je pensais &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;C'est une fonctionnalité *moderne* qui trouve plein d'enthousiastes et peut-être qu'on pourra gagner 2% de performances avec ça&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;... J'étais, comme d'habitude, bien loin de m'imaginer l'intérêt de cette &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;fonctionnalité&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;Première illumination : un &lt;span style="font-style: italic;"&gt;vrai &lt;/span&gt;langage C-like pour les shaders&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;le langage de shading OpenGL est en fait un langage exécuté par le GPU. On programme le GPU par ce langage. On lui fait effectuer des opérations par vertex et par fragment (on dit par pixel sous DirectX).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Donc, à chaque appel à glVertex, on définit soi-même les opérations qui seront effectuées sur le vertex. Transformation, illumination, calcul de normal, coloration... Et on définit aussi les opérations effectuées sur les pixels interpolés (fragments). Texturage, coloration, illumination per-fragment... Tout le code OpenGL qu'on aurait placé en amont dans le glBegin / glEnd avec les 300 changements d'états (si on a mal regroupé les éléments de ses modèles =o)), on le déporte dans 2 fichiers sources .vert et .frag et on se &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;contente&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt; de lier nos objets à ces programmes...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Bien sûr, ce n'est pas aussi simple. Il y a toute une procédure à respecter. Lecture du source, compilation par OpenGL (en ligne !), link des programmes, instanciation, binding, et ensuite définition des paramètres.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Les paramètres ! Grâce à eux, on peut &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;paramétrer &lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;(!) les opérations effectuées dans un shader. L'exemple le plus attrayant est l'animation de particules. Supposons que vous voulez calculez la trajectoire des particules avec une fonction (du genre les bonnes vieilles fonctions de physique de Terminale S).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Vous construisez un shader qui prend comme paramètre une variable temps. Vous placez vos 4000 vertices sur une grille. Vous bindez votre shader à cette grille de vertices. Ensuite, quand vous le souhaitez, incrémentez le paramètre temps et réaffichez. &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;Chaque vertex&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt; va être transformé en fonction de ses coordonnées de départ, et du temps courant. Plus besoin de parcourir soi-même des listes sans-fin de vertices, de leur appliquer une transformation "à la main"...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;On dispose maintenant d'un moyen d'effectuer des traitement pour chaque vertex ET pour chaque fragment !&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Sans parler des possibilités offertes : faire faire des calculs très lourds au GPU pour alléger le CPU. Le GPU est très fort en calcul de matrices par exemple... &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Il est capable par exemple d'exécuter un calcul de matrice 4x4 floats aussi vite que la multiplication 1x1 float... &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Il ne s'agit pas que d'une révolution dans le graphisme... &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;Deuxième illumination : les zones en mémoire vidéo/serveur enfin utilisables&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Il y a eu beaucoup de travail effectué chez NVidia pour réduire les goulets d'étranglement CPU et bus AGP. Ayant déjà essayé à une époque lointaine d'utiliser des vertex arrays, j'en gardais un mauvais souvenir. Envoyer beaucoup de vertices (des centaines de milliers) avec même très peu de calcul à faire derrière (pas d'illumination, pas de texture...) à la carte la mettait très vite à genoux. Le phénomène est simple à comprendre et la solution était "évidente". La lenteur appraissait (entre autres) parce que les tableaux de vertices étaient stockés dans la mémoire application, chez le client (OpenGL est très orienté Client/Serveur). A &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;chaque &lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;dessin il fallait renvoyer &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;tout&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt; le tableau de vertices au serveur (la carte vidéo) pour lui faire faire le transform &amp; lightning... Quelle efficacité !&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J'ai appris la suite de l'histoire récemment. NVidia a créé un extension appelée VAR ou NVAR (pour NVidia Vertex Array Range). Cette extension permettait &lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;de&lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt; réserver&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt; des zones en mémoire vidéo, AGP, ou application... Ainsi on évitait les aller-retour... Si simple ? Pas vraiment.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;D'une part, cette extension avait une limitation au début, au niveau du nombre de vertices : 64K vertices au maximum... peu intéressant. Cette limitation a été levée avec le Geforce3. Mais surtout cette approche cassait le modèle client/serveur d'OpenGL, puisqu'un client avait accès à une zone mémoire serveur comme si elle était chez lui, et celle-ci n'était absolument pas verrouillée. En plus, il fallait que les développeurs codent leurs propres procédures d'allocation (comment savoir si j'ai déjà réservé cette place, en ai-je toujours besoin) ce qui rendait la programmation avec NVAR peu agréable et fiable.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;NVidia (ou un autre constructeur...) a donc créé les VBO/PBO. Il s'agit des Vertex Buffer Object (et Pixel BO...). Il s'agit de permettre de réserver des buffers simplement, de dire où l'on souhaite qu'ils se trouvent (client, serveur). On peut les mapper (les bloquer en lecture/écriture), et l'allocation est gérée par le driver.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Vraiment je ne peux pas attendre lundi/mardi pour "jouer" avec les VBO et voir les différences de performances... Peut-être le million de vertices/frame. C'est le premier but.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;span style="font-weight: bold;"&gt;From the bottom-up&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(192, 192, 192);"&gt; -- digression &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J'ai lu mon premier jour de stage les 5 premiers chapitres du svn handbook. Et il y a une introduction d'un chapitre qui dit à peu près ceci (traduction anglaise plus qu'approximative) : &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;certaines personnes apprennent plus efficacement en partant du bas&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je suis de ces gens-là. Je comprends mieux si je vois d'abord un bon exemple qu'en 2 jours de cours abstraits sur le pourquoi du comment. Je commence par un exemple. Et rapidement je comprends comment fonctionne X. Ensuite, je peux mieux comprendre le pourquoi du comment parce que j'ai une idée de comment ça fonctionne. Je n'ai peut-être pas toutes les subtilités, et mon esprit est sûrement "corrompu" par ce cambouis sur les mains et par une expérience concrète trop précipitée =o).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(192, 192, 192);"&gt;-- fin digression&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J'ai lu le livre d'introduction "OpenGL Shading Language" rapidement, en une journée, et reparcouru rapidement le red book OpenGL pour me &lt;/span&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;re&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;mettre dans le bain... C'était même plus qu'idéal : mon tuteur m'avait laissé un exemple de code qui fonctionnait : une application utilisant Glut (fenêtrage et la théïère) et les "derniers" drivers NVidia sous linux.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Je me suis lancé dans la lecture du code. Qui fait quoi ? Pourquoi ? si j'enlève ça qu'est-ce qu'il se passe ? si je fais ça avant est-ce que ça marche toujours ? Si je demande 1000 fois plus de vertices, est-ce que c'est toujours utilisable ?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Et en 2 heures j'avais déjà un premier résultat sympathique. J'ai vite compris comment ça fonctionnait et j'ai repris le livre sur les shaders pour mieux le comprendre. En 3 jours j'avais déjà de quoi faire une toute petite démonstration où j'affichais, en utilisant un shader, 200000 vertices/frame à quelques dizaines de fps.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;font-family:trebuchet ms;" &gt;&lt;span style="font-size:100%;"&gt;Conclusion, et ensuite ?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Mon premier contact avec les dernières technologies 3D est vraiment enthousiasmant et je commence à comprendre l'engouement général. Je me demande d'ailleurs pourquoi il n'est pas plus important.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;J'ai des souvenirs d'application de calcul qui auraient grandement bénéficié d'une utilisation intensive du GPU. Je pense à des applications de cartographie/géodésie qui demandent des calculs assez lourds (projection conique, cylindrique, interpolation linéaire, changement de système géodésique à 7 paramètres...) et qui en général faisaient s'effondrer un Athlon 2400+... Je pense aussi au projet SETI ou encore à ce projet de dépliage de protéines... Je pense aussi à POV... Augmenter la puissance d'un cluster en rajoutant des cartes graphiques ?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Une bonne semaine. En plus d'un nouvel environnement de travail, de nouveaux collègues, de nouvelles technos, un bon langage (Ada), une mise en selle rapide, et un bonheur de vendredi soir : "J'ai bien bossé"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Et maintenant j'ai envie de m'acheter un Geforce 6800 :-)&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-112701305955134770?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/112701305955134770/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=112701305955134770' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112701305955134770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112701305955134770'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2005/09/opengl-la-3d.html' title='OpenGL, la 3D'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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-7608222.post-112552280994112473</id><published>2005-08-31T22:26:00.000+02:00</published><updated>2005-10-15T01:58:59.856+02:00</updated><title type='text'>Courte (Trop) apologie de SVG et de Deer Park Alpha 2</title><content type='html'>&lt;div  style="text-align: justify;font-family:trebuchet ms;"&gt;&lt;span style="font-size:85%;"&gt;La beta de Firefox 1.1 (ou 1.5...) qui s'appelle Deer Park Alpha 2 démarre, espérons, une période de prospérité et de joie permanente pour les développeurs Web.&lt;br /&gt;&lt;br /&gt;Au dela des améliorations du moteur de rendu HTML/CSS pour lesquelles j'ai peu d'intérêt (à part peut-être si on peut encore se servir de &lt;/span&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;I Must Not Fear&lt;/span&gt;&lt;span style="font-size:85%;"&gt; ou encore &lt;/span&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Delicious Delicacies&lt;/span&gt;&lt;span style="font-size:85%;"&gt;), Deer Park apporte un support assez "complet" du format SVG.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;SVG est un format d'image vectoriel.&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;Mais pourquoi un format vectoriel de plus, bigre ? On a déjà AI (Adobe Illustrator), PDF (Adobe, Portable Document Format), PS (Postscript), DXF/DWF (Autodesk Autocad). On trouvera aussi le format de Dia, de Sketch, et d'une myriade d'autres éditeurs de graphiques vectoriels.&lt;br /&gt;&lt;br /&gt;Le premier intérêt de SVG ici est qu'il s'agit d'une recommandation W3C. Le W3C qui fait XML, XHTML, CSS, DOM et toute une foultitude de recommandations dérivées, qui ont souvent pour dénominateur commun l'idée de faire du Web un monde meilleur. Bien qu'il ne s'agisse que de recommandations, celle-ci sont promulgées par des groupes de travail composés par les poids lourd du logiciel (IBM, Sun, Microsoft...) et font souvent office de "norme" fixe. On peut en lisant les recommandations, créer une implémentation complète de n'importe quel "standard" W3C.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;SVG est donc un format ouvert.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ensuite, c'est un format basé sur XML. Avec tous ses avantages : lisibilité, simplicité, propreté, universalité (il faut bien sûr disposer d'un parseur XML pour traiter du SVG). On peut le styler à l'aide de XSL ou CSS, le manipuler grâce aux interfaces DOM définies (DOMScripting, Ajax, tout çà...), le mixer avec un autre format XML (XHTML par exemple) grâce aux namespaces.&lt;br /&gt;&lt;br /&gt;Une des utilisations les plus intéressantes de la nature "XML" de SVG est la génération grâce à XSLT. Prenez une feuille de données XML sur les statistiques de fréquentation de votre site, puis créez 2 feuilles XSLT. L'une va vous faire générer du XHTML et transformer vos statistiques en tableau, l'autre va vous faire générer du SVG pour dessiner des histogrammes, camemberts, courbes. Avec les mêmes informations de base, créez 2 représentations. Ensuite, avec le DOMScripting, faites interagir vos 2 représentations (rien de bien sorcier, le DOM SVG ressemble beaucoup au DOM XHTML) et vous avez une interface de statistiques riche, modifiable à souhait, indexable (le texte dans vos images est lisible par le moteur de recherche) en très peu d'efforts.&lt;br /&gt;&lt;br /&gt;Pour les dessins plus complexes, SVG dispose de fonctions avancées et puissantes : filtres, dégradés...&lt;br /&gt;Vous pouvez dessiner des courbes (paths) de toutes les formes possibles, en bézier quadratique ou cubique, ou de point à point.&lt;br /&gt;&lt;br /&gt;Vous pouvez réutiliser les objets présents dans le dessin pour faire suivre, par exemple, une courbe à un texte.&lt;br /&gt;&lt;br /&gt;Plus fort encore, vous pouvez déclarer des animations. Animer un objet suivant un chemin défini ailleurs, animer un attribut (couleur, taille de police, dégradé, caractéristique de dégradé), utiliser des keytimes pour vos animations non linéaires... &lt;span style="font-weight: bold;"&gt;SVG est très puissant&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Au niveau de la "lourdeur" du format, tout a été fait pour que les éléments de base du format (les paths) soient optimisables en taille (coordonnées relatives, séparateurs facultatifs, espaces facultatifs...).&lt;br /&gt;&lt;br /&gt;On peut même &lt;span style="font-weight: bold;"&gt;intégrer des images externes&lt;/span&gt; (en binaire/base64 ou en donnant l'adresse du fichier grâce au namespace XLink) et vous en servir comme textures...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;SVG est un format très complet. Un très bon concurrent de Flash.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Point de troll ici. Flash c'est très bien, très puissant, le runtime fait seulement 500Ko, et Macromedia ne cesse d'améliorer son outil, et Flash dispose en plus d'une base installée très importante. Dès qu'on veut un site animé, joli, très interactif, on travaille avec Flash.&lt;br /&gt;Oui le format swf de Flash est ouvert. Flash peut même charger des images SVG et les afficher.&lt;br /&gt;&lt;br /&gt;Alors pourquoi SVG ? Pourquoi un nouveau format ?&lt;br /&gt;Chacun son intérêt.&lt;br /&gt;&lt;br /&gt;Mais SVG reste sérieusement le meilleur outil pour les graphiques générés côtés serveur (ou client, merci XSLTProcessor dans les navigateurs modernes...) et pour fournir des images légères, agrandissable à envie sans pixeliser (même s'il y a une limite) et qui puisse profiter du grand engouement présent pour Ajax et l'applicatif Web.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Je reparlerai sûrement de ce format, sachant que c'est ce format avec lequel j'ai beaucoup travaillé.&lt;br /&gt;&lt;br /&gt;Mais je tenais à lever mon chapeau bien haut pour l'équipe qui programme le renderer SVG (NATIF!) pour Mozilla. La liste des fonctionnalités implémentées est loin d'être complète mais on peut déjà travailler avec les fonctionnalités présentes (pas de super filtres, patterns complexes et dégradés bien chiadés) mais la partie DOMScripting fonctionne comme un charme, et est même mieux implémentée que le viewer majeur du monde SVG (Adobe SVG Viewer 3.03), même si la version 6 beta rattrape pas mal de choses mais ne sortira jamais officiellement (stagne depuis juillet 2003)...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Bravo Messieurs, continuez !&lt;/span&gt;&lt;span style="font-size:85%;"&gt; Mon travail n'en est que plus agréable.&lt;br /&gt;&lt;br /&gt;Premier blog, premier post, un compliment.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7608222-112552280994112473?l=emporteunevache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emporteunevache.blogspot.com/feeds/112552280994112473/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7608222&amp;postID=112552280994112473' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112552280994112473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7608222/posts/default/112552280994112473'/><link rel='alternate' type='text/html' href='http://emporteunevache.blogspot.com/2005/08/courte-trop-apologie-de-svg-et-de-deer.html' title='Courte (Trop) apologie de SVG et de Deer Park Alpha 2'/><author><name>EmporteUneVache</name><uri>http://www.blogger.com/profile/06655815293448023227</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></feed>
