Description

Mise à jour à venir.

Happy or not API.

J’ai été tranquille sur le blog dernièrement. Nous sommes allés nous dorer la couaine au Lac. Il faisait au moins 50 à l’ombre. Certains palmiers commençaient à nous balancer des noix de cocos. Nous avons fait pleins de belles activités comme présenter Godzilla à son arrière Grand-père. Ces vacances m’ont fait du bien, car juste avant de partir, mon jeu m’a fortement contrarié. Et depuis ce temps, je me suis résigné à me tourner vers d’autres techniques. Alors, am I Happy or not API.
Le problème : Tout allait bien dans mon jeu, j’avais atteint un nombre raisonnable d’entités à l’écran sans grande dégradation des performances. Pour pousser la machine un peu plus, j’ai voulu faire défiler mon décor à des vitesses ridicules. En situation de jeu on peut penser à des scènes ou le vaisseau du joueur tente de se sauver d’une base ennemie en train d’exploser. Alors là, tout va vite. Les ennemis sont rares ou absents, il n’y a que le décor qui pète de partout et qui se met inlassablement dans le chemin du joueur. Le tout défile à vitesse grand G afin de créer l’illusion que le joueur a poussé les réacteurs de sa machine à fond. Sauf que, techniquement ça ne vas pas. Quand le décor défile rapidement, il arrive un moment dans l’animation ou le décor n’est pas dessiner ou il devrait l’être. Il y a comme un effet de réfraction. La réfraction c’est ce que l’on observe quand on plonge une paille dans un vers d’eau et qu’elle semble plié au niveau de la surface. En termes de performance, cela ressemble à un phénomène de « hitching ». Autrement dit quand un objet arrête son mouvement momentanément et continue par la suite. Dans mon cas je soupçonne cette dégradation de performance être dû à l’action du « Garbage Collector » qui demande quand même pas mal de ressource en java. Et contrairement au C, on ne peut pas contrôler son action de façon programmatique et implicite. Je soupçonne aussi le fait d’utiliser des « BufferedImage » comme matière première au graphisme, d’être un choix mal approprié à des applications graphiques intenses. Quoique je n’en suis pas sûr, je présume que les actions sur les « BufferedImage » sont gérées au niveau du CPU et non du GPU. Le processeur graphique. Le CPU est le cœur de tout ordinateur, il est doué pour les calculs. Tandis que le GPU est la carte graphique du système que ce soit Radeon, ATI, AMD, etc. Ce dernier traite le graphisme de façon optimale. DirectX et OpenGL sont traités par le GPU laissant plus de ressources au CPU.

En partant de là, j’ai effectué plusieurs tests pour modifier le comportement du « Garbage Collector », sans succès. Je me suis donc tourné vers OpenGL. Selon plusieurs commentaires dans les forums, il semblait très rapide au niveau de la performance. J’avais toujours cru que la technologie OpenGL n’était que pour le 3D, mais non, je me suis trompé. Sauf, que la programmation d’OpenGL est très différente de ce que je suis habitué. En GL, on travaille avec une seule instance globale pour tout le programme. Ça va un peu à l’encontre de la philosophie objet. J’avais quelques réticences à me lancer dans l’apprentissage de GL parce qu’en fait, je n’ai aucune certitudes que cela va régler mon problème. Car mon foutue problème peut être tout simplement dû à une erreur algorithmique… Et dans ce cas, aucune technologie miracle ne va m’aider. N’empêche qu’apprendre OpenGL, m’ouvre les portes aux principes de programmations plus modernes et à l’apprentissage du 3D. Et c’est exactement là que j’en suis. J’ai lu de la documentation sur OpenGL ainsi que des exemples de programmations que j’ai tenté de recréer. Pour utiliser OpenGL  en java, il faut passer par la bibliothèque de programmation (API) jogl. Jogl est une interface java qui fait le lien avec les fonctions natives d’OpenGL. Jogl respectent la syntaxe mot pour mot de OpenGL. Ceci rend les exemples en OpenGL facilement transportables en java. N’empêche, à cause de ma carte graphique qui diffère de celle des exemples et aussi  à cause des différentes versions d’OpenGL, j’ai eu beaucoup de difficultés à obtenir des résultats semblables à Davison pour ne citer que lui. Davison utilisait jogl 1, et moi j’ai utilisé la dernière version qui était la 2 quelque chose. J’ai fini par laisser tomber…

J’ai alors essayé le jeu de Fabien Sanglard que l’on peut trouver ici.

J’ai été impressionné. Après avoir téléchargé le code et que je l’ai fait rouler sur mon ordi, j’ai pu afficher 15000 entités avec détection des collisions et une performance acceptable de 30 fps. Vraiment, si OpenGL est derrière tout cela, son apprentissage en vaut la peine. Sauf que Sanglard est passé par l’api LWJGL ou light weight java game librairie. Il s’agit d’une librairie de classes java orienté jeu. Les concepteurs de cette API on voulu faire une bibliothèque ne contenant que le nécessaire à la programmation de jeu vidéo ce qui en fait une librairie assez simple. Remarquez que la simplicité est toujours relative. On peut avoir plus de classes spécifiques au développement de jeu en utilisant Slick2D que je n’ai pas encore essayé et que je ne prévois pas nécessairement utiliser dans un avenir proche.  Je préfère développer mes propres outils afin de mieux comprendre leurs mécanismes. Quand j’aurai un jeu adéquat, je verrai ce que peut m’apporter Slick2D ou pulpcore, qui contiennent déjà des classes spécifiques telles que les sprites ou les émetteurs de particules. LWJGL ce concentre vraiment sur l’affichage, OpenGL, l’interface avec l’usager (joystick), etc. C’est donc en me basant sur ce que Sanglard à fait que j’ai entamé la reconception de mes classes de gestions d’affichages, de chargements d’images, de sprites, etc. J’imagine que d’ici deux semaines je devrais être en mesure de tester à nouveau mon jeu. Et histoire de me compliquer la vie encore plus, il semble que les mises à jour de java 19 et 20 contiennent des bugs qui chargent les images  en AGBR plutôt qu’en RGBA. Ce qui rend le jeu exécrable. Voir le commentaire ici-bas de Sanglard :

April 5, 2010 : It seems there is an issue with the last JRE 1.6 on windows plateforms. ImageIO.read is loading PNGs as AGBR instead of RGBA. I am not sure if it's a JVM bug or if the PNG are not compliant and I lack time to investigate :/, if anyone have some time to investigate, feel free to email me !

Pour le moment je contourne le problème en spécifiant à la console java d’utiliser une version de la JRE antérieur à 19. Il faudra bien que je trouve une solution à ce problème un jour si je veux que mon jeu soit distribuable.

Commentaires