Après mes épreuves de fin d'année j'ai eu beaucoup de temps libre, j'ai donc fait un moteur graphique et physique en 3D en langage C à l'aide des librairies Monochrome Lib pour les fonctions graphiques et usefull pour l'affichage de la fréquence d'image.
Pour le moteur graphique, le programme projette d'abord chaque point de l'espace sur l'écran de la caméra, puis il trie et dessine chaque triangle déterminés comme visible parmi une liste de triangles. La couleur de ces triangles est déterminée grâce au produit de la couleur de base du triangle par un coefficient calculé à l'aide du produit scalaire entre le vecteur normal du triangle et le vecteur directeur des rayons lumineux.
Un premier filtre met d'abord de coté chaque triangle qui ont leurs points affichés dans l'ordre horaire afin de garder que les triangles qui ont leurs points affichés dans le sens antihoraire pour ainsi faire ce qui est appelé "back face culling". Ce simple filtre permet dans la plupart des cas de réduire de moitié le nombre de triangles affichés. Néanmoins, chaque triangle de l'objet 3D affiché ici sont dirigés dans le bon sens donc aucun triangle n'est mis de coté avec ce filtre. Ce filtre peut se révéler très utiles pour les formes convexes (caractéristique présente pour la plupart des solides étudiés en primaire) car il permet à lui seul d'afficher correctement le solide en question.
Le second filtre permet de mettre de coté les triangles qui sont entièrement derrière la caméra afin d'éviter d'afficher des triangles qui ne sont pas censé être affichés. Si on n'applique pas ce filtre, les triangles derrière la caméra seront affiché comme s'ils étaient devant mais à l'envers.
Les triangles restants sont ensuite triés en fonction de leur distance par rapport à au plan passant par l'écran de la caméra. Ce tri n'est pas très utile dans ce cas mais il permet d'avoir un rendu à peu près correct lorsqu'il faut afficher plusieurs solides. Afin d'avoir un rendu parfait, il faudrait comparer les distances pour chaque pixel de l'écran, ce qui est bien trop couteux au niveau des performances pour 8192 pixels. C'est typiquement ce genre d'opérations pour lequel une carte graphique se révèle utile car elle peut réaliser des milliers voire des millions de taches en parallèle.
Il reste néanmoins deux cas de triangles qui peut poser soucis.
Le premier cas qui pose problème est si le triangle est à moitié devant la caméra.
En effet un ou deux points de ce dernier seront positionnés correctement tandis que le ou les autres points seront affichés à l'envers, créant ainsi une forme incohérente. En réalité, seulement une partie de la surface de ce triangle est devant le plan qui représente l'écran de la caméra. Il faut donc découper cette partie en un ou deux triangles (un si deux points sont derrières et deux si un unique point est derrière). Les sommets des triangles qui forment le découpage sont ensuite projeté sur l'écran de la caméra.
Les second cas qui pose problème est si les sommets du triangles projetés sur l'écran de la caméra sortent de l'écran de la calculatrice. Ceci ne pose pas vraiment problème d'un point de vue visuel mais peut grandement affecter les performances. Un algorithme de découpage est utilisé pour découper le triangle en plusieurs triangles qui sont eux bien dans l'écran de la calculatrice.
Étant donné que la seule forme géométrique dessinée est le triangle, il est donc plus logique d'utiliser un algorithme de rastérisation spécifique à ces derniers qui est environ quatre fois plus rapide que les fonctions classiques pour dessiner n'importe quel polygone. J'ai donc fait une fonction spécifique à l'affichage des triangles ainsi qu'une fonction modifiée de celle pour tracer des lignes horizontales de Monochrome lib afin d'afficher 5 demi-teintes (à l'aide de tramage) au lieu de 3. J'ai également fait une fonction pour afficher 256 demi-teintes sur une ligne horizontale, elle est malheureusement 6 fois plus lente que l'autre fonction car elle calcule la couleur pixel par pixel au lieu de modifier les octets de la mémoire visuelle comme pour l'autre.
Au niveau du moteur physique, une fonction permet de d'appliquer un déplacement à un point à l'aide d'un vecteur de mouvement. Cette fonction vérifie aussi si le segment formé par le point d'arrivée et le point de départ coupe un triangle. Si c'est le cas, le point d'intersection remplace le point d'arrivée et le mouvement est corrigé afin de suivre la géométrie du triangle (sorte de glissade). La fonction est d'ailleurs à nouveau appelée afin de vérifier si ce nouveau mouvement coupe un autre triangle. La fonction renvoie enfin une valeur si aucun triangle n'est coupé ou si la correction annule complètement le vecteur de mouvement. Cette correction est aussi accumulée pour chaque intersection afin d'appliquer cette dernière au vecteur vélocité du point.
Pour l'instant, il n'y a que deux forces appliquées sur le système: le poids et la réaction normale de la surface des triangles. Il faudrait donc encore gérer la friction ainsi que d'éventuels déplacements pour un futur jeu.
Ce programme est plus une démo qu'autre chose, mais la caméra peut être tournée à l'aide des flèches directionnelles et le système peut être remis dans son état initial à l'aide de la touche 0 du pavé numérique. Enfin, la touche EXIT peut être pressée pour quitter l'application.
C'est le premier programme en C que je publie sur planet-casio et il est uniquement compatible pour les calculatrices au processeur SH3. Si vous avez des retours à faire vis à vis de la forme je suis toute ouïe et si vous avez des idées de jeu utilisant l'aspect graphique et physique du programme mais que vous ne pouvez ou ne souhaitez pas réaliser, je suis aussi à l'écoute.
Je publierai plus tard les fichiers sources du programme, en attendant, si vous avez des questions vis à vis des algorithmes mis en application, je suis à votre disposition.
Je prévois à un certain point dans le projet d'en faire un portage pour la PRIZM ainsi que la GRAPH 90+E quand j'aurai réussi à installer les fichiers nécessaires.
⚠️⚠️⚠️⚠️⚠️⚠️
Je souhaiterais également intégrer un support pour du multijoueur à l'aide du câble à trois broches. Si vous avez de la documentation à propos de cet aspect de la calculatrice, je souhaiterais bien que vous m'en fassiez part.
Joli tout ça, joli... ! C'est normal que ça bouge tout seul right ? On est essentiellement une boule dans un bol qui fait des allers-retours ?
SH3 seulement c'est un peu rude... ! Même si tu codes avec le vieux SDK tu dois pouvoir te débrouiller pour être compatible SH4. Y'a que les vieux des vieux ici qui ont encore des SH3 :x
Je vois que t'as implémenté plein d'algos classiques, c'est cool. Le z-buffering ça passe en fait, c'est ce que faisait Windmill d'ailleurs. Je suis très intrigué par un port couleur, parce que je vais pas mentir l'espace graphique noir et blanc et 128x64 ça me fait plus trop rêver maintenant... props cela dit pour le tramage, ça rend bien.
Bonsoir, merci beaucoup des compliments et des retours.
Je ne pensais pas du tout que le z Buffer fonctionnait sur la calculatrice, j'essaierai de l'implémenter demain dans les fonctions de rasterisation et ça pourrait être utile pour afficher des éléments mobiles.
J'essaierai aussi de compiler également une version SH4 pour les prochaines démos.
J'avoue que je n'ai pas été vraiment clair dans la description. Ici, la "boule" apparaît à une position donné avec une vélocité donné lorsque l'on appuie sur 0. Ensuite, le programme s'occupe lui même de gérer les différentes collisions et déplacement au cours du temps en fonction des triangles dans la mémoire. Avec une vélocité et une position initiale différente, le mouvement de la boule sera lui aussi différent.
Si je change de modèle 3D, le programme adapte lui même le mouvement de la boule. Par exemple si je mets un toboggan la boule va bien suivre la trajectoire du toboggan et être projeté vers le haut à la fin avant de redescendre. Les seules opérations appliquées sont une soustraction sur la composante verticale pour la vélocité (afin de représenter le poids) et la réaction normale des triangles qui changent la position et la vélocité de l'objet en fonction des intersections entre les triangles et le segment formé par la position initiale et le vecteur de mouvement.
Pour un portage sur graphique couleur je ne pense pas que ça arrivera tout de suite, j'aimerai bien faire d'abord un jeu en noir et blanc et le porter ensuite sur graph couleur. De plus, le programme qui retranscrit les mesh en données lisibles pour le programme prend en compte les composantes RGB de chaque triangle ce qui est pratique pour une future adaptation. Pour l'instant je préfère me concentrer sur une version monochrome avec si possible un support multijoueur pour un éventuel jeu à l'aide du câble à 3 broches car je trouve que c'est ce qui manque le plus aux jeu sur calculatrice.
Sinon par rapport à hier j'ai modifié la fonction pour inclure des rebonds et de la friction. Ce qui est sympa c'est que je peux faire dépendre les deux paramètres des polygones ce qui est pratique si je souhaite faire du sable (faible restitution de l'énergie et haute friction) et de la glace (restitution de l'énergie moyenne et faible friction) en même temps. J'ai déjà fait une sorte de minigolf mais l'idée de faire un jeu de golf, bien qu'applicable, ne m'emballe peu.
Je pensais plus faire un jeu de tir, un jeu de plateforme ou un jeu de course.
Je n'ai pas pu tester faute de sh3, mais le projet à l'air assez impressionnant. Je pense que tu pourrais t'aider de MCC pour comparer les performances de la calto en matière de 3D. Je pense que j'aurai bientôt une calto SH3, donc testerai dès que possible.
Gky93 a écrit : Je pensais plus faire un jeu de tir, un jeu de plateforme ou un jeu de course.
Personnellement, je serais plus partant pour un RPG avec de l'action type Zelda ou pokémon (Il me semble qu'il y en a pas en 3D pour calto)
Genesect a écrit : Personnellement, je serais plus partant pour un RPG avec de l'action type Zelda ou pokémon
J'y ai pensé mais je trouve dommage d'utiliser un moteur physique en 3D pour faire un RPG: ça met moins en exergue les fonctionnalités du moteur alors qu'un jeu de plateforme nécessite un moteur physique plus poussé. J'ai une idée de jeu mélangeant plateforme et tir mais il faut d'abord que je retravaille le moteur de jeu.
J'ai changé d'approche vis à vis de la scène 3D, au lieu de faire une liste de triangles pour le terrain, je le découpe en plusieurs formes convexes ce qui permet de projeter uniquement les objets en face de la caméra et de ne pas trier les triangles (le back face culling à lui seul permet d'afficher correctement le solide) mais seulement les objets réduisant ainsi le nombre d'éléments à trier.
J'ai aussi changer l'approche pour les collisions et j'ai réussi à utiliser une sphère comme boîte de collision pour les éléments soumis à la physique. Si ça intéresse des gens je pourrais mettre au propre les démonstrations pour les formules.
Pour finir j'ai revu les fonctions pour tracer des lignes horizontales et pour obtenir le motif pour le dithering et elles vont 4 fois plus vite qu'avant.
Je te conseille d'utiliser gint/le fxsdk pour avoir de meilleurs performances et une compatibilité avec la plupart des calculatrices supportant les add-ins.
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd