IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

tableau d'index pour un maillage en triangle_strip


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 26
    Par défaut [Résolu] tableau d'index pour un maillage en triangle_strip
    Bonjour,

    Je travaille actuellement sur la creation d'un maillage en openGl, je suis face a un probleme qui me pose pas mal de soucis.

    Je crée, via un VBO, un maillage regulier affiché avec un GL_TRIANGLE_STRIP, cependant, au bout de chaque bande, le dernier segment vient reboucler sur le premier de la bande suivante.

    voici un exemple sur un tout petit maillage :



    Visiblement la solution est de passer par un tableau d'index pour specifier l'ordre des points et d'utiliser a la place de mon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4*mesh_height*mesh_width);
    un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glDrawElements( GL_TRIANGLE_STRIP, 4*(mesh_width*mesh_height), GL_UNSIGNED_INT, indices);
    Mon probleme vient du calcul de ces indices, je n'arrive pas a comprendre l'ordre des points, et comment le construire.

    Pour aider :

    voici la création des points (j'ai volontairement remplacé la composante sur Z par 0.0f pour eviter de charger trop le post) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    pos[k++] = make_float3(x, 0.0f, y);
    		pos[k++] = make_float3(x+1.0f, 0.0f, y);
    		pos[k++] = make_float3(x, 0.0f, y+1.0f);
    		pos[k++] = make_float3(x+1.0f, 0.0f, y+1.0f);
    je fais l'equivalent d'une boucle sur x et sur y (via de la programmation GPGPU sur Cuda pour ceux qui connaissent. (et pas d'inquietude pour les float3, ca marche bien)

    C'est equivalent a :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    k=0;
    for(int x=0;x<width;x++)
    for(int y=0;y<width;y++){
    pos[k++] = make_float3(x, 0.0f, y);
    		pos[k++] = make_float3(x+1.0f, 0.0f, y);
    		pos[k++] = make_float3(x, 0.0f, y+1.0f);
    		pos[k++] = make_float3(x+1.0f, 0.0f, y+1.0f);
    }
    Merci bien !

  2. #2
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 582
    Par défaut
    Bonjour,

    l'utilisation d'un tableau d'indices ne résoudra pas votre problème, puisqu'une fois une bande terminé, soit il faut en créer une autre, soit supporter un triangle parasite

    par contre, on peut supprimer la visibilité de ce triangle parasite en envoyant 2 coordonnées identiques de suite au driver, soit en dupliquant les coordonnées (cas du glDrawArrays) sinon en dupliquant l'indice de la coordonnée à envoyer (cas du glDrawElements)
    en envoyant 2 coordonnées identiques, la surface du triangle à générer sera nulle et le driver l'ignorera

    concernant le tableau d'indices, vu que vous avez compris l'utilisation de triangle strip, je vais essayer de vous expliquer comment ça fonctionne
    l'intéret d'un tableau d'indices c'est de ne pas avoir à envoyer une même coordonnée plusieurs fois au driver

    je vais prendre un maillage très petit comme exemple, si on considère 3*3 sommets pour le définir, en triangle strip brut il faudra :
    6 coordonnées pour la première bande, plus 6 autres pour la seconde bande
    soit 12 coordonnées

    avec un tableau d'indices, il faut créer un tableau avec les 9 coordonnées et envoyer un tableau de 12 indices qui contiendra l'indice de la coordonnée à utiliser dans le tableau des coordonnées
    dans notre cas, le tableau d'incides contiendrait :
    bande 1 : 0, 3, 1, 4, 2, 5
    bande 2 : 3, 6, 4, 7, 5, 8

    sachant que les coordonnées sont enregistrée dans cet ordre :
    0...1...2
    3...4...5
    6...7...8
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  3. #3
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 26
    Par défaut
    Ok, j'ai compris comment cela fonctionne, je vais essayer de l'implementer

    Merci bien

  4. #4
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 26
    Par défaut
    C'est encore moi

    Je reviens a la charge pour avoir plus de precisions.

    J'ai donc selon, vos conseils, modifié mon code pour utiliser les indices. Cela m'a permis de gagner beaucoup en temps de génération de terrain ca du coup je crée seulement 1 point par intersection (contre 4 avant).

    Cependant, j'ai toujours un probleme pour faire des triangles dégenerés.

    Je vais donc partir sur un exemple simple pour etre sur de comprendre :

    Si j'ai un maillage carré de 2*2, mes points seront donc disposés comme ceci :


    0 - 1 - 2

    3 - 4 - 5

    6 - 7 - 8

    et mon tableau d'indices sera : 0-3-1-4-2-5-3-6-4-7-5-8

    avec ma premiere bande : 0-3-1-4-2-5 et ma deuxieme : 3-6-4-7-5-8

    Si on appele mesh_width la largeur et mesh_height la longueur on aura donc une boucle de type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int i=0;
    	for(int x=0;x<mesh_width;x++){
    		for(int y=0;y<mesh_height;y++){
    			index[i++]=x*(mesh_height)+(y);
    			index[i++]=(x+1)*(mesh_height)+(y);
    		}
    	}
    pour remplir le tableau d'indices.

    Petite question pour l'affichage : je dois bien afficher avec un glDrawElements ?

    Voici mon glDraw :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glDrawElements(GL_TRIANGLE_STRIP, 2*mesh_width*mesh_height-1, GL_UNSIGNED_INT, index );
    index est un tableau de unsigned int definit comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    unsigned int * index;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int index_size = 2*mesh_height*mesh_width;
    index =(unsigned int*) malloc(index_size*sizeof(unsigned int));
    Maintenant, je souhaite ajouter un triangle dégeneré a la fin de chaque bande, et la, je n'arrive pas a comprendre quel(s) indice(s) je dois dupliquer.

    Dans un premier temps j'avais pensé a ajouter le dernier indice de la bande :

    0-3-1-4-2-5-5-3-6-4-7-5-8-8

    mais j'ai toujours un rebouclage

    puis a ajouter le dernier indice de la bande finie et le premier de la bande suivante :

    0-3-1-4-2-5-5-3-3-6-4-7-5-8-8

    La, j'ai un bon resultat en 2D (maillage plat avec une elevation nulle) mais quand je passe en 3D je retrouve les lignes :



    Si vous aviez une idée pour creer un triangle degeneré sans reboucler sur les bandes suivantes

    Merci du coup de main !

  5. #5
    Rédacteur
    Avatar de bafman
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    2 574
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2003
    Messages : 2 574
    Par défaut
    utiliser un seul triangle strip pour l'ensemble du terrain est une mauvaise idée pour plusieurs raisons :
    - tu tombe forcement sur ton problème en bout de ligne
    - utiliser un seul triangle strip te bloque dans l'utilisation d'algo de level od detail et autre decoupage en octree/quadtree

    bref, tu a tout interet à utiliser plusieurs strip pour afficher ton terrain...
    * Il est infiniment plus simple de faire rapidement un code qui marche que de faire un code rapide qui marche
    * pour faciliter les recherches, n'oubliez pas de voter pour les réponses pertinentes
    Mes articles

  6. #6
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 26
    Par défaut
    Alors, j'avais essayé cela, c'etait en fait ma premiere idée :

    Faire une boucle et afficher a chaque incrementation une bande du terrain.

    Probleme : la fluidité.
    J'affiche des "grands" maillages (2000*2000 mailles) et une boucle sur 2000 incrementations prends du temps, surtout qu'elle se trouve dans la fonction de rappel d'affichage et donc opengl boucle dessus

    Bref, s'il n'y a que cette methode valable je m'en contenterai, mais le principe des indices me plaisait assez

  7. #7
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 582
    Par défaut
    tu dois juste doubler le premier indice de la bande suivante
    dans ton exemple cela donne
    0-3-1-4-2-5-3-3-6-4-7-5-8

    la série 5-3-3 créant le triangle dégénéré nécessaire pour passer à la bande suivante

    pour optimiser ton traitement tu peux utiliser les VBO si l'extension est disponible sur la carte vidéo que tu utilises

    pour ma part, je ne pense pas comme bafman, les triangles dégénérés sont très pratiques, ça permet de ne pas avoir à appeler plusieurs fois glDrawElements et de perdre une partie de l'avantage apporté par les array (VA ou VBO)
    tout dépend du nombre de sommets que comporte ton maillage

    si tu avais 65536 sommets maximum, tu pourrais utiliser des indices en GLushort, tu y gagnes en mémoire ET en rapidité

    ce que tu peux aussi faire, c'est fusionner plusieurs bandes tant que ça ne dépasse pas la limite d'un unsigned short en nombre de sommets
    sinon tu crées une nouvelle bande
    et tu crées une display list avec tes appels à glDrawElements pour n'avoir qu'un seul appel à faire à chaque image
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Algorithme d'indexation pour moteur de recherche
    Par caspertn dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 24/04/2006, 16h57
  2. Réponses: 16
    Dernier message: 02/12/2005, 10h39
  3. Parcourir tableau 6Dimenssions Indexation particuliè
    Par Zenol dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 26/07/2005, 15h39
  4. Créer un index pour une Base de données
    Par john7 dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 31/01/2005, 21h43
  5. Réponses: 7
    Dernier message: 21/10/2004, 09h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo