Ce topic regroupe l'ensemble des évolutions du projet de jeu 1v1 3D.
Brève présentation du jeu :
1v1 3D est un projet de jeu de tir à la première personne (fps) en multijoueur sur graph 75/85/95 en utilisant le cable 3pin...
Vous êtes en l'an 2119, et l'homme vit maintenant sous terre. La guerre fait rage entre les différents clans qui essayent de s'accaparer la terre entière... Vous spawnez dans un tunnel désaffecté et vous avez pour mission d'éliminer tout intrus. Cependant, la répartition des territoires et loin d'être claire, et votre adversaire vous traquera, jusqu'à ce que l'un d'entre vous tue l'autre...
Avant de commencer la partie il vous faudra choisir l'une des 3 armes disponibles :
Le pistolet simple (fréquence de tir moyenne, dégâts moyens, et croix pour viser)
Le fusil d'assaut (fréquence élevée, faibles dégâts par balle, et croix pour viser)
Le pistolet laser (rechargement long, mais dégâts puissants, pas de croix et présence d'un viseur avec zoom et masque)
Avancement du projet :
Ce moteur 3d, du nom de FxEngine, est en cours de développement. Je suis actuellement en train de le réécrire sous GNU linux. Cela prend du temps car j'essaie de le rendre réutilisable dans d'autres jeux.
Progrès publiés :
1: version du CASIO fx9860 SDK
Un premier jet très moyen en de performances
Alpha 1
J'ai un peu travaillé sur le sujet, notamment sur comment déformer les textures et j'arrive mainenant à des resultats comme ça :
Donc le rendu est ok, la taille de l'image rendue est de 124x85 mais toutes les variables sont des
double et donc le rendu est très lent, à en juger par le le nombre de FPS affiché en bas (bon, on calc c'est un chouia plus rapide, parce que ici je fais tourner le logiciel avec wine mais 6-7 FPS pour une pyramide pas super proche, ça ne fait pas rêver).
Il faudra donc que je transforme le système de codage des coordonnées en
int et optimiser la fonction de rendu des textures.
Je compte réécrire tout de zéro afin de pouvoir ajouter le clipping et la suppression des faces cachées.
Vous pouvez d'ailleurs noter la présence en bas d'une partie du futur affichage ingame !
Au point où j'en suis, j'utilise les libs suivantes :
MonochromeLib de pierrotll
LibText de lephenixnoir
2: Version 2
Alors que la version précédente a été réalisée avec le SDK de CASIO, j'ai décidé de poursuivre le projet avec les outils libres :
-> GNU Linux (bah oui j'ai dit outil libre)
-> le cross compilateur
GCC pour les architectures sh3eb-elf (le programme est quand même compatible SH4-A, donc avec les calculatrices les plus récentes)
->
le fxsdk et
gint, deux outils puissants faits par
Lephenixnoir
Bien évidemment, cela n'empêche pas le programme d'être mis sur la calculatrice depuis windows, la manipulatiuon se fait comme avec un add-in normal.
Bon c'est pas tout, mais revenons à la bete
Si vous avez regardé la version précédente vous allez certainement être surpris !
J'ai réécrit mon programme de zéro, et appliqué les optimisations suivantes :
Optimisation 1 : J'ai réécrit mon programme, en utilisant à 99,99% des entiers.
Optimisation 2 : J'ai ajouté la notion de coté visible d'une face.
Optimisation 3 : J'ai changé la méthode de conversion des coordonnées, j'utilise maintenant les matrices de rotation.
Optimisation 4 : Un grosse optimisation au niveau de l'affichage des triangles, notamment une suppression du cas par cas pour une boucle plus légère.
Ces quatre optimisations, associées à l'utilisation du puissant compilateur gcc, et de gint (par Lephenixnoir) qui remplace les syscalls peu optimisés de CASIO, permettent d'obtenir le rendu de triangle, à charge égale, d'une vitesse environ 10 fois supérieure (oui, 10 fois, vous ne rêvez pas !). De plus, j'ai complété la fonction de déformation des textures, appliquant maintenant la perspective de façon plus affinée sur celles-ci.
Cependant, la technique de déformation n'est pas encore complètement au point et donc certaines vues sont un petit peu erronées, c'est notamment ce que j'essaierai de corriger pour la prochaine version.
Vous pouvez allez voir l'avancement sur
le dépot gitea du projet.
Le moteur FxEngine est également accessible, mais reste pour l'instant incomplet. A partir du moment où elles auront atteint un minimum de stabilité je publierai en tant que programme. N'hésitez pas à dire ce que vous en pensez !
Citer : Posté le 17/07/2019 20:02 | #
Dans ce cas realloc() te sera sans doute utile
N'hésite pas à doubler la taille du tableau à chaque fois pour maintenir des perfs raisonnables !
Citer : Posté le 17/07/2019 20:55 | #
Je pense plutot a une classe qui contient un pointeur sur la suivante
Pour l'acces ce sera long, mais me calcul a la chaine tres rapide
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog
Citer : Posté le 17/07/2019 20:57 | #
Très bonne idée ! Du coup ça s'appelle plus un vecteur mais une liste chaînée
Citer : Posté le 17/07/2019 21:02 | #
Je compte utiliser ça pour les triangles, notamment. Vu qu'en appelant la fonction display de l'un, ça peut faire une réaction en chaîne.
Tiens, d'ailleurs je viens d'ajouter le lien vers le gitea.
La je suis en train de tout recoder de zéro donc pr l'instant c'est que des classes isolees
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog
Citer : Posté le 17/07/2019 21:04 | #
Certes, toutefois ce n'est pas vraiment une chaîne, plus un arbre...
Et la forme de l'arbre change quand tu tournes la caméra donc ça veut dire que tu dois reconstruire ta structure à chaque frame ou presque !
Merci pour le lien vers le Gitea, n'oublie pas de mettre une espace avant le point (ou d'utiliser une balise [url]) sinon il est pris dans l'URL.
Citer : Posté le 17/07/2019 21:10 | #
Je me suis mal expliqué
Je ne sois pas reconstruire la structure, puisque chaque triangle contient des pointeurs vers ses sommets, stockés à part et partagés, et ce sont eux qui sont modifiés lors d'un déplacement, pas les triangles
Ajouté le 17/07/2019 à 21:17 :
Pour etre plus clair, je peux parler de faces a la place de triangles, mais de toute facon elles sont triangulaires donc ça ne change rien
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog
Citer : Posté le 17/07/2019 21:27 | #
Je vois. Quand tu dis "réaction en chaîne" je comprends que le dessin de certains triangles doit engendrer le dessin d'autres triangles (qui sont devant). Est-ce bien de ça que tu parlais ?
Parce que si tu dois chaîner de cette façon, ça va être compliqué '-'
Citer : Posté le 17/07/2019 21:30 | #
Cest bien de ça que je parlais
Bon de toute façon je n'en suis pas encore là, demain je vais recoder la fonction de translation des coords des points
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog
Citer : Posté le 17/07/2019 21:44 | #
On est d'accord du coup, mais quel triangle en cache quel autre ce n'est pas un information fixe. Ça change si tu tournes l'angle de la caméra...
Citer : Posté le 17/07/2019 21:49 | #
Je ne parle pas de triangle qui en cache un autre, mais de tableau de triangles pouvant voir sa taille incrémentée facilement au sein d'un objet complexe
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog
Citer : Posté le 17/07/2019 21:50 | #
D'accord, mais pourquoi dessiner l'un deux provoquerait une réaction en chaîne du coup ? :o
Citer : Posté le 17/07/2019 21:50 | #
De toute facon j'utilise un zbuffer pour la gestion de la superposition des triangles
Ajouté le 17/07/2019 à 21:54 :
Je veux dire que dans la fonction display du premier triangle (le seul dont l'adresse est stockee dans lobjet), il y a un appel de la fonction display du prochain triangle et l'objet est dessiné avec un seul appel
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog
Citer : Posté le 17/07/2019 22:00 | #
Ah, pour un objet formé de plusieurs faces ! Il s'agit donc juste de dessiner plusieurs faces d'un coup et pas de faire de l'occlusion, c'est bien ça ?
Citer : Posté le 17/07/2019 22:08 | #
Oui
Ajouté le 17/07/2019 à 22:09 :
Sinon l'occlusion est faite par le zbuffer
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog
Citer : Posté le 17/07/2019 23:44 | #
Je ne vois pas l'intérêt de la liste chaîné pour ce cas là... un tableau de triangles ne suffirait pas ?
Dans ton objet, tu stockes le tableau (qui, en mémoire n'est qu'un pointeur vers le premier élément du tableau) et la taille.
Comme ça avec une boucle for tu dessines tous les triangles de l'objet. Plutôt que d'aller chercher le triangle suivant avec un autre pointeur (ça prend de la mémoire supplémentaire en plus ces pointeurs).
Quelle est la raison de ce choix ?
Citer : Posté le 18/07/2019 12:04 | #
Je veux avoir la possibilite de rajouter tres rapidement des triangles a la liste
Ajouté le 18/07/2019 à 12:14 :
Cest d'ailleurs le grand probleme des autres tableaux alloués dynamiquement, leur taille est difficilement changeable. Je sais que j'y perds un peu en memoire (-4 octes par triangle d'une taille de 24 octets), mais au niveau du temps d'accès pour un élément isolé, mais sinon l'accès a la chaine sera il me semble plus rapide. cest justement cela que je cherche
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog
Citer : Posté le 18/07/2019 14:21 | #
Je ne sais pas pourquoi tu penses qu'une liste chaînée est plus rapide à parcourir qu'un tableau - ce n'est pas vrai.
Citer : Posté le 18/07/2019 14:29 | #
Pour moi, quand on veut accéder à un tableau, on doit additionner l'adresse du tableau et l'indice pour avoir la bonne adresse.
Alors que dans la liste chainee, pour moi il n'y a pas d'addition à faire, puisque l'adresse est directement présente.
Après, peut être que je raconte des grosses conneries, mais pour moi, c'est au moins aussi rapide
Ajouté le 18/07/2019 à 14:32 :
mouais...
En fait l'adresse du pointeur n'est pas exactement celle de l'objet donc c'est pareil, vu qu'au final il doit quand meme avoir une addition (avec un nombre constant)
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog
Citer : Posté le 18/07/2019 14:33 | #
Additionner l'indice ?? il faut ajouter le produit de l'indice par le type Si tu as un tableau d'int un int = 4 octets, donc ton case est à l'addresse : addresse_de_la_première_case + 4*numéro_de_la_case
Citer : Posté le 18/07/2019 14:37 | #
Ça c'est vrai Milang, sauf qu'avec la liste chaînée chaque fois que tu veux obtenir l'adresse de l'élément suivant tu dois accéder à un attribut de la structure, ce qui requiert un accès mémoire !
Avec un tableau, si un élément est à l'adresse a, le suivant est à a+24 et ça tu peux le calculer sans aller lire dans la mémoire.
Avec la liste chaînée, si un élément est à l'adresse a, le suivant est à *(a+offset) où comme tu l'as remarqué il y a un offset du pointeur next à l'intérieur de la structure.
Dans cette histoire, ce qui compte ce n'est pas l'addition, mais bien l'accès à la mémoire. Ça coûte bien plus cher
Citer : Posté le 18/07/2019 14:40 | # | Fichier joint
ah ok !
Je n'avais pas du tout pensé au temps d'accès mémoire, je pensais juste en terme de calculs
don oui, faudra plutot que je revienne aux tableaux traditionnels comme je le faisais dans la version d'avant
Projet de jeu multijoueur : 1V1 3D
Une lib de debug simple : la liblog