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 :

Gestion de VBO pour l'affichage de maillage style tesselation


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 5
    Par défaut Gestion de VBO pour l'affichage de maillage style tesselation
    Bonjour tout le monde,

    j'essaye de faire l'affichage de maillages triangulaire avec l'utilisation des VBOs pour des objet 3D assez gros (quelques dizaines de million de triangles) qui ont une structure assez proche des objets raffinés par le procédé de tesselation. En fait, j'ai des maillages avec une certaine quantité de triangles et je les subdivise avec une technique particulière qui fini par augmenter la quantité de triangle et par conséquent le détail de l'objet. Pour résumer, je subdivise un triangle dans n autres triangles. Les nouveaux triangles utilisent donc les sommets du triangle subdivisé, mais aussi de nouveaux points qui sont créés ainsi qu'une nouvelle topologie. Voila pour le résumé.

    Pour l'affichage j'utilise les VBO, histoire de optimiser l'utilisation de la carte, évitant des transfert RAM -> VRAM inutiles comme on a avec le mode immédiat ou les vertex arrays ou les display listes. Alors, imaginons que j'ai un triangle dont les sommets sont donnés comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    float SommetT1[] = {
                                 -0.5f,0.0f,0.5f, //S0
                                  0.5f,0.0f,0.5f, //S1
                                  0.0f,0.5f,0.5f  //S2
                                };
    et topologie (indices):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    uint IndicesT1[] = {0, 1, 2};
    Pour l'affichage je bufferise et dessine (en mode maille de fer) comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    //buffer des sommets
    int vboSommet1;
    glGenBuffers(1, &vboSommet1);
    glBindBuffer(GL_ARRAY_BUFFER, vboSommet1);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 3, SommetT1, GL_STATIC_DRAW);
    glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
     
    //buffer des indices
    int vboIndices1;
    glGenBuffers(1, vboIndices1);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndices1);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint) * 3 * 1, IndicesT1, GL_STATIC_DRAW);
     
    //dessin
    glEnableClientState(GL_VERTEX_ARRAY);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glDrawElements(GL_TRIANGLES, 1 * 3, GL_UNSIGNED_INT, (char *) NULL);
    glDisableClientState(GL_VERTEX_ARRAY);
    Bon, ça j'arrive à gérer sans souci. Le problème maintenant c'est d'afficher les nouveaux sous-triangles à la place de celui de base, sachant qu'ils utilisent les sommets de SommetT1[]. Imaginons que le triangle de base est subdivisé en 4 autres, avec donc les sommets en SommetT1 et des nouveaux comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    float SommetT2[] = {
                                 0.25f, 0.25f, 0.75f,//S3
                                -0.25f, 0.25f, 0.75f,//S4
                                 0.00f, 0.00f, 0.75f //S5
                                };
    et avec la nouvelle topologie:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    uint IndicesT2[] = { 
                          3, 4, 5,
                          0, 5, 4,
                          1, 3, 5,
                          4, 3, 2
                        };
    avec les indices 0, 1 et 2 faisant référence aux sommets S0, S1 et S2 de SommetT1[] et les indices 3, 4 et 5 correspondant aux sommets S3, S4 et S5 de SommetT2[]. Bon, normalement si je veux afficher ces nouveaux triangles je dois recomposer un autre VBO avec une nouvelle liste de sommet comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    float SommetT1etT2[] = {
                                         -0.5f,0.0f,0.5f, //V0
                                           0.5f,0.0f,0.5f, //V1
                                           0.0f,0.5f,0.5f, //V2
                                           0.25f, 0.25f, 0.75f,//V3
                                          -0.25f, 0.25f, 0.75f,//V4
                                           0.00f, 0.00f, 0.75f //V5
                                        };
    ce qui représente quand même un gaspillage d'utilisation de bande passante RAM -> VRAM puisque moité de ces sommets sont déjà dans un premier buffer dans la cg. Je pourrais utiliser la fonction glBufferSubData pour envoyer les sommets en SommetT2[] ce qui fait un grand buffer avec tout ce que j'ai bésoins sans renvoyer les sommets en SommetT1[]. Le problème là c'est que ce grand buffer je dois le créer avec la capacité totale pour accueillir les 6 sommets, ce que du coup représente un gaspillage de mémoire quand je ne veux afficher que le triangle de base. Pareil si je veux re-afficher les triangles de base après afficher les triangles détaillés (on ne peux pas faire de resize des VBO pur éliminé les sommet dont j'ai plus besoin. Puis, effacer tout le grand buffer et renvoyer les sommets de SommetT1 c'est le truc à éviter.)

    Voilà où j'en suis! Je vous appelle au secours Est-ce qu'il y a un moyen d'éviter le renvoie des sommets de base mais qu'au même temps je puisse effacer les sommets des triangles détaillés une fois ne plus utilisé? Dans le cas ou j'ai plusieurs millions de sommet et quelques re-subdivisions à faire par triangle ça devient un grand problème qu'il faut gérer au risque de trop ralentir le rendu des objets (ou déborder la VRAM quand j'aurai à afficher plus d'un objet). Pour la topologie je dois renvoyer a chaque fois qu'on change de topologie (ou bien tout garder en VRAM quand possible!), mais ça on n'y peut rien.

    Avez-vous des idée? Est-ce qu'il serait possible de fondre deux VBO et puis les re-séparer au besoin? D'ailleurs, comment openGL gère la tesselation, comment ils font pour optimiser la consommation de mémoire quand on change de niveau de détaille à répétition?

    Merci à vous tous pour votre attention,

    lao

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 173
    Billets dans le blog
    155
    Par défaut
    Bonjour et bienvenu,

    Wouah, plutot ardu comme problèmes.

    Je ne crois pas avoir de solution. Pour éviter ce gaspillage en mémoire ( ou ce gaspillage de bande passante ) je ne vois pas vraiment de méthode.
    L'utilisation des VBO n'est pas si mauvaise, mais dans votre cas, vous semblez faire souvent de changement de forme.
    Du coup, je dirai d'utiliser les glVertexPointer() ( et autres ) mais sans les VBO mais cela va faire un assez grand débit en mémoire.

    Devez vous faire une application en temps réel, ou du 20 FPS n'est pas génant ?

    Pour la tesselation, c'est implémenté que sur les cartes récentes. De plus, la tesselation c'est directement sur la carte graphique. On donne un triangle ( ou autre ) et lui il nous le découpe ( comme tout se passe sur la carte graphique, y a pas de problème de bande passante )
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 5
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Bonjour et bienvenu,
    Wouah, plutot ardu comme problèmes.
    Bonjour et merci pour l'accueil Malheureusement ça risque de ne pas être très simple en effet : /

    Citation Envoyé par LittleWhite Voir le message
    Devez vous faire une application en temps réel, ou du 20 FPS n'est pas génant ?
    Disons que je cherche la solution idéale, s'il y en a une! J'ai pas forcement une contrainte major de fps, mais le plus fluide, le mieux c'est, surtout que les perfs changent pas mal selon la cg.

    Citation Envoyé par LittleWhite Voir le message
    Pour la tesselation, c'est implémenté que sur les cartes récentes. De plus, la tesselation c'est directement sur la carte graphique. On donne un triangle ( ou autre ) et lui il nous le découpe ( comme tout se passe sur la carte graphique, y a pas de problème de bande passante )
    Je comprends. Mais est-ce que les donnés du maillage de base qu'on passe à la carte sont écrasé par le nouveaux maillage plus fin? Ou il est gardé quelque part si jamais on désire le re-afficher? La géométrie de base est-t-elle dupliqué dans un grand buffeur quand on réalise la tesselation? Je pourrait peut-être essayer de copier ce qu'il font comme gestion de mémoire

    Merci encore,

    lao

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 173
    Billets dans le blog
    155
    Par défaut
    Je ne sais pas vraiment comment est faite la tesselation, dans les nouvelles version d'OpenGL.

    Je viens de penser, et si vous utilisiez un geometry shader pour faire votre tesselation directement sur la carte graphique. ( Le problème, c'est un recalcul à chaque image ). L'avantage, c'est que l'on ne passe qu'un triangle, le shader fait le reste et tout sur la carte graphique. ( Je ne suis pas sur de la possibilité de ce que je dis ).

    Sinon, peut être qu'en jouant sur le glBufferDubData, cela peut fonctionner, mais comme vous dites, je ne peux pas dire si les indices vont aussi être efficace sur toute les données ( je pense que si )
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    ...
    Je viens de penser, et si vous utilisiez un geometry shader pour faire votre tesselation directement sur la carte graphique. ( Le problème, c'est un recalcul à chaque image ). L'avantage, c'est que l'on ne passe qu'un triangle, le shader fait le reste et tout sur la carte graphique. ( Je ne suis pas sur de la possibilité de ce que je dis ).
    ...
    Je ne suis pas sur que le geometry shader soit une bonne solution. J'avais fait des test pour une tesselation de terrain et j'vais été très déçu pas la lenteur de la chose.

  6. #6
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    Bonjour,

    juste une idée vite fait: pourquoi ne pas calculer et stocker le maillage fin une fois pour toute dans un VBO, puis jouer uniquement sur le VBO contenant la liste d'indices? La géométrie n'est alors envoyée qu'une fois, et actualiser la liste d'indices n'est pas aussi couteux que tous les sommets.

Discussions similaires

  1. Gestion d'un singleton pour l'affichage
    Par shenron666 dans le forum Contribuez
    Réponses: 1
    Dernier message: 03/01/2011, 13h49
  2. Gestion page suivante page précédante pour l'affichage
    Par sylvie.forum dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 26/03/2006, 17h51
  3. Question des gestions des genres pour livre, BD...
    Par Oberown dans le forum Schéma
    Réponses: 3
    Dernier message: 16/09/2004, 17h58
  4. Gestion des modifications pour un enregistrement
    Par Pascal Jankowski dans le forum Bases de données
    Réponses: 3
    Dernier message: 10/03/2004, 15h09

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