Humm par quoi commencer... 2004? Oui 2004 est une bonne année car c'est l'année de création de la toute première version de GeeXLab qui, à l'époque, s'appellait Hyperion. Puis à cause de sombres et nauséabondes histoires légales, le nom d'Hyperion a du être abandonné une ou deux années plus tard. C'est très probabelement dans un excès de fureur que j'ai pondu le nouveau nom du produit: Demoniak3D. Avec ce nom, pas de soucis de copyright. Google n'en avait jamais entendu parler et le nom de domaine était disponible. J'ai developpé Demoniak3D jusqu'aux environs de 2008.
2009. Nouvelle année et nouveau changement de nom. Demoniak3D était sympathique mais pour certaines personnes, ce nom était un peu trop diabolique. J'ai finalement cédé, repassé plusieurs heures sur google et j'ai finalement trouvé un nouveau nom: GeeXLab. Même chose que pour Demoniak3D: aucun resultat dans le moteur de recherche et nom de domaine disponible. De plus, en 2009, Twitter commençait à faire parler de lui et hop, le compte @geexlab a été ouvert.
Hyperion, Demoniak3D puis GeeXLab. Trois noms mais au final il s'agissait toujours du même logiciel. GeeXLab a été developpé ainsi jusqu'en 2012. Ces trois premières itérations ont été développées avec un moteur 3D (oZone3D...) que j'avais commencé en 2003. oZone3D était un moteur C/C++ disponible uniquement sous Windows. Et jusqu'en 2012, GeeXLab ne supportait que la plateforme Windows. oZone3D etait vraiment ce que l'on appelle un moteur 3D. Toutes les arcannes de la 3D étaient cachées et la programmation d'une scène 3D se faisait selon le mode retained. Grosso-modo, on dit au moteur ce que l'on veut afficher (par exemple je veux dessiner une sphere texturée) et le moteur se charge de gérer la scene 3D et la façon de rendre le contenu 3D. Du point de vu utilisateur du moteur, c'est relativement simple. Mais le gros inconveniant c'est la perte de controle. Si le scenario de rendu n'était pas cablé dans le moteur, il était impossible de rendre la scène 3D.
A la mi-2012, je me suis lancé dans le développement de ma nouvelle architecture pour remplacer le moteur oZone3D. Cette fois-ci il me faillait quelque chose de bas niveau pour que je puisse faire tout et n'importe quoi avec et quelque chose de multi-platforme. Ce quelque chose devait supporter Windows, Linux et macOS (OS X à l'époque, comme quoi je ne suis pas le seul à changer de nom de mes applications!). Et petit détail qui a son importance: ce quelque chose devait supporter les CPUs 32 et surtout 64-bit. oZone3D était un moteur de type retained mode, limité à Windows et en 32-bit uniquement.
Donc près de 10 ans, après la création du premier moteur 3D, je me suis lancé dans ma nouvelle architecture. Et cette fois il ne s'agissait plus d'un moteur 3D mais d'une simple librairie 3D. Cette librairie (appellée gxc pour GraphiX Core) est une librairie écrite en C++, multi-plateforme, supportant les architectures 32 et 64-bit et surtout c'est une librairie de bas niveau. Cette librairie est la brique de base pour tous mes nouveaux développements à partir de 2012.
En janvier 2013, j'ai sorti la nouvelle version de GeeXLab qui du coup ne s'appelait plus GeeXLab mais GLSL Hacker. Et de quatre! Pourquoi ce changement de nom? Pour montrer la rupture avec l'ancienne architecture, l'ancien fonctionnement de GeeXLab et surtout pour mettre en avant le coté plus bas niveau. Dès sa sortie, GLSL Hacker était disponible pour Windows (32 et 64-bit), Linux (64-bit) et macOS. Il embarquait comme langage de programmation le Lua et le Python et les shaders (les fameux programmes qui tournent directement sur le GPU) pouvait être live-codées soit en local soit via le réseau. Pas mal pour une première version!
En décembre 2015, rebelote, j'ai encore changé de nom. Mais cette fois-ci, j'ai fait une sorte de rollback: GLSL Hacker a laissé place à... GeeXLab. Pourquoi? Tout simplement par ce que j'avais ajouté le support Direct3D 12. Le nom GLSL Hacker était cool mais était trop lié à l'API 3D de base qui est OpenGL. GeeXLab est un nom assez générique, qui évoque le coté geek (ou plutôt geeks) et le coté expérimental (lab). Et ce choix de GeeXLab s'est révélé payant puisqu'en avril 2016, j'ai aussi intégré le support de l'API Vulkan (sous Windows et Linux).
Après ce rapide historique, rentrons dans le vif du sujet. Qu'est-ce que GeeXLab?
Au sens très général, GeeXLab est un outil de création d'applications. GeeXLab, à l'instar d'un navigateur web comme firefox ou chrome, a une interface graphique très dépouillée voire quasi inexistante. Tant mieux, c'est ça de moins a apprendre!
GeeXLab
Firefox
Ok mais alors comment on fait une application avec GeeXLab? Et bien de la même manière qu'une application web. Pour afficher une page web dans un navigateur, il faut d'abord coder cette page web dans un fichier (en utilisant du HTML par exemple) puis ouvrir ce fichier avec le navigateur. C'est exactement la même chose avec GeeXLab. On code quelques lignes dans un fichier et on charge ce fichier dans GeeXLab.
Et pour reprendre la similitude avec une application web, une application GeeXLab (que je nomme toujours demo, donc dans tout ce qui suit, une demo GeeXLab est en réalité une application GeeXLab) n'est pas limité à un seul fichier: la demo peut être repartie dans des dizaines de fichiers différents. Il n'y a pas de règles. L'organisation et le nombre de fichiers est un choix propre au développeur d'une demo GeeXLab. GeeXLab n'impose rien!
La programmation d'une demo / application GeeXLab ne nécessite pas grand chose: avoir envie de programmer, avoir un editeur de texte et bien sur GeeXLab. GeeXLab est extremement simple à utiliser et ne nécessite aucun environnement de développement (un IDE) ou plugin particulier. Pour créer des applications GeeXLab, de la plus simple à la plus complexe, un simple éditeur de texte est suffisant. Le grand avantage est que vous pouvez développer une demo GeeXLab sur n'importe quelle plateforme supportée par GeeXLab. Il y aura toujours un editeur de texte (vi ou nano sous Linux par exemple).
Si vous savez pas quel éditeur de texte choisir, en voilà quelques-uns:
Pour ma part, Notepad++ est mon editeur préféré sous Windows. Sous Linux (cela comprend aussi les Raspberry Pi et autre Tinker Board), j'utilise Geany. Sous macOS, je code avec Sublime Text.
GeeXLab est une application multi-plateforme (ou cross-plateforme) c'est à dire qu'elle est disponible sur plusieurs systèmes d'exploitation (un système d'exploitation = une plateforme). En date de mai 2018, GeeXLab est disponible pour les plateformes suivantes:
Ma plateforme principale est Windows 10 64-bit. Toutes les applications dont j'ai besoin sont disponibles, les cartes graphiques sont parfaitement supportées et toutes les technologies utilisées dans GeeXLab sont présentes.
GeeXLab est un outil de création d'application. Mais de quel genre d'application exactement? Et bien essentiellement les applications de visualisation de données au sens large du terme. GeeXLab permet aussi de créer des applications de traitement de l'information. Visualsation et traitement de l'information. Voilà le domaine des applications possibles de GeeXLab.
La 3D n'est qu'une façon de représenter de l'information. Mais c'est une façon terriblement puissante. Dans ce domaine, GeeXLab possède toutes les fonctionnalités pour facilement créer des applications 3D. Vous souhaitez afficher un objet 3D ou développer un petit jeu video? Pas de problème, GeeXLab est présent. Mais il n'y a pas que la 3D. Vous avez envie de créer votre propre visionneuse d'images 2D? Encore une fois GeeXLab est là. Mais comment se répartissent vos fichiers dans un répertoire ou sur le disque dur? GeeXLab est encore là. Envie de jouer avec votre webcam? Pas de problème, GeeXLab aime bien les webcams. Envie de piloter une LED? GeeXLab connait bien le connecteur GPIO du Raspberry Pi. Et la VR? Oui GeeXLab sait aussi afficher des données en Réalité Virtuelle avec les gros casques HTC Vive ou Oculus Rift.
Abordons maintenant le fonctionnement de GeeXLab. Une application GeeXLab est composée de un ou plusieurs fichiers contenant le code source ainsi que d'un ou plusieurs fichiers contenant les données (images, mp3, objets 3D, base de données, etc.). Les fichiers de données ne sont pas obligatoires, la demo peut générer elle-même ses propres données (données procédurales).
Pour programmer une application, plusieurs languages de programmation sont à disposition:
Fondamentalement, une demo GeeXLab est composé d'un fichier XML qui décrit le contenu de la demo. Le XML n'est pas un language de programmation, c'est un language de description. Et il est parfait dans le cas de GeeXLab. Toute la demo GeeXLab peut être codée dans le fichier XML (c'est assez pratique pour des toutes petites demos) ou être répartie sur plusieurs fichiers. Mais dans tous les cas, il y a toujours un fichier XML principal qui représente le point d'entrée. J'appelle souvent ce fichier main.xml.
Ce fichier XML décrit les différents scripts qui sont le coeur du code source. Ces scripts sont écrits avec les languages Lua ou Python. Et cette fois-ci nous avons affaire à des vrais languages de programmation. Les deux languages peut etre présents dans une demo GeeXLab. Ils ne sont pas mutuellement exclusifs.
Les scripts Lua et Python peuvent être contenus dans le fichier XML principal ou être stockés dans des fichiers séparés. Dans ce cas, le fichier XML contient des références vers les fichiers de script.
Le GLSL est le language de programmation des GPUs (le processeur principal d'une carte graphique) et est utilisé pour programmer les shaders, responsables de la plupart des effets graphiques que l'on voit dans les applications 3D modernes et les jeux video. Nous reviendrons plus en détail sur les shaders dans une autre partie. Tout comme les sctipts, les shaders écrits en GLSL peuvent être contenus dans le fichier XML principal ou être stockés dans des fichiers séparés.
Le fonctionnement de GeeXLab est relativement simple. Le fichier XML est le point d'entrée de la demo. Une demo est essentiellement composé d'un bloc d'initialisation et d'un bloc de traitement. Lors d'une demo, le bloc d'initialisation est exécuté une seule fois, alors que le bloc de traitement est exécuté de manière répétitive dans une boucle infinie. La sortie de la boucle (par exemple par une appui sur la touche ESC) permet de terminer la demo.
GeeXlab dispose de differents types de scripts:
L'exécution des différents scripts peut être résumé par le petit diagramme suivant:
Comparé à une application traditionnelle (un logiciel de bureautique comme Word ou à un navigateur Internet), une application 3D temps réel comme GeeXLab (et tous les jeux video au passage) exécute en permance le rendu de la scene 3D. Ce rendu, qui est codé dans le script FRAME, est exécuté près de 60 fois par seconde.
Mais au fait pourquoi 60? 60 correspond tout simplement à la fréquence de rafraichissement vertical de votre moniteur LCD: 60Hz. A chaque balayage vertical de l'écran, le script FRAME est exécuté. Note démo est synchronisée sur le rafraichissement vertical de l'écran. Cette synchronisation sur le rafraichissement vertical porte un petit nom: la VSYNC (ou Vertical SYNChronization). La démo, dans ces conditions, tourne à 60FPS (FPS = Frames Par Seconde).
Mais on voit souvent des démos 3D qui tournent plus vite que 60FPS, pourquoi? Tout simplement parce que la démo n'est plus synchronisée sur le rafraichissement vertical. Dans ces conditions, le script FRAME est exécuté le plus de fois possible par seconde. C'est le mode préféré des logiciels de benchmarking. GeeXLab possède une instruction qui permet d'activer ou de désactiver dynamiquement la VSYNC.
Le Hello World est la façon la plus efficace et la plus simple pour passer de la théorie à la pratique. Grâce à cette micro démo, nous allons voir concrêtement la structure du fichier XML et le contenu des scripts. Et pour cette demo, nous utiliserons le language Lua.
Sans plus attendre, voilà la demo Hello World:
Pour tester la demo, suivez le guide:
Bon ok, c'est un poil plus compliqué sous Linux pour lancer une demo. Mais bon, un hacker de pixel ne se laisse pas impressioner par cette petite commande, n'est-ce pas?
Et voila le code source de la demo v1 avec une structure vraiment très simple:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<glsl_hacker>
<window name="win3d01" title="Hello World!" width="700" height="200" />
<script name="init_scene" run_mode="INIT" filename="init.lua" />
<script name="update_scene" run_mode="FRAME" filename="frame.lua" />
<script name="resize_scene" run_mode="SIZE" filename="size.lua" />
</glsl_hacker>
Je pense que vous avez facilement reconnu les différents scripts de la demo: INIT, FRAME et SIZE. Chacun de ces scripts est stocké dans un fichier .lua séparé. Ces fichiers Lua sont tous enregistrés dans le même répertoire que le fichier XML principal (qui au passage se nomme main.xml). Regardons ensemble ces différents fichiers:
font = gh_utils.font_create("Tahoma", 14)
On voit que l'on crée un objet font. Le detail de la fonction qui sert à créer l'objet font n'est pas important pour le moment.
3 - le script FRAME: fichier frame.lua
gh_renderer.clear_color_buffer(0.4, 0.4, 0.4, 1.0)
x = 10
y = 20
gh_utils.font_render(font, x, y, 1.0, 1.0, 0.0, 1.0, "Hello World from GeeXLab!")
x = 10
y = 40
elapsed_time = gh_utils.get_elapsed_time()
gh_utils.font_render(font, x, y, 1.0, 1.0, 1.0, 1.0, "Elapsed time: " .. elapsed_time)
Le script FRAME c'est ce fameux script qui est exécuté sans cesse dans une boucle infinie. C'est d'ailleurs la seule méthode
pour insufler de la vie dans la démo et pourvoir créer de l'animation. Dans cette démo, l'animation se résume au temps qui s'écoule...
4 - le script SIZE: fichier size.lua
winW, winH = gh_window.getsize(0)
gh_utils.font_set_viewport_info(font, 0, 0, winW, winH)
Encore une fois le contenu du script n'est pas important pour le moment. Mais on voit que l'on récupère la nouvelle taille de la fenêtre à la première ligne pour ensuite l'utiliser à la seconde.
Comme on peut le constater, la structure de base d'une application (ou démo) GeeXLab est très simple. Cette même démo aurait pu être totalement contenue dans le fichier XML principal de la façon suivante (demo v2):
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<glsl_hacker>
<window name="win3d01" title="Hello World!" width="700" height="200" />
<script name="init_scene" run_mode="INIT" >
<raw_data><![CDATA[
font = gh_utils.font_create("Tahoma", 14)
]]></raw_data>
</script>
<script name="update_scene" run_mode="FRAME" >
<raw_data><![CDATA[
gh_renderer.clear_color_buffer(0.4, 0.4, 0.4, 1.0)
x = 10
y = 20
gh_utils.font_render(font, x, y, 1.0, 1.0, 0.0, 1.0, "Hello World from GeeXLab!")
x = 10
y = 40
elapsed_time = gh_utils.get_elapsed_time()
gh_utils.font_render(font, x, y, 1.0, 1.0, 1.0, 1.0, "Elapsed time: " .. elapsed_time)
]]></raw_data>
</script>
<script name="resize_scene" run_mode="SIZE" >
<raw_data><![CDATA[
winW, winH = gh_window.getsize(0)
gh_utils.font_set_viewport_info(font, 0, 0, winW, winH)
]]></raw_data>
</script>
</glsl_hacker>
Dans le cas particulier de cette petite démo, les scripts INIT et SIZE ne sont pas vraiment indispensables. Cette démo pourrait se contenter d'un seul script FRAME qui gère aussi l'initialisation et le redimensionnement (demo v3):
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<glsl_hacker>
<window name="win3d01" title="Hello World!" width="700" height="200" />
<script name="update_scene" run_mode="FRAME" filename="frame.lua" />
</glsl_hacker>
Tandis que le contenu du script frame se résume à:
if (font == nil) then
-- INIT
font = gh_utils.font_create("Tahoma", 14)
end
-- SIZE
winW, winH = gh_window.getsize(0)
gh_utils.font_set_viewport_info(font, 0, 0, winW, winH)
-- FRAME
gh_renderer.clear_color_buffer(0.4, 0.4, 0.4, 1.0)
x = 10
y = 20
gh_utils.font_render(font, x, y, 1.0, 1.0, 0.0, 1.0, "Hello World from GeeXLab!")
x = 10
y = 40
elapsed_time = gh_utils.get_elapsed_time()
gh_utils.font_render(font, x, y, 1.0, 1.0, 1.0, 1.0, "Elapsed time: " .. elapsed_time)