Lol j'y suis arrivé seul et il n'y a jamais eu personne pour m'aider. et si il devait y avoir 50 programmeurs pour que je continue il y aurait déjà eu longtemps que j'aurai arrêté.
- Edité par OmbreNoire 23 décembre 2024 à 13:34:29
J'ai corrigé une erreur de compilation dans le fichier fastDelegate.h, en effet, passer un objet qui n'était pas un pointeur avec une fonction membre au delegate provoquait une erreur de compilation et ça ma gênait de devoir utiliser un pointeur car il faut aussi le libérer.
Pour rappel le delegate de ODFAEG permet de définir des pointeurs de fonctions de n'importe quel type, avec des arguments de n'importe quel type, même des placeholders!!! De plus le seul type pour le delegate est le type de retour de la fonction donc on peut stocker dans un std::vector tout les delegate de même type. Très utilise pour gérer des évènements personnalisés. Le listener peut contenir plusieurs commandes qui peuvent contenir une action (un ou plusieurs évènements claviers, souris, etc...) un signal (un delegate) et un slot (un autre delegate) qui sont connectée au listener à l'aide d'un std::string, le nom de la connexion sert à changer les paramètres des delegates pour une commande c'est à dire du signal et du slot. (par exemple la position de la souris) Chaque GUI possède son propre listener qui peut être activé ou désactivé si on souhaite gérer les évènements pour la gui ou non. Si plusieurs GUI sont superposées il faut gérer soi même l'activation et la désactivation du contexte de gestion des évènements si l'on ne veut pas traiter les évènements pour les deux guis en même temps.
Ceci sera expliqué plus clairement à l'aide d'exemple de code dans le doc. Je dois la refaire car beaucoup de choses on changé depuis la dernière fois que j'ai mit à jour la doc, une fois tout mes projets de fini je ferai aussi un cours sur comment créer un moteur de jeux et un jeux car certaines personnes m'ont demandé comment j'ai fais. Et pas de cours sur Internet pour créer un mmorpg de A à Z.
- Edité par OmbreNoire 28 décembre 2024 à 23:08:41
Je continue à corriger les bugs et j'en ai encore corrigé un dans ODFAEG Creator la sélection du rectangle de texture en mode aligné avec la grille ne se faisait pas au bonne endroit par rapport à la position de la souris, ce soucis est maintenant réglé.
Je vais continuer à créer le premier niveau pour le jeux tout en corrigeant les derniers bugs éventuels.
J'ai dû laissé tombé la 3D parce que en gérant tout (transparence, ombres, lumières et réfraction) le FPS est assez bas car il y a plus de polygones à afficher en 3D.
> C'est écrit partout sur l'internet qu'on ne débute pas la programmation de jeux vidéo par le c++ mais par le javascript. Source ? Parce que ça n'a aucun sens, le but n'est pas le même... (de plus, je serais tenté de dire qu'OmbreNoire n'a pas trop de soucis avec le langage lui-même, sauf quand il part dans des trucs ésotériques)
> DragonJoker > On ne peut pas utiliser ton castor3d tout de suite donc il faut que tu attendes, et si tu veux accélérer le boulot, il va falloir communiquer dans la salle de travail discord. Je vois pas pourquoi tu parles encore de Castor3D ici. Je n'ai pas besoin de tes conseils, j'ai jamais demandé qu'on utilise mon moteur, je n'ai jamais fait que le présenter, je le fais dans mon coin, à ma vitesse. Si tu veux qu'il progresse plus vite, n'hésite pas à venir aider, moi je m'en cogne. (Et si tu ne peux pas l'utiliser, c'est probablement juste un problème de PIBKAC)
Si vous ne trouvez plus rien, cherchez autre chose.
Salut! Je suis entrain de remettre à jour la documentation.
Je vais continuer les tutoriels vidéos sur ODFAEG Creator.
Mais avant, je vais essayer de connecter le serveur de jeux à mysql à l'aide de Qt, parce que ça m'embête vraiment et maintenant que j'ai la dernière version de mingw qui compile ODFAEG je devrais pouvoir link Qt sans problème. (avant ça ne fonctionnait pas parce que déjà j'avais un compilateur 32 bits et une ancienne version)
J'avais essayé avec le connecteur mysql mais avec mingw ça plante.
Pour un serveur, C++ n'est probablement pas la techno la plus optimale, d'autres langages sont plus specialises server side et offriront un tas de fonctionalites out of the box ou presque: connection DB, ORM generateur sql, pool de connection DB, lecture de stream formattes (json, yaml, xml...) protocole de communication sur differentes couches(socket, http, rest, graphql,...), securite (hashage, encryption, integration FIDO, integration vault, oauth), gestion du cache local ou distribue, gestion des emails, gestion des templates, horizontal scaling, HA, remarrage a chaud/rechargement dynamique, monitoring, logging distribue...
Si tu veux gerer tout ca a la main,
1) tu vas galerer, et bien plus que pour une simple connection DB
2) certaines fonctionalites ne pourront pas etres reproduites
3) Ce sera bugge.
Autant un bug cote client, c'est embettant mais pas la fin du monde, autant cote serveur, la ou se trouvent les informations des joueurs, la 'Verite' sur l'etat du monde de jeu, les differents secrets a stoquer, sans parler de la disponibilite, un serveur pas hautement disponible, ce sont tous les clients qui sont impactes, c'est nettement plus problematique.
Salut! Le serveur c++, c'est juste le serveur du jeux parce que le client est en c++ aussi. Pour tout ce qui du développement web (http, gestion des mails, etc..., je vais utiliser un autre langage.) Sinon j'ai fait la gestion des sockets et tout ce qui est sécurité moi même grâce à la SFML et OpenSSL et je n'ai pas trouvé cela très compliqué à faire. (Il y a juste que à certaines exécutions du serveur, je dois le redémarrer parce que openssl me lance un bad decrypt error avec le réseau de la SFML au lancement du client, pourtant les caractères sont les mêmes à la réception et à l'envoi donc je ne comprend pas ce plantage...)
Mais bon à part ça ça tourne nickel.
Je suis entrain de mettre en ligne une vidéo sur l'installation du moteur de jeux car pas mal de choses on changé depuis.
Mais quand tu dis que ca tourne niquel, tu as teste avec combien de joueurs connecte simultanements? et avec le serveur qui tourne combien de temps parce que trouver ca facile, ca sent tres fort le "j'ai seulement teste en localhost pendant 10 minutes" sans variation de ping, deco brutales, et autres joyeusetes du fallacies of distributed computing ou encore quelques fuites memoires bien cachees qui font tomber le systeme apres x temps.
Un joueur (moi) et je l'ai fait tourner pendant une dizaine de minutes mais faudrait que je test avec plusieurs joueurs pendant un temps plus long mais je sais que je dois tester avec plusieurs joueurs pendant plus longtemps mais ça je le ferai au lancement de la bêta.
Salut! J'ai remarqué un problème avec les balises html <code><pre> dans le repo. git. : ça n'affiche pas tout le code qui se trouve entre ces deux balises sur cet page entre autre : https://laurentduroisin7601.github.io/ODFAEG/commandes. Du coup problème avec les exemples de code source qui sont dans la doc..., je ne sais pas quoi faire pour régler le soucis.
Salut! J'ai trouvé la solution pour les bugs d'affichage des codes sources dans la doc faut remplacer en html < par < ça > par > et ça & par &
Salut! j'ai essayé le multi-threading mais avec opengl c'est peine perdue, des éléments ne s'affichent pas.
Par contre les mutex côté CPU (et je ne comprends pas en quoi ça change le rendu et la vitesse) règlent certains problème d'affichage et optimise le code le FPS a doublé, mais il est encore trop bas.
Bref je commence à être démotivé, je dois dessiner la scène pas mal de fois (pour la transparence, les ombres, la lumière et la réfraction) donc même si il n'y a pas énormément de polys. le FPS est assez bas surtout en 3D. (J'en suis entre 20 et 35 FPS à peu près pour la 3D)
Je ne sais pas si je vais continuer le projet parce que sans aide d'un expert, je crois que mon moteur de jeux ne sera pas très performant, bref...
J'essaie de limiter les transferts CPU=>GPU mais j'ai encore des problèmes d'affichage contrairement à lorsque je fais les transferts à chaque frame.
Regroupe tes transferts au début de la frame, fais du double buffering (prépare les buffers pour la frame N+1, utilise les buffers de la frame N),.
Comment ça, "tu dois dessiner la scène plusieurs fois" ? Pour la réfraction tu peux utiliser le rendu de la frame précédente, pour le reste tu rends les objets opaques d'abord, puis ceux avec de la transparence. As-tu pensé à avoir une depth pre-pass ?
Tu rends quoi dans tes shadow maps ? A quelle résolution ? Combien de cascades ?
Si vous ne trouvez plus rien, cherchez autre chose.
Salut j'ai différent depthBuffer : un pour stocker la profondeur des ombres avec un alphabuffer pour l'alpha masque pour pas afficher les ombres sur les objets qui sont devant les ombres. Un autre depthBuffer pour stocker la profondeur des objets réfractable avec un alpha masque pour ne pas afficher la réfraction sur les objets devant l'objet réfracté.
Et même chose pour les lumières ou je stocke la pronfondeur des lumières et je fais aussi un alpha masque pour ne pas afficher la lumière sur les objets devant la lumière.
Rien que ça ça me fait 2*3 = 6 draws de la scène.
Sinon pour la transparence j'utilise les per-pixel-linked-list c'est ce qui marche le mieux. J'utilise une per-pixel-linked-list pour dessiner les objets de la scène tout en gérant la transparence ça fait un draw call de plus on en est à 7.
Pour la réfraction je dessine la scène une fois au niveau du CPU mais au niveau du GPU je la dessine 6 fois avec un geometry shader et j'utilise une per-pixel-linked-list par face de la cubemap pour gérer la transparence des objets réfractés. Ca fait 8 draw calls.
Pour les ombres je n'ai qu'une seule cascade pour le moment et le shadowmapping ça fait 2 passes donc 10 draw calls.
Et pour la lumière je dessine les textures de normales sur une grande textures pour le bump mapping et les composantes spéculaires sur une autre texture et enfin je dessine la lumière ça fait 13 draw calls.
Donc je suis à plus de 10 drawCalls sans compter la mise à jour des VBO (transferts CPU=>GPU) avant chaque draw calls. Et encore si je ne draw pas le même type de primitive ou le même type de draw (instancing ou non instancing) ça me fait des drawcalls en plus. Si des meshs sont sélectionnés ça me fait aussi des drawcalls en plus.
Mais je veux que mon moteur gère vraiment tout au niveau du rendu. L'inconvénient c'est que le FPS est bas. (20 frames par secondes en 3D en affichant environ 5k polys)
Je sais pas si il y a moyen d'optimiser ça, j'ai essayé de mettre les meshs statiques dans un VBO que je ne remet pas à jour à chaque frame mais j'ai eu des problèmes d'affichage et de toute façon même en faisant ça il faut remettre à jour les indices pour n'afficher que les objets statiques visibles.
Et encore je n'ai pas encore implémenté le cascade shadow mapping, le PBR et toutes ces choses je crois bien que le FPS serait encore plus bas en implémentant ça pour ça que je le fais pas.
Mais je m'attendais à avoir un FPS plus élevé quand même surtout avec un PC aussi puissant bon c'est pas le plus puissant mais ça va. (13 draws calls et 13 mises à jours de VBO 13 * 5k polys c'est pas si énorme que ça si ?)
Et je fais du batching donc si on rajoute des polys le nombre de drawcalls ne change pas si on rajoute des textures non plus grâce au bindless texturing et si on a plusieurs groupes d'instances le nombre de drawcalls ne change pas non plus grâce à l'indirect rendering.
On m'a déjà dit que opengl pouvait dessiner des millions de poly assez rapidement et là ça ne fait même pas 1 million de polys.
Et on dirait que le CPU attend après le GPU même en faisant du double buffering, parce que le FPS baisse beaucoup en faisant juste des drawcalls et des transferts GPU en plus.
Et je n'ai pas très envie de changé d'api. (Opengl=>VULKAN) normalement opengl pour les jeux vidéos c'est bien.
Pourquoi tu mets à jour tes VBO à chaque draw call ? Il y a quoi dans ces VBO ?
Parce que les mesh sont dynamiques et je n'affiche que les meshs visible et ça peut changer à chaque frame. Les infos ça dépend de ce que je vais dessiner mais il y a la position, la couleur et les coordonnées de textures pour les vertices. Ensuite je crée d'autre VBO pour avoir des informations supplémentaire comme le n° de la couche, l'index de la texture (bindless texturing), et pour les lumières les composantes spéculaires pour la réfraction le type de matériel, etc...
La visibilité d'un mesh ne devrait pas avoir d'influence sur son VBO (il sera créé et en VRAM mais ne sera pas utilisé, pas forcément un drame à ton niveau). Par contre, les VBO sont faits pour stocker les données qui peuvent changer par vertex. J'ai l'impression que le numéro de la couche, l'index de la texture, les informations de matériau, ... ne varient pas par vertex, et n'ont aucune raison de se trouver dans un VBO, mais plutôt dans un SSBO regroupant les informations de meshes dans un tableau, avec une entrée par mesh, ça prendra beeaaauuucouuup moins de place en VRAM (j'espère d'ailleurs que tes VBO ne sont pas en interleaved, sinon tu dois trasher le cache bien comme il faut, avec toutes tes données dans tes VBO)
Si vous ne trouvez plus rien, cherchez autre chose.
Oui mais le vertex shader varie par vertex donc les attributs aussi doivent varier par vertex pour récupérer l'index de texture dans le vertex shader et puis le passer au fragment shader.
Ben non, si l'index de texture ne varie pas par sommet de ton mesh (cas habituel), ce n'est donc pas une donnée de sommet mais une donnée de mesh, et du coup elle n'a rien à faire dans le vertex buffer.
Si vous ne trouvez plus rien, cherchez autre chose.
Mais du coup je ne sais pas comment accéder à l'index de texture et à mes autres variables dans le SSBO dans le fragment shader. Avec les VBO il n'y a rien à faire on définit vertex attrib pointer et l'incrémentation de l'index pour la donnée pour le prochain vertex se fait tout seul, ce n'est pas le cas avec un SSBO.
De plus tout les meshs n'ont pas le même nombre de vertex.
Le seul moyen se serait de faire de l'instancing, je faisais ça en mettant toutes mes matrices de transformations dans un SSBO et en utilisant gl_InstanceID mais je veux laissé la liberté à l'utilisateur de définir si il veut faire de l'instancing ou non pour un mesh.
Avec les VBO il n'y a rien à faire on définit vertex attrib pointer et l'incrémentation de l'index pour la donnée pour le prochain vertex se fait tout seul, ce n'est pas le cas avec un SSBO.
C'est vrai, et on se retrouve avec des données dupliquées à tire larigot, une occupation en VRAM inutile, tu trash le cache... ça n'apporte que des bonnes choses...
De mon côté j'ai un SSBO qui contient un tableau de ModelData, structure qui contient les informations d'un mesh (matrice de transformation, ID de matériau, ...) et lors du draw call pour ce mesh, je passe une push constant contenant l'index du mesh dans ce tableau. Mes matériaux sont dans un autre SSBO, pour limiter la duplication de données.
Vu que tu es en OpenGL, une simple variable uniform ferait l'affaire
OmbreNoire a écrit:
je veux laissé la liberté à l'utilisateur de définir si il veut faire de l'instancing ou non pour un mesh
Pourquoi ? C'est quoi l'intérêt ?
- Edité par dragonjoker 7 février 2025 à 9:56:22
Si vous ne trouvez plus rien, cherchez autre chose.
Tu utilises un uniform pour l'index du matérieau pour chaque mesh ? Tu remets à jour l'index avant chaque appel à draw pour chaque mesh ? Ca doit être lent!
Moi je ne fais que un draw call pour tout mes meshs. xd
Tu utilises un uniform pour l'index du matérieau pour chaque mesh ? Tu remets à jour l'index avant chaque appel à draw pour chaque mesh ? Ca doit être lent!
Moi je ne fais que un draw call pour tout mes meshs. xd
- Edité par OmbreNoire il y a environ 11 heures
de ce qu'il t'explique, et de ce que tu dis avant, la lenteur, c'est de ton coter visiblement .. Teste peut être les propositions de dragonjoker qui essais de t'aider à ne pas abandonner ?
- Edité par Koyuki Tanaka 8 février 2025 à 10:12:18
Salut! J'ai déjà essayé de faire comme il l'explique ça n'a pas accéléré le FPS. Peut être lui plus rapide parce que il ne gère pas tout (pas de per pixel linked list pas de depthBuffer avec des images pas de masque pour l'alpha) et il utilise vulkan et sans doute du multi-threading.
Moi si vouloir continuer moi devoir payer qlqn pour implémentation vulkan et optimisation du code.
EDIT : J'en ai parlé à mon frère à propos de la lenteur il me dit que c'est parce que ma carte graphique elle est trop ancienne j'ai une gtx 1660 super et maintenant c'est les rtx ma carte graphique elle date de 5 ans et il m'a dit que lui il a une carte graphique de 2 ans et le dernier assassin's creed il ne tounerait pas dessus parce que maintenant c'est du raytracing et sa tour ne serait pas assez rapide et la mienne non plus n'est pas assez rapide pour du raytracing. (En effet je tourne à du 1 FPS en raytracing avec compute shader)
Mouais, m'est avis que ton GPU devrait largement supporter l'affichage de 13*5k polys... Faut arrêter de tout reporter sur le matos. Ton moteur est lent, il faut y remédier.
> il utilise vulkan et sans doute du multi-threading. Mon moteur n'utilise qu'une seule queue, donc pas de multithreading, non...
> Tu remets à jour l'index avant chaque appel à draw pour chaque mesh Pas besoin de remettre à jour l'index avant chaque draw, l'ID de matériau est un truc qui ne change pas souvent.
> Tu utilises un uniform pour l'index du matérieau pour chaque mesh ? Je n'envoie pas l'index du matériau, mais le pipeline ID (qui peut être le même pour plusieurs matériaux) et couplé au draw ID (je suis en multi draw indirect) et à l'instance ID, je retrouve le model ID, qui me permet de retrouver toutes les infos dont j'ai besoin.
> Ca doit être lent! T'es mignon...
Si vous ne trouvez plus rien, cherchez autre chose.
Mouais, m'est avis que ton GPU devrait largement supporter l'affichage de 13*5k polys... Faut arrêter de tout reporter sur le matos. Ton moteur est lent, il faut y remédier.
> il utilise vulkan et sans doute du multi-threading. Mon moteur n'utilise qu'une seule queue, donc pas de multithreading, non...
> Tu remets à jour l'index avant chaque appel à draw pour chaque mesh Pas besoin de remettre à jour l'index avant chaque draw, l'ID de matériau est un truc qui ne change pas souvent.
> Tu utilises un uniform pour l'index du matérieau pour chaque mesh ? Je n'envoie pas l'index du matériau, mais le pipeline ID (qui peut être le même pour plusieurs matériaux) et couplé au draw ID (je suis en multi draw indirect) et à l'instance ID, je retrouve le model ID, qui me permet de retrouver toutes les infos dont j'ai besoin.
> Ca doit être lent! T'es mignon...
Salut, ce n'est pas mon GPU qui est lent je pense c'est le CPU parce que le GPU fait son travail en parallèle du CPU logiquement donc le CPU ne devrait pas attendre après le GPU. Peut être à cause de la mise à jour trop fréquentes des VBO et le fait que je passe pas mal d'attributs de sommets. Je vais essayer de faire des VBO préchargées, j'ai déjà essayé de virer les push_back pour voir mais ça n'accélère pas le rendu.
Par contre je ne sais pas comment je vais faire pour mettre les données du matériau dans un SSBO, pour l'instanced rendering ça pourrait passer avec gl_InstanceId mais pour tout ce qui n'est pas instanced il faut une donnée par vertex et donc un VBO. Ou alors s'amuser à compter le nombre de vertices pour chaque mesh et essayé un attribDivisor pour incrémenter gl_vertexId correctement mais je ne suis pas sûr que c'est possible et que ça soit très optimisé de faire comme ça. Je ne vois qu'une seule solution : tout dessiner en indirect et en instanced.
Le seul endroit ou je trouve qu'un SSBO est utilise c'est pour les per-pixel-linked-list.
EDIT : je crois que je vais faire les changements que tu dis dont 3 changements à venir :
-Utilisation de SSBO pour stocker les données de mesh (et non de sommet) et tout sera dorénavant dessiné en instanced rendering. J'utiliserai moins de shader comme cela et moins de draw calls.
-Possibilité de préchargé les entités sur les composants de rendu, de ce fait les VBO ne seront plus mise à jour à chaque frame mais seulement une fois. Seul les indices seront mis à jour à chaque frame pour dessiner seulement les sommets visibles. Pour entité non statique (les animations et particules) il faudra quand même mettre à jour les données du grand VBO à chaque mise à jour.
-Changement de la technique de réfraction/réflection, le dynamic environment mapping bouffe trop de FPS je passe de 80 à 20 et ça ne fonctionne pas en 2D j'ai trouvé une autre technique sur le site de nvidia qui fonctionnerait mieux.
Voilà.
EDIT 2 : par contre il y a un inconvénient avec les SSBO : tu ne sais pas utiliser un buffer d'indices pour seulement récupérer les indices des matériaux visible. Donc obligé de mettre à jour les SSBO à chaque frame pour récupérer le bon matériau avec le gl_InstanceID, c'est sans doute pour ça que je n'ai pas utilisé un SSBO pour ça.
Salut! J'ai trouvé une idée pour optimisé le temps de rendu!!! Mais je n'ai pas encore testé j'ai eu cette idée en parlant avec dragonjoker sur discord. (le créateur du moteur de rendu castor3D)
Apparemment les transferts CPU=>GPU coûte cher donc j'ai décidé de les réduire aux maximum.
Voici comment je compte faire :
-Mettre chaque donnée de sommet dans un SSBO et chaque donné des matériaux dans un autre SSBO. -Créer un VBO par entité mais à la place de lui passer les positions de sommets je vais lui passer l'ID de l'entité et l'ID du matériel. -Trier les entité par type de primitive et dessiner tout en multiDrawIndirect. -Récupérer les données dans le SSBO du shader grâce à l'ID de l'entité et l'ID du matériau et glDrawID et glInstanceID.
Il n'y a que les entités dynamiques ou je devrais remettre à jour les sommets ou le matériel dans les SSBO. Pour tout le reste plus de transfert. En fait je pensais que les draw calls étaient gourmand donc je les ai réduits au max mais dragonjoker m'a dit que ce sont les transferts CPU=>GPU qui sont le plus gourmand donc voilà pourquoi j'ai mal codé le moteur.
Si vous ne trouvez plus rien, cherchez autre chose.
PXL Le retro gaming facile Thread sur le forum: https://openclassrooms.com/forum/sujet/retro-pxl
PXL Le retro gaming facile Thread sur le forum: https://openclassrooms.com/forum/sujet/retro-pxl
Si vous ne trouvez plus rien, cherchez autre chose.
Si vous ne trouvez plus rien, cherchez autre chose.
Si vous ne trouvez plus rien, cherchez autre chose.
Si vous ne trouvez plus rien, cherchez autre chose.
Si vous ne trouvez plus rien, cherchez autre chose.
Si vous ne trouvez plus rien, cherchez autre chose.