retour à l'accueil dernière actualité articles interviews qcm dictionnaires bibliothèque forums inscription membre profile recherche sauvegardes contacts aides
entete 0titre de la page
menu du haut




DirectX : Techniques de compression des textures
 Auteur : Tanguy Fautré Dernière révision : 22 Juillet 2003
Faire un commentaire :   0 message(s)








Introduction
   

Toujours des graphismes plus spectaculaires, toujours plus rapides; les jeux actuels ont souvent recours à la compression de texture pour atteindre ces objectifs. Cette technique permet d'utiliser plus de textures et/ou des textures plus grandes tout en utilisant moins d'espace mémoire.

Lorsqu'on parle de compression de texture on pense souvent au S3TC ou au DXTC, parfois sans très bien savoir ce que ces acronymes signifient réellement. Le S3TC est un format compressé qui a été développé par la société S3 vers la fin des années 90; il se trouve être à l'origine du DXTC qui n'est rien d'autre qu'une collection de formats compressés tous basés sur le S3TC.

Cet article va tenter d'expliquer comment se compose et comment fonctionne le DXTC, et d'en voir les bénéfices ainsi que les inconvénients.





Qu'est-ce que la compression ?
   

Les unités de stockage (mémoire RAM, disque dur, bande magnétique...) ont deux caractéristiques techniques importantes : leur capacité de stockage et leur bande passante (vitesse à laquelle on va pouvoir écrire ou lire des données dans ces unités de stockage). En réduisant la taille des données qui y transitent ou qui y sont stockées on peut réduire de façon significative la charge de travail d'une machine. On a donc rapidement cherché à compresser la taille des données.

Une méthode de compression permet de réduire la taille d'un ensemble de données (un fichier par exemple), mais les besoins et les utilisations variant énormément il n'existe pas une méthode universelle, il en existe des centaines! Toutefois on peut les classer en deux grands groupes :

Compression sans perte: (lossless compression)
Très souvent on désire compresser des informations pour les retrouver intactes une fois décompressées; c'est le cas par exemple lorsqu'on compresse des fichiers en format ZIP ou RAR, ou une image en PNG. Ces techniques permettent donc, dans un certain contexte, de compresser les données intéressantes sans les altérer. D'un point de vue mathématique si I représente les données, C(x) la fonction de compression et D(x) la fonction de décompression, alors I = D(C(I)). Cette équation signifie que si on compresse puis décompresse un groupe de données I alors on doit retrouver exactement ces données I.

L'avantage de ces méthodes réside justement dans le fait qu'on n'altère pas les données tout en gagnant de la place. Par contre elles ont de gros désavantages : le taux de compression (c'est-à-dire le rapport entre la taille des informations non comprimées et leur taille une fois qu'elles ont été compressées) est très variable et a ses limites - il n'est pas possible de compresser infiniment un fichier par exemple, dans certain cas extrêmes celui-ci pourra être plus gros qu'au départ -, les algorithmes de compression et de décompression sont généralement assez lourds, ils limitent souvent la lecture des données compressées à une lecture séquentielle et donc on ne peut pas accéder à l'information n'importe comment,...

Compression avec perte: (Lossy compression)
Dans d'autres cas il n'est pas réellement nécessaire d'avoir une correspondance parfaite entre les informations d'origine et celles obtenues après la décompression. Par exemple dans le cas d'une vidéo, d'un fichier audio ou d'une image on désirera avoir un taux de compression plus important au dépend d'une perte d'informations jugées inutiles; c'est le cas notamment des formats JPEG, MP3, MPEG, etc. D'un point de vue mathématique I ~ D(C(I)).

Par exemple dans le cas d'une image compressée en JPEG, on autorise une dégradation de l'image pour obtenir un meilleur taux de compression. L'idée est qu'on ne verra pas cette dégradation à moins d'inspecter l'image à la loupe et de comparer l'image compressée avec l'originale. Même chose avec un MP3 où l'on élimine entre autre les sons imperceptibles à l'oreille humaine. Bien sûr il existe une limite subjective au delà de laquelle la perte de qualité deviendra inacceptable.

Le principal désavantage de ces techniques c'est que l'on peut perdre des informations qui n'étaient pas si inutiles que ça (ex: dégradation trop importante de l'image ou du son après la compression). Leurs principaux avantages sont de pouvoir garantir un meilleur taux de compression, voire un taux de compression fixe, d'être généralement plus simples et plus rapides à décompresser, de pouvoir être accédé avec plus de liberté,...





Comment se compose une texture compressée ?
   

DirectX a basé ses propres formats de texture compressée sur le S3TC développé par S3. On se réfère généralement à ces formats sous l'appellation DXTC (DirectX Texture Compression). Le DXTC est en fait composé de 5 formats de textures différents: DXT1/2/3/4/5; ils sont tous les cinq basés sur des algorithmes de compression avec perte.

J'expliquerai d'abord comment se composent et se décompressent ces formats pour ensuite expliquer pourquoi ils ont été conçus tels quels et pas autrement.

Un petit rappel : les couleurs sont souvent encodées en RGBA, c'est-à-dire en 4 composants distints qui fournissent le taux de rouge (Red), de vert (Green), de bleu (Blue) et de transparence (Alpha). Lorsqu'on dit qu'une texture est encodée en RGB 5:6:5 ça veut dire que chaque pixel est encodé sur 16 bits : 5 bits pour le rouge, 6 bits pour le vert, 5 bits pour le bleu et 0 bit pour la transparence. Une image est décrite par ses dimensions (par exemple 640 sur 480 pixels) et par une série de valeurs RGBA qui correspondent à la couleur de chaque pixel. Une texture n'est tout simplement qu'une image qui sera utilisée par la carte 3D.

L'idée du DXTC est de décomposer l'image, la texture en blocs de 16 pixels (4 pixels sur 4). Une texture de 256 pixels sur 256 sera composée donc de 4096 blocs (64 x 64 blocs). Chaque bloc est compressé et décompressé indépendamment des autres.

Le format DXT1, qui est strictement identique au S3TC, utilise des blocs de 64 bits. Chaque bloc n'est composé que d'un seul sous-bloc de 64 bits ne contenant seulement que les informations sur la couleur RGB des pixels, on appelle souvent ce sous-bloc le Color Block (bloc de couleur). On verra plus loin que les formats DXT2/3/4/5 utilisent en plus un Alpha Block qui comme son nom l'indique fournit en plus la valeur 'alpha' de chaque pixel.

Ce bloc de couleur se compose d'un en-tête (header) de 32 bits contenant deux couleurs de 16 bits (format RGB 5:6:5), et d'une matrice 4x4 de 16 pixels, chaque pixel ayant une valeur encodée sur 2 bits (32 bits + 16 x 2 bits donne bien un bloc de 64 bits). Le schéma suivant montre un tel bloc :

Color Block
Schéma d'un bloc de couleur


Pour obtenir la couleur de chaque pixel à partir de sa valeur encodée sur 2 bits et des deux couleurs contenues dans l'en-tête, on utilise une interpolation linéaire entre les deux couleurs décrites par :

00 = Couleur1
01 = Couleur2
10 = (2 * Couleur1 + Couleur2) / 3
11 = (Couleur1 + 2 * Couleur2) / 3


Tous les formats DXTC utilisent cette méthode pour leurs blocs de couleurs. Mais pour le DXT1 et uniquement le DXT1 il existe une variante si (Couleur1 < Couleur2) qui permet de donner une valeur de transparence alpha 0 ou 1 :

00 = Couleur1
01 = Couleur2
10 = (Couleur1 + Couleur2) / 2
11 = Transparent


Il est à noter que les opérations ci-dessus sont effectuées sur les composants RGB des couleurs, c'est-à-dire que (Couleur = Couleur1 + Couleur2) doit être interprété comme (R = R1 + R2), (G = G1 + G2), (B = B1 + B2). L'addition et la multiplication de couleurs n'ayant aucun sens sinon.

Les formats DXT2/3/4/5 utilisent des blocs de 128 bits, composés de deux sous-blocs : un bloc alpha de 64 bits et un bloc de couleur de 64 bits identique à celui décrit ci-dessus.

Les formats DXT2 et DXT3 ont comme bloc alpha une matrice 4x4 de 16 pixels dont la valeur alpha est directement donnée par 4 bits (16 x 4 bits donne bien 64 bits).

Les formats DXT4 et DXT5 utilise un bloc alpha composé d'un en-tête de 16 bits fournissant deux valeurs alpha de 8 bits et une matrice 4x4 de 16 pixels chacun ayant sa valeur encodée sur 3 bits (16 bits + 16 x 3 bits donne bien 64 bits). Le principe de décompression d'un tel bloc est aussi une interpolation linéaire plus ou moins identique à celle vue pour le bloc de couleur avec la différence qu'ici l'interpolation est dictée par 3 bits et non 2 ce qui permet une plus grande précision.

La différence entre le DXT2 - DXT3 et le DXT4 - DXT5 se situe au niveau de l'interprétation des couleurs RGBA. En effet en DXT2 et en DXT4 les valeurs RGB du bloc de couleur ont été pré-multipliées par leur valeur alpha au moment de la compression; les formats DXT2 et DXT4 sont relativement peu utilisés et sont même indisponibles en OpenGL.





Pourquoi un tel format ?
   

Comme on a pu le voir les 5 formats qui composent le DXTC sont fort similaires. Ils ont donc tous les mêmes avantages et inconvénients à quelques détails près.

Leur principal défaut étant d'être le résultat d'une compression avec perte, on ne peut pas retouver l'image d'origine à partir de sa version encodée en DXTC. (J'éviterai de mettre la démonstration mathématique, donc sur ce point il faudra me faire confiance ;-)). Dans certains cas, l'utilisation du DXTC peut dégrader la qualité des textures jusqu'à atteindre un niveau inacceptable, on ne peut pas compresser aveuglément toutes les textures en utilisant le DXTC si l'on veut garder un résultat correct.

Par contre le taux de compression est fixe et garanti. On peut donc savoir avec exactitude la taille d'une texture, et on est sûr que toutes les textures seront compressées avec la même efficacité.

La principale occupation d'une carte 3D actuelle se fait au travers de lectures de texels (pixels composant une texture) et de combinaisons de ceux-ci. Il est donc important que les accès aux texels puissent se faire très rapidement et n'importe où, sinon ça rendrait la carte 3D tellement lente qu'elle serait complètement inutile. Or avec les formats DXTC la carte 3D peut justement accéder à n'importe quel texel d'une texture compressée. En effet à partir de la position d'un texel on peut savoir dans quel bloc il se trouve ainsi que sa position dans ce bloc, de plus seul ce bloc devra être lu.

Même si les algorithmes de compression pour arriver à un format DXTC sont relativement complexes, l'algorithme de décompression est quant à lui extrêment simple à mettre en oeuvre et demande peu de calculs ce qui permet d'avoir rapidement la valeur d'un texel; un point crucial comme vu plus haut. Et puis si la décompression avait été trop lourde, la complexité de la puce et le prix de celle-ci aurait augmenté de façon significative (il faut se remettre dans le contexte de l'époque où l'on ne savait pas produire des puces graphiques avec plus de 10 millions de transistors).

Les trois principaux avantages sont donc : le taux de compression fixe et garanti, la simplicité de la méthode de décompression, et la vitesse laquelle on peut avoir la valeur d'un texel. A la vue de ces avantages on peut comprendre pourquoi un tel ensemble de formats ait été choisi pour compresser des textures et que pour le moment aucune carte ne supporte d'autres formats comme PNG ou JPEG qui ne possèdent aucun des avantages cités ci-dessus.





Comment compresse-t-on une image en DXTC ?
   

Si la décompression d'une image encodée en un des formats DXTC est extrêment simple, le compression est quant à elle une autre paire de manches.

Vu que les images utilisant les formats DXTC sont le résultat de compressions à perte, il n'existe généralement pas de solution parfaite, c'est-à-dire qu'on n'arrivera pas à trouver une image compressée identique en terme de qualité à l'originale. En théorie il existe une image compressée qui est la plus proche visuellement de l'image d'origine, cette image est considérée comme étant la meilleure solution au problème. En pratique les algorithmes de compression de textures essaieront de donner un résultat le plus proche possible de cette solution idéale, mais sans toujours y parvenir.

L'idée de base est d'essayer pour chaque bloc de trouver les couleurs 1 et 2 et les valeurs de chaque pixel qui donneront la meilleure solution. Pour ce faire on génère une série d'essais, de versions brouillons, dans un intervalle de couleurs et de valeurs plus ou moins grand et l'on ne garde que le meilleur essai de tous. Suivant le nombre d'essais que l'on fera, de l'intervalle de couleurs et de valeurs couvert on aura plus ou moins de chance d'être proche de la solution idéale. Généralement si on fait un plus grand nombre d'essais et si les intervalles sont choisis plus intelligemment, alors l'image compressée résultante sera de meilleure qualité mais cela demandera généralement plus de puissance de calcul. Il existe donc un rapport direct entre le temps de compression et la qualité de l'image compressée.

Lorsqu'une application 3D désire utiliser des textures compressées, deux grands choix s'offrent à elle :

  • Elle peut donner les textures d'origine à la carte 3D, et ce sera aux drivers de compresser les textures. Par exemple, c'est la méthode utilisée par Quake III et les jeux dérivés comme Jedi Knight II et Soldier of Fortune II. L'avantage de cette solution est sa simplicité pour l'application qui ne doit changer que 2 à 3 lignes de codes. Mais le problème c'est que la compression d'une texture prend du temps, ca ralonge donc le temps de chargement du jeu. De plus pour que les textures ne mettent pas des heures à se charger sur la carte 3D, les drivers utilisent des algorithmes de compression qui sacrifient la qualité au profit de la rapidité (par exemple, en ne faisant qu'un petit nombre d'essais comme vu plus haut). Certaines applications sauvent les textures ainsi compressées sur le disque dur pour ne pas devoir les recompresser la fois suivante (c'est le cas de GTA3 sur PC); ce qui nous conduit au choix suivant.

  • Elle peut fournir directement les textures dans un format précompressé. Généralement l'application fournit directement les textures précompressées sur le CD (c'est la solution utilisée par Unreal Tournament 2003), celles-ci ayant été compressées à l'aide d'outils spécialisés que l'on peut trouver sur le site de Microsoft, d'ATI ou d'NVIDIA, ou bien elle peut compresser les textures au moment de l'installation (comme 3DMark2001). L'avantage c'est que l'application peut passer plus de temps sur la compression (généralement plusieurs minutes pour un groupe de grosses textures) et ainsi donner un meilleur résultat, et le temps de chargement au final sera très court.


Le choix de telle ou telle méthode a d'autres avantages ou inconvénients un peu plus techniques que je ne décortiquerai pas ici. Mais en ce qui concerne la qualité d'image c'est la deuxième méthode en utilisant des outils spécialisés qui semble la plus intéressante.





Comparaison des différents formats (1 - Compression et couleurs)
   

Comme vous pouvez vous en douter, les formats DXT1/2/3/4/5 n'offrent pas tous la même qualité visuelle, le même taux de compression ni la même vitesse de décompression.

Le tableau suivant donne les différents taux de compression de chaque format par rapport à la texture correspondante en 32 bits (RGBA).

 32 bits
DXT18:1
DXT2 / DXT34:1
DXT4 / DXT54:1


La taille d'un bloc DXT1 étant de 64 bits (8 bytes) et comportant 16 pixels on arrive bien à un taux de compression de 8:1 par rapport à 16 pixels en 32 bits qui donnent un total de 64 bytes. Les blocs en DXT2-5 faisant deux fois la taille d'un bloc DXT1 ça donne bien un taux de compression deux fois moindre.

Il faut quant même noter que le DXT1 ne fournit pas réellement de transparence et que le comparer à du RGBA 32 bits est un abus. Donc on le compare plutôt à un format 24 bits RGB, ce qui donne un taux de compression 6:1. Oui mais pourquoi l'avoir comparé à du 32 bits alors ? Et bien tout simplement parce que la plupart des cartes 3D (Radeon, GeForce et autres) stockent les textures 24 bits sur un alignement de 32 bits pour des raisons d'efficacité (optimisations internes au processeur graphique). Ce qui implique que les textures 24 bits prennent tout autant de place que les 32 bits sur de telles cartes 3D, et du coup le taux de compression du DXT1 passe en pratique de 6:1 à 8:1.

Une compression de 8:1 est assez impressionnante, mais comme on l'a dit plus haut le prix à payer est une perte de la qualité des textures. Le meilleur moyen pour s'en rendre compte c'est de comparer quelques screenshots.

Basse résolution, non compressée
Basse résolution, non compressée
Basse résolution, DXTC
Basse résolution, DXTC
Haute résolution, non compressée
Haute résolution, non compressée
Haute résolution, DXTC
Haute résolution, DXTC


Ces screenshots proviennent directement d'un programme test en OpenGL sur une GeForce 2; les textures compressées ont été générées avec nvdxt.exe (v. 5.19) disponible sur le site d'NVIDIA. Vu qu'il n'y a aucun effet de transparence n'importe quel format DXTC donnera le même résultat visuel (en théorie); l'encodage des couleurs étant strictement le même pour tous. Toutefois j'ai utilisé le DXT5 pour ce test car en pratique les GeForce 256, 2 et 3 n'affichent pas correctement les textures en DXT1. NVIDIA n'a jamais donné d'explication officielle sur ce bogue, cependant on est presque sûr que la cause vient du circuit de décompression des textures DXT1 qui travaille avec une précision de 16 bits au lieu de 32 bits, ce qui donne une moins bonne qualité d'image. (Note: XBox, GeForce 4, GeForce FX ou plus n'ont plus aucun problème à ce niveau là par contre.)

Comme vous pouvez le voir il y a deux versions d'une même texture, la première est une version basse résolution en 256 x 256 et la deuxième est une version haute résolution en 512 x 512. Les screenshots de gauche ont été faits en utilisant ces textures en 24 bits et donc non compressées, et les screenshots de droite ont été faits en utilisant le DXTC.

Si l'on compare la texture basse résolution compressée et non compressée on peut rapidement remarquer la perte de qualité. Certains détails ont été fortement modifiés mais dans ce cas-ci ce n'est pas forcément gênant et on a besoin de la version non compressée pour s'en rendre compte. On peut aussi remarquer un changement de teinte assez important au niveau des banquises, le blanc passant légèrement à une couleur mauve; ce détail par contre est plus embêtant. Sans montrer d'autres screenshots on peut rapidement conclure sur ce dernier point que le DXTC n'est pas très indiqué pour les images contenant des zones de couleur trop uniformes car les défauts seront plus facilement visibles à l'oeil nu.

Avec la version haute résolution les différences sont déjà plus dures à voir entre la version compressée et non compressée. Seule la teinte rougeâtre-mauve au niveau des banquises reste gênante.

Mais qu'en est-il de la version basse résolution non compressée et de la version haute résolution compressée? Il est clair que dans l'ensemble la version haute résolution est de bien meilleure qualité même si celle-ci est compressée. Et si je vous dis que cette dernière prend deux fois moins de place en DXT1 que la version basse résolution non compressée cela devient assez impressionnant !

Il est assez net que le DXTC est plutôt à utiliser pour mettre plus de textures de plus grande résolution sur la carte 3D. En effet si la carte 3D n'a pas assez de mémoire pour contenir toutes les textures d'une scène, les performances chûteront rapidement et ça deviendra vite ingérable (<5 fps?). Dans ce cas le DXTC pourra venir en renfort et faire tenir les textures sur la mémoire de la carte 3D et cela évite aussi que trop de mémoire centrale ne soit monopolisée par les textures. La plupart des jeux récents se basent sur cette idée pour améliorer l'aspect graphique tout en restant dans les limites de l'hardware. Certains jeux d'ailleurs ne permettent l'utilisation de textures haute résolution que si la compression de textures est utilisée en parallèle.

Dans le cas où on a déjà assez de mémoire sur la carte graphique on peut toujours compresser les textures pour gagner en performance en diminuant la bande passante utilisée mais le gain sera assez faible (5 - 15%) car malheureusement la décompression augmente le temps d'accès aux texels et le fait que les textures soient compressées ne permet pas d'éliminer par magie tous les accès mémoires. La faible augmentation de performance n'excusant généralement pas la dégradation des textures, on ne préfère pas utiliser cette solution. Par exemple, utiliser la compression de textures dans Quake III sur une carte graphique avec 128 MB ou plus n'a de ce fait pas beaucoup d'intérêt.

Il est à noter qu'avec le temps on arrive toujours dans le cas où l'on a assez de mémoire puisque les cartes graphiques évoluent sans cesse. La compression de textures permet simplement de prendre un peu d'avance sur son temps et de faire plus avec moins.





Comparaison des différents formats (2 - Transparence)
   

Il a été dit plus haut que tous les formats DXTC donnaient tous en théorie le même résultat en ce qui concerne la couleur, alors pourquoi avoir 5 formats différents ?! Et bien la différence se situe au niveau du composant Alpha souvent utilisé pour la transparence. Comme les screenshots le montrent, il existe une différence de qualité entre les différents formats. Je ne m'étalerai pas sur le DXT2 et le DXT4 dans ce test, formats qui brillent par leur absence en OpenGL et qui sont identiques aux DXT3 et DXT5 du point de vue de l'encodage.

RGBA 32 bits
RGBA 32 bits
DXT1
DXT1
DXT3
DXT3
DXT5
DXT5


Pour tester la qualité de la transparence des différents formats j'ai utilisé une texture blanche de 512 x 512 sur fond noir. Les parties transparentes laisseront ainsi apparaître ce fond noir. On peut remarquer à nouveau la décoloration du blanc avec les formats compressés mais il faut faire abstraction de ce détail, ce test portant sur la transparence et non sur les couleurs.

Le premièr screenshot montre la transparence telle qu'elle devrait être, elle a été obtenue en utilisant une texture RGBA en 32 bits. Ce sera notre image de référence.

Le second screenshot a été faits en utilisant le DXT1. Ce format ne supporte pas réellement la transparence, seule une information binaire (totalement transparente ou totalement opaque) peut être fournie, il n'est donc pas surprenant que la texture montre simplement les endroits transparents comme étant complètement transparent et ignore certaines zones transparentes si celles-ci ne le sont pas suffisamment. Evidemment le DXT1 ne sert pas beaucoup pour les effets de transparence très poussés.

Le 3ème screenshot utilise la version DXT3 de la texture. La transparence y est mieux rendue qu'avec le DXT1 mais reste loin de l'image de référence. La raison vient du fait qu'en DXT3 les informations alpha sont explicites, c'est-à-dire que les valeurs alpha de chaque pixel sont données directement et ne sont pas compressées. Comme cela a déjà été expliqué avant, ces valeurs sont fournies sur 4 bits ce qui donne 16 nuances de transparence différentes. Cette limite de nuance se voit très bien via l'effet de bande qu'elle produit à certain endroit. Le DXT3 est donc essentiellement à utiliser lorsqu'on n'a besoin que d'effets de transparence uniformes.

La dernière screenshot montre la texture en DXT5. Je doit avouer que j'ai du mal à voir la différence par rapport à la version non compressée. Contrairement au DXT3, les informations alpha sont compressées tout en gardant un bloc alpha de même taille, ce qui permet d'avoir plus d'informations et donc une bien meilleure qualité au niveau de la transparence. Format à utiliser pour la plupart des textures transparentes.

Dans la majeure partie des cas, le DXT3 est assez inutile par rapport au DXT5. Son existence s'explique surtout du fait que lors de la création du DXTC il était simplement un peu plus rapide que le DXT5 puisque le bloc alpha ne doit pas être décompressé, mais sur les cartes modernes ça n'a plus aucune importance.





Conclusion
   

La compression de textures est aujourd'hui devenue une chose courante, voire implicite dans la plus part des applications 3D, surtout dans les jeux. Même si elle n'est plus au centre des discussions sur les dernières cartes graphiques, il ne faut pas perdre de vue que sans elle les graphismes de jeux tels que Unreal Tournament 2003 ou IL2 Sturmovik n'auraient pas été possibles sur des systèmes avec 32 à 64 MB de mémoire vidéo. La compression de textures est aussi indispensable à l'essort des textures 3D qui prennent une place mémoire imposante et qui commencent tout doucement à apparaître sur nos PC.

Les techniques actuelles de compression de textures exposées dans cet article reposent sur les avancées faites par S3 dans le domaine des cartes graphiques grand public, ce sont donc les plus répandues mais il est toutefois important de noter que ce ne sont pas les seules techniques existantes, pour les intéressés vous pouvez trouver une liste non exhaustive (en anglais) via l'exposé suivant : Texture Compression Survey. Il contient également une introduction et plusieurs explications plus techniques sur la compression de textures.

Ceci achève mon premier article sur Onversity. J'espère qu'il vous aura plu car pour ma part j'ai pris un grand plaisir à l'écrire. Si vous avez la moindre remarque ou le moindre commentaire n'hésitez pas, le forum, mon adresse email ainsi que celle de Jean-François sont là pour ça. Je tiens d'ailleurs à remercier Jean-François pour son support et son aide, sans qui cet article n'aurait jamais vu le jour.




YOUM
(analyseur syntaxique temps réel)
Nombre de définitions trouvées
98
Multi-dico par texte : actif   -   Multi-mots par définition : 4






fonction
menu de droite
fin de menu

qcm du mois
Télescope spatial Hubble
fin qcm


Page générée en : 0.016 secondes
ligne
Technologies Onversity : Hydrogen 1.0 (moteur de base de données) - SE.EN 1.0 (moteur de recherche) - YOUM 2.0 (analyseur syntaxique temps réel)
Tous droits réservés à Jean-François MAQUINÉ
ligne