Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » OutRun pour Graph 90+E
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

OutRun pour Graph 90+E

Posté le 20/02/2022 16:00

Hello,

bon je pense que certains d'entre vous sont déjà (plus ou moins) au courant de mon projet en cours de réalisation d'un OutRun pour la Graph 90+E.



Le projet vient juste de commencer est se trouve donc dans un état relativement peu avancé. Le début du jeu est fonctionnel, la route s'affiche, la vitesse est prise en compte, ... pas de décoration pour le moment ni même de sprites (voitures, panneaux, ...).



Ca devrait avancer gentiment dans les jours/semaines qui viennent.
Plein d'idées à implémenter pour en faire un truc propre. A ce stade, sans optimisation (ou presque), ça tourne à environ 40fps.

Ciao

Sly

avec bien entendu un @RDP pour quand elle sortira


Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 05/03/2022 13:18 | #


Ouuuf mais oui tu as un tableau de pointeurs. Donc non seulement tu as encore 4 octets par élement (pour le pointeur dans le vecteur) mais en plus tu as d'autres allocations donc tu augmentes la fragmentation du tas. Ne cherche pas, ton tas est juste plein. C'est pas s qui échoue l'allocation mais bien le vecteur.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 05/03/2022 13:19 | #


Tiens, un truc intéressant.
en faisant juste la modif, le vector.size() donne 7773;

A priori j'ai pu allouer et stocker 7773 Segments de 72 octets chacun ... par contre ça coincide pas avec mon 4311.
Je continue mes investigations ...
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 05/03/2022 13:22 | #


Le vecteur n'est pas réalloué à chaque push_back ; la technique classique pour amortir les copies consiste à multiplier la taille par un facteur constant à chaque allocation. C'est donc toujours plus grand.

N'oublie pas non plus que quand le tableau grandit il doit temporairement avoir deux versions : une pour les pointeurs originaux, une plus grande dans laquelle il fait la copie. Bien sûr c'est "que" 4 octets par élément pour cette allocation-là. Mais quand même, ça compte.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 05/03/2022 13:28 | #


Je viens de vérifier, juste avec mon if(s!=nullptr) ...
je suis passé à la fameuse taille 7773 et les données sont bien correctes jusqu'à cette valeur.
C'est donc bien effectivement un problème de mémoire (fragmentation ou saturation).

Lephenixnoir a écrit :

Le vecteur n'est pas réalloué à chaque push_back ; la technique classique pour amortir les copies consistent à multiplier la taille par un facteur constant à chaque allocation.

N'oublie pas non plus que quand le tableau grandit il dois temporairement avoir deux versions : une pour les pointeurs originaux, une plus grande dans laquelle il fait la copie. Bien sûr c'est "que" 4 octets par élément pour cette allocation-là. Mais quand même, ça compte.


Oui j'ai bien en tete. Une std::list serait a cet égard bien meilleure, mais hélas je pourrais pas profiter de la "vitesse" du vector et de la capacité à chopper le i ème élément facilement dans mes boucles.

Je vais maintenant regarder ce que ça donne avec un taille d'objet plus petite.
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 05/03/2022 13:38 | #


Une std::list est doublement chaînée donc tu ne ne serais pas aidé de toute façon.

À mon avis c'est bien la taille de la structure le plus gros problème. Je ne sais pas à quoi correspondent toutes les valeurs, mais je soupçonne que tu pourrais bien la diviser par 3/4.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 05/03/2022 13:48 | #


oui en descendant (facilement) à 40 bytes, j'ai mon vector de 10000 éléments qui fonctionne.
donc pb résolu.
Merci Lephe.

PS : bon en plus le µstl::vector est bien éprouvé cette fois. Ca semble robuste

Ajouté le 05/03/2022 à 22:26 :
Lephenixnoir a écrit :
Une std::list est doublement chaînée donc tu ne ne serais pas aidé de toute façon.

À mon avis c'est bien la taille de la structure le plus gros problème. Je ne sais pas à quoi correspondent toutes les valeurs, mais je soupçonne que tu pourrais bien la diviser par 3/4.


Oui pour la taille totale en mémoire c’est pas top par contre il n’y a pas le problème de la mémoire contigue nécessaire à l’allocation comme avec un std::vector.
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 05/03/2022 22:49 | #


Ma suggestion personnelle, si jamais tu veux vraiment faire des circuits longs et que tu recroises le même problème, c'est d'attaquer le "paradoxe" apparent selon lequel tu aurais besoin à la fois d'une grande échelle (circuit très long) et d'une petite échelle (fragment très détaillé), ce qui n'est en général pas vrai (pour la plupart des programmes).

De ce que je vois, il ne me semble pas que tes circuits bougent beaucoup à l'échelle d'un segment : réencoder la position complète de X/Y/Z donne donc beaucoup de répétition. Tu pourrais par exemple encoder la différence de X/Y/Z sur chaque segment, laquelle tient probablement sur 16 bits (vue la taille de l'écran je ne vois pas ce que tu ferais avec plus de 65'000 variations différentes sur chaque axe).

Si tu ne veux pas perdre l'accès aléatoire, tu peux toujours redonner la position absolue une fois tous les (par exemple) 32 segments ; ainsi le calcul de la position d'un segment quelconque nécessite au plus 32 étapes (et souvent tu les lis dans l'ordre donc c'est gratuit ; et tu peux aussi le faire en sens inverse).

Mieux encore, tu pourrais capitaliser sur ce groupement et allouer tes segments par paquets de 32, réduisant ainsi la quantité de pointeurs à stocker dans ton tableau, donc ta sensibilité à la fragmentation, en plus de ce que ça t'économise en overhead de malloc (8 octets par allocation).

Bon c'est juste des pistes qui me sont venues ; je serais simplement surpris qu'il n'y ait pas de solution convenable. Les circuits ne semblent quand même pas si denses en information. (Heck tu pourrais même te la jouer en expriment le profil de la route avec des courbes de Bézier, et ensuite calculer à la demande.)
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 06/03/2022 09:19 | #


Merci Lephe pour toutes ces idées.

Pour certaines d'entres elles, effectivement je pense que je vais les adopter à terme (notamment la notion de "blocs" de segments), mais en l'état ce n'est pas "compatible" facilement avec l'architecture de ce que je développe. Ça ne se voit pas actuellement car il n'y a pas certaines "features", comme les virages, les côtes et descentes, mais surtout les éléments de décoration sur le bord de la route et les voitures du trafic.

Par contre, j'ai joué sur les tailles des éléments de la classe Segment car tu as tout à fait raison, un int64_t pour tout, c'est la bombe atomique pour tuer une mouche.

Ça devient donc :


class Segment
{
    public:
...
...
...

        uint8_t Curve=0;

        // World Coordinates (X,Y,Z)
        int16_t wX=0;
        int16_t wY=0;
        double wZ=0.0;

        // Screen Coordinates (X, Y) + width of the projected Road
        int16_t X=0;
        int16_t Y=0;
        int16_t W=0;

        // Decorations on the Road (Left and Right)
        int8_t Ldeco=0;
        int8_t RDeco=0;
};


Avec ces modifications, je passe d'une taille de structure de 72 bytes à 24 bytes (soit divisée par 3 ).
Ayant fait des essais fructueux avec une taille de structure à 40 bytes, je pense que cette fois ça va fonctionner sans problème.

Bien entendu, le retour de bâton est sur le temps de calcul, qui est de fait augmenté, mais globalement c'est tout à fait acceptable.
Moyennant quelques autres petites optimisation ici et là, je ne pense pas trop perdre sur le framerate.
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 06/03/2022 16:18 | #


Excellent ! Bon travail de réduction de taille, c'est certainement plus convaincant comme ça.

Bien entendu, le retour de bâton est sur le temps de calcul, qui est de fait augmenté, mais globalement c'est tout à fait acceptable.

En quoi ? Les conversions d'entiers sont négligeables. Par contre en divisant la taille par 3 tu augmentes beaucoup la localité des données, donc l'effet du cache. S'il fallait deviner comme ça je parierais que ce serait plus rapide. Mais je suppose que tu as fait les mesures ; peut-être qu'il y a des calculs intensifs que je ne vois pas ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 06/03/2022 22:33 | # | Fichier joint


Ça a bien avancé ce soir,

J'ai pu aujourd'hui implémenter 2/3 trucs sympas :
- la gestion des tracés en virage et en côte/descente
- la gestion des décorations en bordure de route

Ici en gros pour le moment les décorations, ce sont les arbres, mais à terme il y aura d'autres choses, comme par exemple des panneaux, des gens, ...

Un exemple de virage:


Les différents arbres présents :


Je vous mets en PJ une version compilée avec un circuit d'exemple.

Les touches :
[SHIFT] pour accélérer
[ALPHA] pour freiner/reculer
[EXIT] pour quitter
[<- / ->] aller à gauche / droite


[F1] et [F2] affiche les infos de debug

pour ceux qui ont un fxlink opérationnel :
[F4] fait un screenshot
[F6] active la sortie flux vidéo (attention dans ce cas le framerate meurt !!!)


Çà tourne à grosso modo 30-40ips, avec tous les trucs affichés, donc je suis assez content des optimisations.

La prochaine grosse MàJ sera liée à l'introduction du trafic je pense.

Bon, si c'est pas trop tard @RDP.

A plus

Sly
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 06/03/2022 23:36 | #


Joli ! Le framerate est clean. Le plus étonnant c'est l'effet stroboscopique sur la route et les arbres. Le dimensionnement n'est pas non plus idéal... et je ne sais pas exactement ce qui pourrait être fait. Vu que les images sont plus hautes que larges t'as essayé de faire une version par hauteur possible ? Même si ça risque de faire beaucoup de mémoire.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 07/03/2022 11:33 | #


Merci Lephe.

Oui cet effet stroboscopique est un poil énervant, je suis d'accord. Il faut que j'affine les paramètres des segments en fonction de ... je sais pas quoi d'ailleurs ... idéalement le framerate, mais c'est un peu compliqué. Donc il faut réfléchir un peu plus et être malin.

Pour la taille des sprites, effectivement il y a un problème, mais j'ai une piste. Actuellement la décroissance de taille est linéaire (chaque sprite est 15% plus petit que le précédent car je fais un scaling par un facteur 0.85 entre deux sprites), mais c'est idiot, j'ai pas réfléchi en faisant ça, car la perspective, c'est du 1/X, vu qu'on divise par un facteur (world.Z - camera.Z). Je vais essayer de corriger comme ça pour voir si ça rend mieux et surtout si le rendu est plus "crédible".

Par contre, j'avoue ne pas avoir saisi l'histoire de la version par hauteur. Tu peux expliciter un peu ?

@+
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 07/03/2022 11:38 | #


Actuellement la décroissance de taille est linéaire (chaque sprite est 15% plus petit que le précédent car je fais un scaling par un facteur 0.85 entre deux sprites), mais c'est idiot, j'ai pas réfléchi en faisant ça, car la perspective, c'est du 1/X, vu qu'on divise par un facteur (world.Z - camera.Z).

Effectivement.

Par contre, j'avoue ne pas avoir saisi l'histoire de la version par hauteur. Tu peux expliciter un peu ?

Une version de 40px de haut, une de 39px de haut, une de 38px de haut, etc. Bourrin mais on sait jamais ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 07/03/2022 11:44 | #


Ah Ok, bein en fait c'est ce qui est implémenté actuellement (pas tous les pixels comme proposé, certes), mais oui la conso mémoire peut vite exploser.

Logiquement, avec un bon FPS, ont devrait pouvoir éviter d'avoir besoin de 50000 versions des sprites, mais là encore c'est à ajuster.


D'ailleurs, pourrais tu me repréciser la ligne de code pour avoir la conso mémoire "uram" ? Je l'ai noté je sais plus où et je retrouve plus ma note. J'ai recherché dans la shoutbox, mais l'historique est pas assez long.

Y'a t il un tuto sur la partie gestion mémoire de gint qui expose les arènes, les kmalloc .... ?
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 07/03/2022 11:51 | #


Avant que j'oublie, pour l'effet stroboscopique une des options c'est juste de coller un peu d'aléatoire. Si tu décales les arbres de façon aléatoire sur chaque segment (ne serait-ce qu'avec un rand() initialisé par le numéro du segment) l'effet est pas mal réduit. Mais il me semble que la voiture va vraiment vite, donc si un arbre n'est pas visible au moins quelques bons frames consécutifs à l'écran pour permettre au joueur de le suivre des yeux je ne sais pas si ça aidera.

D'ailleurs, pourrais tu me repréciser la ligne de code pour avoir la conso mémoire "uram" ? Je l'ai noté je sais plus où et je retrouve plus ma note. J'ai recherché dans la shoutbox, mais l'historique est pas assez long.

kmalloc_get_gint_stats(kmalloc_get_arena("_uram"))->used_memory

Il n'y a pas de tutoriel encore malheureusement, mais tu peux regarder les définitions de <gint/kmalloc.h>, qui sont très courtes/minimales.

La seule chose un poil subtile c'est que dans chaque arène tu as des statistiques de base qui peut être calculées même sans contrôler le malloc/free (ce qui est fait notamment sur le tas OS), et dans les arènes gérées par l'allocateur personnalisé de gint tu as des stats beaucoup plus précises, qui sont activées dans le cas de l'arène _uram.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 07/03/2022 15:20 | # | Fichier joint


Voici une toute petite MàJ, faite entre la poire et le fromage

Quelques modifications sympa (rapidement mises en place pour tester leur influence sur le gameplay et les performances) :
- correction de la perspective dans le calcul de la taille des arbres (non plus linéaire mais en ~1/x, tel que cela aurait du être si je réfléchissais un peu )
- ajout d'une forme d'aléa dans le positionnement des décorations en bordure de route (c'est une version vraiment de base, mais effectivement Lephé, ça le fait vraiment bien, donc en jouant sur la vitesse maxi de la voiture, ça devrait passer)
- ajout des nuages (je voudrais aussi mettre des forêts / montages / city skylines. Actuellement c'est juste un défilé avec un modulo, mais je vais mettre en place un système de parallaxe idéalement sur 2 niveaux (1 pour le ciel et les nuages et un pour un plan intermédiaire (forêt / montage ...)






en PJ la version en cours.

Sly
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 07/03/2022 19:51 | # | Fichier joint


Je suis content aujourd'hui ça avance vraiment bien

Des couleurs un peu plus cool (en fait ça sort pas du tout pareil sur la calculatrice, car là sur l'écran ça pique les yeux )



Et différents biomes (pour le moment PLAINS et DESERT, d'autres pourront être très facilement implémentés)




La voiture a vu sa vitesse maxi limitée. Dites mois si vous préférez comme ça ou comme avant. Là ça limite l'effet stroboscopique est c'est plus "réaliste".

Enfin, le défilement des nuages est corrigé.

PJ annule et remplace.

Sly
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 07/03/2022 19:54 | #


C'est pas mal du tout. Je pense qua la vitesse maximale actuelle est bien suffisante. Tu as changé la taille des arbres ? Parce que là j'ai toujours un très gros saut entre la taille normale et la première taille inférieure, et on a toujours l'impression que ça "sursaute" à vitesse faible.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 07/03/2022 22:52 | #


Oui il y a un saut entre la première est seconde position, c'est lié à la différence importante de taille (proportionnelle à 1/X) quand X est petit (typiquement entre 1 et 2). Dans ce cas le rapport de taille vaut 2. J'essaie de trouver une "tatane" pour avoir qqchose de moins brutal quand on est "proche de l'ecran" et que la distance Z tend vers 0. Mais pour le moment j'ai rien trouvé de vraiment satisfaisant.

Quand Z devient plus grand, par contre maintenant c'est vraiment pas mal. on a une belle continuité dans les tailles d'un cran à l'autre.
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Slyvtt Hors ligne Maître du Puzzle Points: 2387 Défis: 17 Message

Citer : Posté le 11/03/2022 15:22 | # | Fichier joint


Hello,

voici en pièce attachée la version du moment.

Les nouveautés :
- ajout du trafic (pour le moment sans IA et sans interaction avec le joueur, c'est pour voir ce que ça donne en terme de performances)
- amélioration des performances globalement (on reste vers 30fps malgré tous les ajouts)
- ajout d'un système de background (sur 2 plans avec la parallaxe : un plan montagne + un plan foret)
- la voiture du joueur "tourne" désormais dans les virage
- les pneus du joueur donne une illusion de vitesse
- plus de type de décorations (cactus, feuillages ...)
- plus de voitures dans le trafic : 8 types différents


La video est capturée "on calc" donc ça parait vraiment très lent - fort heureusement c'est pas le cas IRL









Il y a encore pas mal de choses à mettre en place et toujours optimiser ... optimiser ...

Ciao

Sly


et @RDP
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 11/03/2022 17:12 | #


Wow dès que rajoutes du décor ça devient vite impressionnant !

Je sais que suis chiant, mais je comprends quand même pas l'histoire des virages. Entre 0:50 et 1:05 il est évident que la voiture prend le virage tout seule... >_o
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 123 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

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