Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1433 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Monde infini en openGL

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Monde infini en openGL

n°630930
iceteapech​e
www.iceteapeche.com
Posté le 04-02-2004 à 13:03:13  profilanswer
 

Kikoo tous,
 
j'essaye de programmer un petit soft en openGL a la magic carpet. Je bloque sur un algo qui me permettrait d'avoir mon monde 3D "rond", c'est a dire que je puisse infiniment avancer tout droit sans jamais en voir la fin. J'ai pensé a un algo utilisant 9 maps et qui les bougerai au fur et a mesure
 
/****/****/****/
/  1 /  2 /  3 /
/****/****/****/
/  4 /  5 /  6 /
/****/****/****/
/  7 /  8 /  9 /
/****/****/****  
 
si je passe du 5 au 1
-------------------->
 
 
 
/****/****/****/
/  9 /  7 /  8 /
/****/****/****/  
/  3 /  1 /  2 /
/****/****/****/
/  6 /  4 /  5 /
/****/****/****/
 
 
Apparement ca devrai marcher mais je n'arrive pas a coder les algo :(
 
Pouvez vous m'aider
 
Merci de vos réponses


Message édité par iceteapeche le 08-02-2004 à 10:00:18

---------------
Se souvenir des belles choses...
mood
Publicité
Posté le 04-02-2004 à 13:03:13  profilanswer
 

n°630959
Taz
bisounours-codeur
Posté le 04-02-2004 à 13:18:04  profilanswer
 

ASV ?

n°630966
chrisbk
-
Posté le 04-02-2004 à 13:23:10  profilanswer
 

ben tu decoupes ton monde en patch (ou secteur). chaque secteur centré sur l'origine
tu trouves le secteur ou est le viewer (S)
 
tu dessine le carre de (s-1,s-1) a  (s+1,s+1) avec des modulos/test  pour cycler, avec bricolage de la matrice de transformation pour chaque secteur
 
bref jvois pas le pb :o

n°630968
Dav Vador
Posté le 04-02-2004 à 13:23:18  profilanswer
 

En fait tu as 9 cases pour ton monde.
Pour chaque case, tu fais une structure du genre :
 
typedef struct _Case
{
   int ID;
   _Case * NE, // Nord Est
         * N,
         * NO,
         * E,
         * O,
         * SE,
         * S,
         * SO;
} Case;
 
A l'init tu mets pour chacune des 9 cases les bonnes valeurs de NE, N, ..., S, SO.
 
A l'affichage, tu regardes ds quelle case tu es, par ex la case 5, et tu affiches toutes les cases NE, N, ..., S, SO voisines définies ds la structure ;)

n°631028
iceteapech​e
www.iceteapeche.com
Posté le 04-02-2004 à 13:52:46  profilanswer
 

Merci pour vos réponses!!!  
 
L'algo de Dav Vador m'a l'air bien sympathique :D
 
 
merci tous


---------------
Se souvenir des belles choses...
n°631048
chrisbk
-
Posté le 04-02-2004 à 14:06:19  profilanswer
 

Oublie pas de bricoler ta matrice de translation

n°631140
Dav Vador
Posté le 04-02-2004 à 15:35:08  profilanswer
 

IceTeaPeche a écrit :

Merci pour vos réponses!!!  
 
L'algo de Dav Vador m'a l'air bien sympathique :D
 
 
merci tous

C'est une soluce parmis tant d'autres, c'est ptet pas la meilleure ;)

n°634992
iceteapech​e
www.iceteapeche.com
Posté le 08-02-2004 à 10:07:16  profilanswer
 

Je me permet de relancer le sujet meme s'il devait etre bouclé ;)
En fait l'algo ne marche pas... Deja il m'est pas facile de savoire exactement ou je suis puisqu'en fait les cases bougent tout le temps, je ne peux donc pas faire de tests direct sur les coordonées...
 
mon monde est représenté par neuf cubes disposés de la facon suivante :
1 2 3
4 5 6
7 8 9
 
et je translate a chaque fois mon repere sur le coin haut droit du cube n pour le dessiner.
 
Je stocke quelque part les coordonnées du coin haut droit du cube du milieu.
 
Jusque la tout marche.
 
Si je rajoute avant tout ca la fonction suivante pour mettre a jour le cube ou je me trouve ca plante...

Code :
  1. int SetMondeCourant()
  2. {
  3. tVector3 MaPosition = Camera.Position();
  4. glScalef(Echelle,Echelle,Echelle);
  5. glTranslatef(coinhautdroit.x,coinhautdroit.y,coinhautdroit.z);
  6. if (MaPosition.x >0)
  7. {
  8.  coinhautdroit.x=coinhautdroit.x + 85*MAP_SCALE;
  9.  coinhautdroit.y=coinhautdroit.y;
  10.  coinhautdroit.z=coinhautdroit.z;
  11.  return monde[mondecourant-1].E;
  12. }
  13. if (MaPosition.x < -85*MAP_SCALE)
  14. {
  15.  coinhautdroit.x=coinhautdroit.x - 85*MAP_SCALE;
  16.  coinhautdroit.y=coinhautdroit.y;
  17.  coinhautdroit.z=coinhautdroit.z;
  18.  return monde[mondecourant-1].O;
  19. }
  20. if (MaPosition.z > 0)
  21. {
  22.  coinhautdroit.x=coinhautdroit.x;
  23.  coinhautdroit.y=coinhautdroit.y;
  24.  coinhautdroit.z=coinhautdroit.z + 85*MAP_SCALE;
  25.  return monde[mondecourant-1].N;
  26. }
  27. if (MaPosition.z < -85*MAP_SCALE)
  28. {
  29.  coinhautdroit.x=coinhautdroit.x + 85*MAP_SCALE;
  30.  coinhautdroit.y=coinhautdroit.y;
  31.  coinhautdroit.z=coinhautdroit.z - 85*MAP_SCALE;
  32.  return monde[mondecourant-1].S ;
  33. }
  34. return mondecourant;
  35. }


 
mes cubes sont de 85x85 et MAP_SCALE est l'echelle de ma height map. monde[9] est ma structure de monde et coinhautdroit le coin haut droit associé au cube du milieu.
 
Bah ca fait n'importe quoi le cubes apparaissent puis disparaissent c'est une catastrophe.
Voila aussi ma fonction de rendu

Code :
  1. void Render()
  2. {
  3.  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  4.  glMatrixMode(GL_MODELVIEW);
  5.  glLoadIdentity();
  6.  Camera.Update();
  7.  Camera.Look();
  8.  Frustum.CalculateFrustum();
  9.  glPushMatrix();
  10.   mondecourant = SetMondeCourant();
  11.  glPopMatrix();
  12.  glPushMatrix();
  13.  //glLoadIdentity();
  14.   glScalef(Echelle,Echelle,Echelle);
  15.   glTranslatef(coinhautdroit.x,coinhautdroit.y,coinhautdroit.z);
  16.   DrawMonde(mondecourant-1);
  17.  glPopMatrix();
  18.   //CUBE SUD  
  19.  glPushMatrix();
  20.   glTranslatef(coinhautdroit.x,coinhautdroit.y,coinhautdroit.z);
  21.   glScalef(Echelle,Echelle,Echelle);
  22.   if (Frustum.CubeInFrustum(-85*MAP_SCALE/2,85*MAP_SCALE/2 ,-85*MAP_SCALE/2, -85*MAP_SCALE-85*MAP_SCALE/2))
  23.   {
  24.    glTranslatef(0.0f, 0.0f , -85*MAP_SCALE);
  25.    DrawMonde(monde[mondecourant-1].S-1);
  26.   }
  27.  glPopMatrix();
  28.                 //etc  
  29. }


 
Si vous pouvez m'aider ...
 
Merci


Message édité par iceteapeche le 08-02-2004 à 10:08:06

---------------
Se souvenir des belles choses...
n°635046
youdontcar​e
Posté le 08-02-2004 à 13:23:40  profilanswer
 

IceTeaPeche a écrit :

[..] magic carpet.

De mémoire, c'était une map carrée, le terrain était une map d'élévation avec des mesh par dessus. Comment ça marche chez toi ? '9 carrés', c'est vague.

n°635412
iceteapech​e
www.iceteapeche.com
Posté le 08-02-2004 à 21:03:40  profilanswer
 

C'etait bien une map carré. J'utilise aussi une heightmap avec des mesh par dessus. Les "9 carrés" c'est en fait une division de mon carré en 9 zones du type  
123
456
789
 
pour me permettre de faire basculer les carrés et donner l'illusion du monde infini
 
du genre je commence dans le carré 5 puis des que je passe dans le carré 2 mon monde est affiché comme il suit :
 
789
123
456
 
Maintenant je n'ai qu'un seul bmp pour la carte d'elevation.  
 
Si tu connais un meilleur algo pour l'illusion d'infini... :)
 
[J'espere qu'on comprends quand meme un minimum ce que j'essaye de dire ;)]
 
Merci tous


---------------
Se souvenir des belles choses...
mood
Publicité
Posté le 08-02-2004 à 21:03:40  profilanswer
 

n°635439
youdontcar​e
Posté le 08-02-2004 à 21:40:27  profilanswer
 

iceteapeche a écrit :

Les "9 carrés" c'est en fait une division de mon carré en 9 zones du type

Une méthode de barbare, donc :D
 
Pour un truc similaire (rendu voxel de comanche, rotozoom 3d), ça marchait comme ça - ton champ de vision est une pyramide, formée par 4 rayons. Intersecte ces 4 rayons avec ta heightmap et tu vas obtenir un quadrilatère quelconque : c'est ce que tu dois afficher à l'écran. Rasterize ce quadrilatère comme 2 triangles, tu pourras ainsi afficher la partie de ton paysage qui t'intéresse.
 
Maintenant il va sûrement falloir que tu subdivises ta map en carrés, comme tu as fait - là tu ne rasterizes plus ta heightmap mais ta heightmap subdivisée.
 
Pour simuler l'infini, ça se fait à la toute dernière étape, avant de récupérer les texels à afficher. Mettons que ta map fasse 256x256, tu vas obtenir des coordonnées (312, 260), tu fais un petit and (312 & 255, 260 & 255) et hop - ton terrain est infini.


Message édité par youdontcare le 08-02-2004 à 21:40:49
n°635595
iceteapech​e
www.iceteapeche.com
Posté le 09-02-2004 à 02:24:13  profilanswer
 

Euhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
 
j'ai pas tout compris je crois ; desolé :(
 
j'arrive a avoir les quatres rayons de la pyramdie (c'est mon frustum) et je pense avoir compris pour la rasterization
 
par contre le and la je crois qu'il me manque une notion ou deux... Pourrais tu m'expliquer la manip stp


---------------
Se souvenir des belles choses...
n°635692
youdontcar​e
Posté le 09-02-2004 à 10:31:05  profilanswer
 

C'est du raytracing standard. Tu intersectes le plan xOz, tu obtiens un point 3d P. Tout point d'intersection du plan xOz aura le même y (=0), tu considères donc x & z comme étant les coordonnées de ta texture. Tu obtiens qq chose comme P = (-1054.28, 3123.2). Ta texture fait 256x256. Il faut donc trouver un moyen de mapper des coordonnées infinies sur des coordonnées finies (ta texture). Pour ça, il suffit de les passer par un modulo % 256 (reste de la division par 256) : toute coordonnée sera ramenée entre 0 et 255.
 
Le modulo sur des puissances de 2, c'est un cas particulier dans lequel on utilise un & binaire. Tes coordonées peuvent varier entre 0 et 255, soit 8 bits :
 
11111111
 
Si tu files une coordonnée plus grande
 
1010010101001110
 
tu gicles bêtement les bits qui ne t'intéressent pas (ceux de poids fort. Ça se passe avec un AND :
 
1010010101001110 AND 0000000011111111 = 0000000001001110
 
et voilà la coordonnée bornée entre 0 et 255.

n°635694
chrisbk
-
Posté le 09-02-2004 à 10:35:23  profilanswer
 

(la plupart des compilos sont suffisament intelligent pour remplacer un %(2^n) par un &((2^n) - 1) )

n°635708
youdontcar​e
Posté le 09-02-2004 à 10:50:20  profilanswer
 

Oui. Vieux réflexe :D

n°635743
iceteapech​e
www.iceteapeche.com
Posté le 09-02-2004 à 11:31:39  profilanswer
 

oki mais ca veut dire qu'a ce moment la je ne reviendrai pas au début de ma map si je la depasse. Ce que j'appelle une simulation d'inifini ce serai de tourner en rond infiniment sur ma map en avancant tout droit...
Je me sens boulet la je suis dslé


---------------
Se souvenir des belles choses...
n°635775
youdontcar​e
Posté le 09-02-2004 à 11:51:55  profilanswer
 

IceTeaPeche a écrit :

oki mais ca veut dire qu'a ce moment la je ne reviendrai pas au début de ma map si je la depasse.

Ben si ! Ça veut dire que quelles que soient les coords de ta caméra, leurs rayons intersecteront toujours le plan de ta texture.  
 
Imagine : tu es en (0, 0), tu traces un rayon juste en bas, tu te retrouves avec les coords terrain (0, 0). tu te déplaces tout droit, tu te retrouves en (256, 0), tu traces à nouveau un rayon, tu obtiens (256, 256) qui une fois modulé donne (0, 0) -> tu es revenu à ton point de départ.

n°635807
iceteapech​e
www.iceteapeche.com
Posté le 09-02-2004 à 12:18:28  profilanswer
 

(ca m'a l'air bien puissant comme algo) et vu que je calcule ca a partir des rayons meme la vue sera ajustée?? Je ne pense pas que je saurai coder ca :S n'y a t il pas un tutorial ou n'as tu pas une portion de code avec cet algo histoire de voir a quoi ca ressemble?
 
En tout cas merci pour l'info, ca a l'air d'etre exactement ce que je cherchais!


---------------
Se souvenir des belles choses...
n°635830
youdontcar​e
Posté le 09-02-2004 à 12:45:05  profilanswer
 

Oui c'est puissant, enfin c'est surtout le seul vraiment adapté. Ça affiche exactement ce qu'il faut à l'écran, et tu peux limiter en profondeur facilement. Comme tu as des objets sur ton terrain, tu peux savoir lesquels afficher avec la même méthode.
 
Côté code, tu peux regarder des sources de voxel ou de rotozooms 3d. Je ne connais rien de spécifique.
 
Enfin c'est vraiment pas compliqué. Pour résumer, il te faut :
* définir un plan qui contient ta heightmap
* définir une caméra 3d (x, y, z) avec son orientation
* à partir de ça, calculer les 4 rayons de la pyramide de vision (faire gaffe lorsque tu regardes l'horizon)
* intersecter ces rayons avec ton plan
* traiter le quadrilatère comme 2 triangles à rasterizer. (c'est largement plus simple que du mapping standard, vu que tu peux choisir le sens dans lequel partir, et que tu n'interpoles pas les coords de texture)
* chaque coordonnée obtenue par la méthode précédente te donne sa position dans le repère monde, la modulation de ces coordonnées te donne l'index dans la map. Tu as donc tout ce qu'il te faut pour l'affichage : une position 3d & son texel correspondant.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Monde infini en openGL

 

Sujets relatifs
[Opengl mais pas seulement] Pb du au Filtrage des texturesperformances opengl
PB OPENGL et mon application WIN32[openGL] un menu qui apparait en appuyant sur Echap
[OpenGL] recuperer l'adresse d'une textureContourner limitation des taille de textures en OpenGL
[OpenGL / GLUT] Appliquer une texture à une sphère[OpenGL] Utilisation des NURBS
opengl[CSS] positionnement - IE vs le reste du monde
Plus de sujets relatifs à : Monde infini en openGL


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR