LMP3D une nouvelle librairie ! (PS2/DC)

a marqué ce sujet comme résolu.

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  :
Image utilisateur

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 :
Image utilisateur

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.

+4 -0

Eh non le projet n’est pas mort :P
Je ne fait que très peu de news , donc voila les grosses nouveauté :

Je gère une nouvelle plateforme la PS1 :
-Émulateur m’indique que je peux afficher 2000-3000 triangles par frames
-Je gère les textures 8bpp
-Chargement et rendu d’un model 3D

La difficulté était bien sur de faire un truc avec , vu que le SDK non officiel est très récent mais aussi extrêmement vide xD
Une particularité de la PS1 , elle ne gère pas les nombres à virgule flottant et elle ne possède pas de Zbuffer :D
Donc j’ai du faire un algorithme du peintre pour afficher les triangles dans l’ordre…
Le gros souci c’est qu’elle ne manipule que des matrices 3x3 , et elle possède en hard un truc pour faire de la ’perspective’ mais jamais réussi a avoir le résultat voulu :(
C’est le seul truc qui me bloque actuellement dessus ^^’

Voila un screen :
Image utilisateur
(s’il est un peu bizarre c’est que les conversion float -> nombre entier , y’a des pertes forcément )

La version Dreamcast :
-pareil, néanmoins je peux afficher ’18 000’ triangles

La Dreamcast sa particularité (outre qu’elle possède plusieurs Frame buffer en tile) , enregistre tout les vertex en Vram :aie:
Une commande permet de clear le FrameBuffer et de rendre le rendu stocker sur les vertex , si Sega a choisi cette méthode c’est que le rendu se fait en "parallèle" (enfin quand on l’appelle) a l’exécution , il n’est pas bloquant !
Le souci est que cela demande d’avoir un double-buffer de vertex (pour pas avoir de collision entre le rendu et ce qu’on envoie) et donc cela consomme beaucoup en VRAM et je pense que pour la version DC le mieux c’est de tourné sur 30 fps (une partie rendu et une partie game logic ) et ça permettra de faire une partie des calculs de l’animation par squelette sur l’autre frame .
De cette façon je peux avoir 26k triangles sur une frame avec ou sans animation par squelette ;)

Cela m’a demandé un gros taff de réécrire (et comprendre) tout la partie bas-niveau , KGL et PVR (qui sont les lib homebrew pour la DC pour le rendu) ne stocke de toute façon que 512ko de vram (équivalent à "7000 triangles").
Enfin cela dépens de comment on gère nos triangles pour réduire le nombre , on peut mettre les U/V en float 16 bit ce qui réduit leur taille et les transferts (et je ne stocke par les couleurs ) ;)
Je stocke un peu moins de 2Mo (a peu près 28k triangles max).

Un screen :
Image utilisateur

La version PS2:
J’ai pas eu de gros changement , j’ai régler des bugs graphique et rajouter le clipping (pour les triangles) sans grande perte de performance :)
Je pense avoir trouver enfin la façon d’utiliser les deux VU :)

Pour tout ces projets j’utilise mon propre format 3D pour 2 principal raison :
-ne pas me faire ’chier’ avec tout les format 3D
-avoir un chargement ultra rapide !

Ce format gère les index , les nombres flottants/nombre fixe , l’animation par squelette , et il est bien sur en format binaire ;)
J’utilise assimp et j’ai fait une bonne découverte ( qui va m’aider pour la PS2 ) c’est qu’on peut créer des submeches avec index , ça sera parfait pour diviser le taff entre le VU0 et VU1 ! :D

De manière général :
Pour chaque plateforme je gère les conversions adéquate flottant/nombre fixe , une petite idée de quel format est optimisé pour chaque plateforme :
PC:nombre flottant,index
PS1:nombre fixe,pas d’index
PS2:nombre fixe, index + submesh
DC:nombre flottant,index

J’ai créer un convertisseur (a la volée) qui convertie les images en format adéquat , voici les formats conseillés:
PS1,PS2 : PCX
DC : PNG ou VQ compressed(pas encore fait)
PC : PNG

Par exemple la PS1 ne gère que les 8bpp ou les RGB16 bits , donc si vous chargez un PNG il va le convertir en RGB16 bits,de même que la Dreamcast (et la PS1) ne gère bien que les RGB 16bits donc pour le PCX il va convertir la palette de couleur en RGB24bit en RGB 16bits.

Je gère les fichiers .tar (une sorte de .zip mais sans compression), et le bmp,pcx et png.

Je crois avoir rien oublier (j’ai fait pas mal de petit détails mais je ne vais pas vraiment m’attarder dessus , les détails sont surtout des choix de design pour avoir une lib cohérente sur autant d’architecture différentes).
Alors le github de la lib : https://github.com/Kannagi/LMP3D
Et pour le convertisseur de format 3D : https://github.com/Kannagi/BCMConvert

Je vais essayer d’avoir une version stable assez rapidement pour avoir quelque contributeur dessus (vu l’étendu du projet je commence a désespérer seul ) , j’ai une liste encore très longue de truc a finir :/

J’avais fait une petite vidéo de la lib , et cela montre aussi ma façon de bosser :
https://www.youtube.com/watch?v=AEwg1k-KOf4

Bien donc j’ai quelque nouvelles depuis :)

Alors pour PS1 je gère parfaitement la perspective maintenant ah ah :
Image utilisateur

J’ai enfin rajouter mes fonctions 2D , coder 4 fois le même code de manière un peu différente la joie , voila le résultat :
Image utilisateur

Donc je gère le tilemap (avec scrolling et limite du terrain) , les sprite + animation et bien sur le flip horizontal/vertical (sur sprite ou tile).
(Qui sait je rajouter l’animation par tile automatique , la Neo Geo le faisait elle animait les tiles automatiquement).

(Et puis certain sont peut être intéresser pour faire des jeux 2D aussi).

Cela m’a pris du temps parce que j’ai voulu gérer le 8bpp/4bpp partout donc comme je le gérer pas j’ai du apprendre comme faire sur certaines plateformes :D
La Dreamcast est assez limité sur ce point , elle ne gère que 1024 couleurs niveau palette (disons que la compression ne se fait pas vraiment a ce niveau là ).
Sur PC je converti en RGBA (mais donc du coup si on utilise des effets sur la palette ça marchera pas sur PC ah ah xD).

J’ai rajouter le Backface culling sur PS1,PC et Dreamcast (sur PS2 un peu la flemme de plus je ne sais pas trop comment faire ça dessus , je ne comprend pas pourquoi la PS2 propose un ’Vector outer product’ mais ça multiplie avec x,y,z , alors que je m’attendais plus a un cross product ).
Sur Dreamcast , il n’y a pas de cross product en hardware , j’ai fait 2 inner product + soustraction :p

J’espère que la suite sera rapide la camera , ’Viewing frustum culling’ et comprendre pourquoi mon z-clipping ne marche pas lol
Et je pense faire ma première version ’stable’, la suivante sera pour l’animation par squelette :)

A la limite pour faire de la 2D , elle reste peut être même une bonne ’alternative’ pour la SDL2 et la SFML :p

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte