c'est un Skydome que je vois là ? :)
Version imprimable
Impressionnant. Quel type d'algorithme utilises-tu (LOD/ROAM) ? Sous quel forme de struct/variable stokes-tu tes données (heightmap?). Tu sépares par patch, donc tu coupes ton terrain en sous-terrain de NxN (carré) ? Quid de la consommation mémoire pour une telle grandeur ? Est-ce que ton terrain supporte le changement dynamique des points ?
Désolé pour toutes ces questions, si tu me permets, je suis très intéressé vois-tu :ccool:
Pas de souci pour les questions;)
Pour expliqué en quelques mots, Je ne mets en mémoire vidéo que la textures en niveau de gris dans la carte graphique. A coté de ça je crée 2 maillage de petite taille que je vais dessiné plusieurs fois à différentes echelle(une échelle correspondant à un LOD). Le rendu est fait par un shader qui va récupéré la hauteur du point à dessiné dans la heighmap et donc à la volé modifier mes petit maillage. J'espere avoir été clair.:mrgreen:
Je t'invite à lire le forum, dans un des messages j'ai mis les articles qui m'ont aidé : http://www.developpez.net/forums/d72...rain-clipmaps/
Je comprends pas bien le concepts des deux maillages. Ils sont issus les deux de ton heightmap (qui est ta texture en niveau de gris?) mais ils ont différentes précisions, c'est ça ? D'ailleurs y'a beaucoup de documents sur les terrains, je jetterais un œil à ton post pour les références, merci.
Sinon j'ai implémenté mon chargeur de fichier .obj (sans texture pour l'instant) dans mon programme. Je gère mes objets objets mobiles (ici des vaisseaux) basé sur les mesh décrit par le fichier .obj. Est-ce qu'il y a une méthode optimisé pour contenir ce type de donnée (à savoir ces mesh). Je rappel que les fichiers .obj contiennent simplement les points des vertices et les faces composées des précédentes vertices (avec texture et normales) cf: http://en.wikipedia.org/wiki/Obj. Pour l'instant je stoque les points des vertices dans une liste-file (pour l'ajout dynamique en O(1)) qui est convertie en tableau C (accès rapide en O(1)). Parallèlement je stocke les faces (numéro des vertices qui les composent) dans une file. Ensuite pour dessiner je parcours simplement la liste des faces et utilise le tableau pour composer les triangles. Est-ce selon vous une/la bonne méthode ?
D'autres part, comme dans de nombreux jeux, on utilise le même modèle/mesh pour plusieurs entités. Ici par exemple une armée du même vaisseau. On a donc un seul objet mesh en mémoire simplement dessiné plusieurs fois. Je stocke ces "instances" de mesh dans un struct qui sauve la position, les angles d'orientation et la taille. Puisque j'ai commencé à gérer les collisions (encore quelques bugs d'ailleurs) je stocke aussi la Bounding Box (BBox) (comprendre boîte entourant l'objet) (elles sont toujours parallèles aux axes de la scène dans mon implémentation) dans chaque instance et non dans le mesh. Peut-être n'est-ce pas très optimisé mais pourtant chaque vaisseau peut avoir un angle différent, ce qui implique une BBox différente. Je la stocke de deux manières: 1/ le point minimum et maximum (les sommets opposés de la boîte) 2/ les plans de la boîte. Tous deux varient si l'angle de l'instance est modifié. Je les calculent à chaque rotation mais pas translation car ça change rien. Même question pour cet aspect, est-ce une/la bonne méthode, y'a-t-il mieux selon vous ? Je sollicite votre avis et votre expérience.
Voici la vidéo correspondante : http://www.youtube.com/watch?v=VrzVlrln6IU
1/quand tu dis que le mesh est stocké une seule fois c'est uniquement côté RAM (client) ou bien aussi VRAM (GPU) ? tu n'alloues cet objet qu'une fois c'est ça ?
2/comment t'y prends pour l'intersection Box/Box, ray/Box Frustum/Box, ça m'intéresse
utilises tu une structure de partitionnement (Octree, etc...)
Je vois dans ta video que tu as recours au picking : comment calcules tu la transformation de ton mesh par rapport au déplacement de la souris ?
3/comment transmets tu la matrice de transformation de chaque "instance" ? par variable uniform ?
Je stocke uniquement en RAM car je ne sais pas comment stocker en VRAM. J'utilise les malloc et l'allocation automatique du C. Il me semble que je n'ai jamais à m'occuper, à aucun moment, de la VRAM. Donc je dirais une seule fois côté RAM uniquement. Peut-tu m'éclaircir ?
J'utilise d'abord un contrôle par la distance. Si elle est plus grande que la plus grande distance de collision possible (somme de la moitié de l'hypoténuse des deux boites) alors il n'y a pas de collision possible. Il n'y a pas d'Octree actuellement car la méthode des distances suffit (pour le moment) amplement. Le picking se fait (comme c'est indiqué dans les détails de la vidéo) avec gluUnproject qui utilisent les matrices. Je prends 2 points, une fois le Near et une fois le Far. Je crée un vecteur à partir de ceux-ci, je le normalise et décide de la distance à prendre par rapport à la caméra (code sous la main si intéressé). Après je soustrais ce vecteur au vecteur de position de l'objet (sauvé dans l'instance du mesh)
Les matrices (modelview, projection, viewport) sont sauvées dans une global, elle est sauvée à chaque frame (pas très optimisé, non?) utilisée ensuite avec gluUnproject. Preuve à l'appui voici mon instance de mesh :
Je n'utilise donc de variable uniforme (ne sachant même pas ce que c'est, honte à moi). De plus je n'ai pas besoin des matrices pour détecter les collisions, ni pour les boîtes. Je ne vois pas bien le rapport en fait ?Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 struct __meshinstance { // Model of the instance MeshObject *model; // Own propreties float x, y, z, angleX, angleY, angleZ, size; // Bounding box (collision detection) float boundingBox_minCoord[3], boundingBox_maxCoord[3]; vPlane **boundingPlanes; // [FIXIT] Don't forget to FREE them ! // Animation vLine *road; unsigned int roadStart, roadEnd, roadCurTime; float roadSpeed; };
EDIT: oui, on s'est croisé dans les messages. Je rajouterais :
Je ne vois pas de quoi tu parles. Je n'utilise (pas encore) de glBufferData. Quel est le principe et son utilité dans mon cas exactement ?
C'est une des commandes qui envoie les données de la RAM à la VideoRAM.
Un moment, j'ai failli vous dire d'utiliser les liste d'affichage ( display list ) pour avoir qu'une seul instance du mesh, et la dessiner plein de fois, mais les VBOs c'est encore mieux ( faut que j'évolue un peu ).
Sinon d'après l'explication que vous avez donné pour les bounding box, je n'ai rien à redire :ccool:
Et puis ça semble bien parti, votre projet, bonne continuation ;)
Au fait ton projet, c'est quoi exactement?
un terrain + un vaisseau = un RTS ou un jeu de combat aérien futuriste:D
Merci pour votre interêt et votre aide !
Alors effectivement, ça risque d'être une bonne idée si ça fonctionne comme je l'imagine (on crée une liste de triangle, on utilise une fonction exprès au lieu de faire beaucoup d'appel à glVertex3*). Ainsi on peut en dessiner beaucoup sans coût de transfert de donnée RAM -> GPU à chaque fois. Après on peut même imaginer libérer la RAM je pense. Effectivement le projet est bien lancé, et il est pas prêt d'être terminé vu mes faibles connaissances en Computer Graphics et OpenGL !
J'aimerais pas trop dévoiler (ce serait pas drôle sinon). En gros, ce serait un jeu mixé, RTS et d'autres type de jeux mais futuriste effectivement (ça se voit tant que ça ? zut). Le projet est ambitieux (déjà vu mon niveau) car le monde sera grand. Voilà ça suffit pour l'interview :P Si y'a des intéressés à rejoindre le projet (moyen terme) c'est vrai que je suis preneur.
1/ Sinon concernant les RTS, vous auriez de l'expérience concernant la programmation des ordres, mouvements/actions d'unités ? À part la gestion de collision (pour les unités et construction de bâtiments par exemple).
2/ Il y a aussi une grosse question que je me pose. Comment gérer une collision avec un terrain ? L'approximer par des boîtes c'est vraiment pas top, si des unités courent dessus ça fera escalier... sauf si les boîtes ne sont pas parallèles (complications des calculs), qu'est-ce que vous en pensez ?
3/ Sinon, comme tout RTS, il faudra que j'implémente l'algo A*, je l'ai déjà fait en 2D donc pas de souci, j'ai peut-être juste un doute sur la grille de chemin (passages possibles/bloqués). Je pensai faire une grille créée dynamiquement selon le point de départ et arrivée (grille rectangulaire avec une certaine largeur et qui commence du pt de départ jusqu'à l'arrivée avec un peu de marge). La grille serait composées de points assez séparés dont accessibilité serait déterminé s'il y a des objets dans un rayon autours. Après l'algo calcule le chemin le plus court selon les contraintes. Peut-être que la grille pourra être affinée et modifiée selon si des objets bougent, etc. Je stockerais la grille dans l'instance de mesh qui serait gérée par un animateur générale (mouvements), une espèce de singleton général. Qu'en dites-vous ?
4/ Selon vous est-ce que les boîtes (Bounding Box) doivent être parallèles, ou bien devrais-je utiliser des formes convexes régulières (polyèdre) pour être plus précis ? Est-ce que vous utilisez lorsqu'une collision est détectée par les BBox une méthode plus précise, à savoir contrôler les collisions avec les faces du mesh directement, par exemple ? Si vous avez implémenter quelque chose de semblable, cela m'intéresse aussi comment et le contexte.
Ce qu'il y a de sur, c'est qu'il faut enlevé les glVertex3f. Les listes d'affichage, c'est bien, mais c'est dépassé.
Les VBOs c'est encore mieux ;). Et cela fait à peu près ce que vous dites ( par contre, libération mémoire de la RAM, je ne le conseille pas )
Normalement, un bon modèle va contenir plusieurs boite de collision pour les différentes parties du modèle ( et non juste une unique grosse boite ).
Dans le cas d'un corps humain, nous retrouvons une boite pour la tête, une, le torse, plusieurs pour les jambes / bras ...
Oui évidemment, pour autant que le format utilisé décrive des groupes. Ce qui n'est pas le cas de mon fichier .obj car il a été convertit. Avec de la chance Blender a une option pour conserver ces propriétés. D'autre part je pense aussi faire des boîtes en OBB (orientée), si j'arrive à comprendre les matrice de covariance (enfin j'ai presque compris mais pas comment on intègre les coordonnées des points dans la matrice, c'est encore obscure pour moi).
Sinon, mes questions (1 à 4) restent toujours d'actualité et toujours sans réponse. Enfin ce serait plutôt des suggestions, avis et expérience pour être plus précis. S'il y en a qui veulent bien s'exprimer, merci d'avance.
Je sais que l'on peut utiliser des piles, pour chainer des ordre. Sinon, chaque objet à sa propre pile. Et chaque objet à une fonction update() qui le déplace.
Normalement, le terrain, c'est une collision utilisant les normales si je me rappelle bien.
Après, ce n'est pas vraiment collision avec me terrain... on parle juste de coller un objet avec le seul ( et il ne pourra pas aller plus bas ). Il faudra calculer la normal des triangles vertices. Mais y a une methode pour repéré dans quel triangle l'objet se trouve. Ce qui fait que le calcul n'est pas lourd :) ( Système de grille )
Après, si on ne veut pas qu'un objet aille quelque part ( pente trop grande, il faut voir entre la normal et le vecteur up de l'objet )
Perso, je ne sais pas :s
J'avais dit, pas de forme convexes réguliers. Je pensais avoir répondu à celle là
Tu peux regarder comment c'est fais dans TA spring , un RTS open Source.
Tu peux télécharger les source sur le site:
http://springrts.com/
C'est bien ce que j'imaginais, merci de me rassurer dans ce choix. C'est sûrement identique pour les bâtiments (queue d'objets à fabriquer/amélioration à faire). Après pour le update, je pense qu'il doit y avoir une classe générale qui gère les déplacements (avec collisions, physique genre balistique). L'update des objets donc doit faire appel à cette classe. Mais je peux toujours me tromper !
Je vois, c'est la méthode qui détecte si l'objet change de côté (changement du signe du produit scalaire). Je pense aussi à une autre méthode qui consiste à faire une interpolation de hauteur du heightmap avec la position de l'objet et voir si il traverse pas au point le plus proche (ou quelque chose comme ça). Faudrait aussi gérer le contact, pour pas que ça fasse des sauts.
Après pour l'histoire de hauteur de pas, je pense que y'a pas trente six milles solution et celle-ci convient bien.
C'était pas complétement répondu, mais voilà qui est fait. Merci !
Je connaissais pas, merci. Je regarde ça de plus près dès que j'aurais un peu plus de temps. Ça a l'air d'être du costaud ce projet !
Sinon de mon côté j'avance sur les terrains. Je charge mes heightmap à partir du format PGM et j'ai commencé mon algorithme ROAM. J'ai pas mal de soucis avec et je pense que je vais pas tarder à poster un topic pour détailler mes problèmes. Je me suis basé sur un article qui utilise une méthode spéciale. Finalement c'était peut-être pas une très bonne idée mais pourtant j'étais convaincu par leur méthode (sur le papier), cf http://dip.sun.ac.za/~henri/DiamondPaper.ps. Ils utilisent 4 queues: merge-above/below et split-above/below avec une forme de triangle en diamant.
Voilà, j'ai une nouvelle question qui me turlupine en ce moment. Comment est-ce que vous gérer les animations avec les DisplayList ou VBO ? Ces principes me semblent contraires, puisque ces listes sont statiques, n'est-ce pas ? Si on a un modèle d'un personnage humain, comment vous le faites marcher (jambes/pieds) s'il faut modifier les positions de plusieurs points dans le mesh ?
J'ai publié les sources pour le terrain que j'ai fais, voir la description de la vidéo (à la fin). J'espère que ça t'aideras.
Sinon, je tiens à vous remercier pour votre intérêt, votre aide m'a été précieuse.
Salut jamesb, ça avance ton projet on dirait :P
alors pour les animations, elles ne absolument pas incompatibles avec les VBO, puisque tu peux mettre ceux-ci à jour en modifiant les données dans tes buffers ; par exemple en OpenGL tu peux allouer tes VBO à l'initialisation avec glBufferData (allocation de l'espace mémoire) et glBufferSubData (copie des données de la RAM vers la VRAM), puis à chaque frame les rafraîchir avec de nouveau glBufferSubData ou bien glMapBuffer (voir les specs pour plus de précisions)Citation:
Comment est-ce que vous gérer les animations avec les DisplayList ou VBO ? Ces principes me semblent contraires, puisque ces listes sont statiques, n'est-ce pas ?
bien sûr envoyer de nouvelles données prend du temps mais c'est possible :ccool:
(en revanche je ne pourrais pas te répondre sur les display list, ne les ayant jamais pratiquées :()
une autre possibilité est d'effectuer les mises à jour dans les vertex shaders mais peut-être n'en es tu pas encore là, je réserve ça pour plus tard :);
je ne comprends pas trop ta questionCitation:
Si on a un modèle d'un personnage humain, comment vous le faites marcher (jambes/pieds) s'il faut modifier les positions de plusieurs points dans le mesh ?
Ça avance pas beaucoup, pour l'instant je pose encore les bases avant de me jeter dans les animations. Pour vous rendre compte j'ai même pas attaquer l'implémentation des textures, mais ça va venir (d'ailleurs les animations c'est plus important que les textures je dirais).
Apparemment on perd un peu l'initiative d'avoir mis ça dans la RAM du GPU puisqu'il faut de nouveau renvoyer les données (toutes ?). Par contre, si on peut renvoyer que les points qui ont bougés, ce serait le plus optimal, mais j'en doute. Donc, j'ai pensé à séparer les parties d'un mesh (pour l'exemple d'un bonhomme: tête, bras, corps, jambes, pieds) dans des DisplayList/VBO différents, ce qui permettrais de ne pas avoir à mettre à jour (ou peu). Tout cela dépend bien sûr du nombre de listes maximale autorisé, si c'est limité.
Un peu loin effectivement, mais j'ai déjà jeté un œil aux shaders de lumière pour me projeter dans les possibilités. Donc envoyer à l'aide d'une propriété par glColor3fv (si me souviens bien) les nouvelles positions, comme ça le shader peut mettre à jour sa mémoire, pour autant que la VBO soit atteignable dans le shader (uniform ou un truc du style ?). Là je ne fais que deviner, est-ce que je vois juste ?
C'est pas grave, c'était pour donner un exemple de mesh dont différentes parties peuvent être animées indépendamment. Ce qui sera aussi le cas dans mon jeu, pour la plupart des animations. Merci !