Je viens ici pour présenter mon projet et vous montrer son avancement pas a pas.
Donc j’ai décidé de me lancer dans une lib 3D multi-plateforme , qui vise ces machines :
-PC (Windows/Linux/MAC OS).
-PlayStation 2
-Dreamcast
-PSP
Si dans le futur j’ai beaucoup de temps :
-WII
-GAMECUBE
-XBOX
Et si j’ai encore plus de temps : -PlayStation 1 -N64 (Non pas la Saturn ).
Pour la Version PC
J’utilise la SDL 1.2 pour le fenêtrage et les évents , et OpenGL 1
Éventuellement mettre une option pour OpenGL 2 voir 3 , mais mon but n’est pas de pousser la version PC , le but de cette lib c’est pas de faire des jeux 3D Moderne
Pour la Version Dreamcast
La version Dreamcast j’avais utilisé un binding OpenGL (que faudra que je m’en passe pour exploiter la machine a 100%).
Pour la Version PS2
Actuellement je travaille sur la version PS2 , donc attendez vous a un gros pavé !
Pour ceux que ça intéresse pas des masses je vous conseille de sauter ce passage.
Avant de vous parlé Voila quelque truc a savoir :
La PS2 a un processeur principal le EE (Emotion Engine) cadencé a 300MHZ
Et 2 co processeur mathématique le VU0 et VU1 qui possède respectivement 4 et 16ko.
Et son GPU le GS (Graphic Synthesizer ).
Niveau info intéressante sur PS2 , ben deja la GS utilise des nombres a firgule fixe ! je trouve ça marrant , enfin ça réduit les transferts la PS2 est une console 64/128 bits sur 64 bits en envoie les coordonnées pour X,Y,Z. (ici Z dans le sens Z Buffer) , 16 bits pour X , 16 bits pour Y et 32 bits pour Z.
L’affichage de la PS2 se fait sur un "écran virtuelle" (je sais pas comment appeler ce truc) sur 4096x4096 , du coup si on veut avoir des nombres négatif , le mieux c’est d’afficher dans son centre donc 2048 x)
La PS2 possède 4Mo de VRAM mais cette VRAM prend en compte le Frame Buffer et le Z buffer , et donc ça réduit énormément le nombre de texture mais !
Si on met le Zbuffer en 16 bits.
Le Frame Buffer en 16 bits (mais ça réduit le nombre de couleur).
Le Frame buffer peut être en 640x240 (qui peut être en mode 640x480 en agrandissant par deux la hauteur de l’écran).
De plus si on utilisent des textures en mode palette de couleur (oui c’est la seul console qui peut le faire de cette génération a ma connaissance) , d’ailleurs les jeux squaresoft utilisait cette compression , vu que leur textures faisait moins de 256 couleurs !
Donc du 640x256 (c’est le mode NTSC) ça prend 1Mo en mode 16 bits le FB et 1,6 Mo le mode 32 bits.
Une texture peut prendre donc 64ko , donc pour 2Mo on peut avoir 32 texture de 256x256.
On peut faire des transferts dma RAM/VRAM, la PS2 possède des transferts très rapide et je pense qu’on peut rajouter 4-8 textures en plus sans que les perf soit très altérer.
Alors comme vous le savez c’est une console extrêmement compliqué et qui même si elle est la console la plus vendu de l’histoire ben la scène homebrew est quasi inexistante.
Il existe un binding OpenGL fait par des amateurs , je l’ai jamais utilisé mais en regardant son code , il n’afficherait pas plus de 15-20k poly par frame , soit moins 1 millions de poly par seconde.
Et le PS2 SDK lui probablement moins de 10k poly par frame si on l’utilise comme tel.
Pour expliquer la prog PS2 , si on fait un affichage 3D en Macro code avec le VU0 (en gros un truc pas en parallèle qui s’exécute sur le EE principal), on affiche 9000 poly.
On peut augmenter a 13000 poly si on fait un Double Buffer !
Oui on peut faire un double buffer sur les transferts DMA vu qu’ils sont en parallèle (bref non bloquant) on peut faire le calcul suivant en attendant.
Par exemple sur les vielles machines comme la SNES ou la Mega Drive le DMA est bloquant et donc en attend que le DMA finisse son transfert pour reprendre le main.
J’avais augmenter les perf a 14500 poly en réduisant les transferts DMA.
A vrai dire mon premier test sur PS2 j’avais remarqué un truc , deja que j’affichais que 25k poly (via VU1) et que le temps de calcul était assez bas.
La réponse j’ai eu du mal a la trouver le premier est que mon temps de calcul assez bas est sûrement du a la lecture des entrées qui est sûrement un peu longue (a vu de nez elle est de 10 cycle).
Le second avec beaucoup de test j’ai remarqué que mes temps de calcul était réparti comme ceci :
-10% DMA
-70% le VU1
-20% GS
Donc j’ai du retravailler la programmation du VU1,enfaîte c’est un processeur qui ne fait que 1 cycle instruction sous certaine condition , sinon le VU va attendre que l’instruction finisse avant de passer a la suivante (qui dure a peu prés 4 cycle par instruction).
Et cela devient très compliqué a optimiser croyait moi , parce que ça demande de faire un code comment dire dégueulasse il faut pas organiser forcément son code de façon ’logique’ en gros faut faire tjs faire des calculs , par exemple calculer le vertex suivant ou récupérer la valeur du vertex en même temps (oui c’est un processeur Superscalaire et VLIW) ,ah oui le VU1 c’est en asm que ça se code , un assembleur 128 bits et assez difficile a coder, et c’est lui qui fait tout les calculs 3D (et faire de l’asm en 3D sur un processeur aussi compliqué que le VU1 c’est sportif ! ).
D’un coté ça explique pourquoi la PS2 a mis du temps pour être exploiter (et que en amateur elle ne l’a jamais était exploiter !).
Ma première optimisation m’a permis de monter a 37k poly par frame.
Ensuite j’ai optimiser a droite a gauche 41 puis 45k et la blocage :3
Vous vous souvenez j’ai dit que le GS prenait a peu près 20% , on peut le faire en parallèle et j’ai gagnait donc les 20% , et je suis montait a 64k poly, ensuite j’ai réduit encore l’utilisation du VU1 en optimisant le code , et je suis monté a 69k poly.
La première fois que j’ai fait cela (a 64k poly) ça marchait bien mais quand j’ai encore optimiser a 69k poly , ça marchait bien sur l’ému mais pas sur la PS2 réel ou j’avais de gros bug d’affichage , j’ai remarquer en faite que le souci venait du transfert vers le GS (que pendant le transfert je l’écrivait en court de route ), et maintenant dans le code du VU1 je met un double buffer x)
Voila le résultat sur une PS2 :
69k tri : https://img15.hostingpics.net/pics/77015520110126055420.jpg
rendu zack :
On faisant des petites optimisation j’ai pu monter encore a 70k poly.
Ma dernière optimisation a était de réduire les transfert DMA ,donc en mettant des virgule fixe et en faisant les transfert en parallèle au VU1 et donc j’ai pu obtenir plus de 115k tri :
Je peux encore augmenter , le VU0 se fait en parallèle au VU1 donc on peut encore augmenter le nombre de vertex calculer. La dernière technique a mettre en place est difficile , c’est les index donc la je parle d’une augmentation facile de 100% de poly en plus , je ne détaillerai pas la difficulté de cette technique dans mon cas (non faire un for avec un tableau a la con ça augmente que dalle ).
Niveau code donc je code en C et en assembleur , tout le code relatif a l’affichage je le fait moi même en tapant directement sur les I/O .
Conclusion
Donc pour ma lib elle gérera quoi exactement ? :
-Le Rendu 3D
-l’animation par squelette
-les collisions
-le rendu 2D software et Hardware
Pour ceux qui se demande pourquoi , la plupart des consoles de cette génération possèdes des instructions assembleurs spécifique pour les calculs mathématique , le but de ma lib est que son utilisateur n’aura pas besoin de les codé lui même donc que je dois gérer les collisions et l’animation
Pour le rendu 2D software , un sprite peut prendre beaucoup de place en VRAM donc on les gérant en software en peut gagner beaucoup en mémoire.
Voila donc le code source ce trouve ici : https://github.com/Kannagi/LMP3D
Vous m’excuserez du code quelque fois peu propre , mais bon apparemment dans la scène homebrew PS2 personne n’avait atteint les 330 000 vertex par frame , donc je me suis pressé de finir pour présenter mon travail.