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'indices avec openGL (Peut être avec un VBO ?)


Sujet :

OpenGL

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 351
    Points : 432
    Points
    432
    Par défaut tableau d'indices avec openGL (Peut être avec un VBO ?)
    Un tableau de 8 sommets:
    -0.5 0.5 0.5
    0.5 0.5 0.5
    -0.5 -0.5 0.5
    0.5 -0.5 0.5
    -0.5 0.5 -0.5
    0.5 0.5 -0.5
    -0.5 -0.5 -0.5
    0.5 -0.5 -0.5
    Un tableau de 6 normals:
    1.0 0.0 0.0
    -1.0 0.0 0.0
    0.0 1.0 0.0
    0.0 -1.0 0.0
    0.0 0.0 1.0
    0.0 0.0 -1.0

    un tableau de 6*8 indices donc 6 faces avec offset 0 (vertex) et offset 1 (normals) :

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


    Comment peut-on afficher cela avec openGL svp ? je ne trouve pas la solution , il y a bien glIndexPointer() , mais ici le tableau d'indice est entrelacé .

    Si quelqu'un connais la solution je veux bien un petit bout du code.

  2. #2
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Bonsoir,

    voilà un petit bout de code pour afficher une face d'un cube de taille "size" en (x,y,z) dans le plan XY. Il te suffira de l'adapter en considérant qu'une face du cube est un carré qui est lui même composé de deux triangles.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    glBegin(GL_TRIANGLES) ; 
    glNormal3f(0.f, 0.f, -1.f) ;
    glVertex3i(x, y, z) ;
    glVertex3i(x+size, y, z) ;
    glVertex3i(x+size, y+size, z) ;
    glNormal3f(0.f, 0.f, -1.f) ;
    glVertex3i(x+size, y+size, z) ;
    glVertex3i(x, y+size, z) ;
    glVertex3i(x, y, z) ;
    glEnd() ;

  3. #3
    Membre éclairé
    Avatar de Happy
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2005
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Autre

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2005
    Messages : 665
    Points : 875
    Points
    875
    Par défaut
    ToTo13, je ne vois pas en quoi ça réponds à son message?

    Sinon il faudrais voir du coté de glInterleavedArrays();

  4. #4
    Membre éclairé Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Points : 693
    Points
    693
    Par défaut
    En fait un Vertex Array, peut être vu comme un tableau d'informations de sommets dans lequel tu peux mettre :

    - les coordonnées du sommet;
    - les coordonnées de la normale au sommet;
    - et bien d'autre choses (cf la reference tout en bas see also, les glXXXPointer).

    Spécification des emplacements de données
    Le Vertex Array (qui est en fait un tableau de pointeurs vers ces informations) se remplit à l'aide des fonctions glXXXPointer.
    Tu dois à chaque fois fournir une zone mémoire qui contient les informations adéquate pour tout tes sommets.

    Il est aussi possible de spécifier tous ces pointeurs en une seule fois avec glInterleavedArrays (si tes données sont entrelacées).

    (des)Activation de l'utilisation de ces emplacements
    Pour qu'OpenGL aille chercher ces informations au moment du rendu, il faut lui dire avec la fonction glEnableClientState(); et les constantes qui vont bien (GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, ...).
    Après le rendu de l'objet, il faut penser à desactiver ces états (avec glDisableClientState()).

    Rendu
    Ensuite pour rendre tes polygones (TRIANGLE, QUAD ou autres) tu as au moins deux moyens :
    - rendu en prenant les sommets dans l'ordre avec glDrawArrays();
    - rendu en prenant les sommets dans un ordre défini par un tableau d'indice avec glDrawElements();


    Voilà comment ça se passe.
    Tu comprends donc que ta structure de donnée avec un tableau d'indice de normal n'est pas adaptée à un Vertex Array.

    En effet, puisque tu as 8 sommets, il te faut :
    - 8 coordonnées de sommets;
    - 8 coordonnées de normales.
    stockées en mémoire (entrelacée ou pas)
    - 1 tableau de N indices de 0 à 7 qui définit tes polygones.

    ps: un Vertex Buffer Object est un moyen de stocker les données en mémoire vidéo pour que le Vertex Array travaille directement sur la carte vidéo.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 351
    Points : 432
    Points
    432
    Par défaut
    Merci pour vos réponses. Effectivement ToTo13 n'avait pas bien saisi mon problème.

    Je sais afficher un cube , ou d'autres formes , ce n'est pas vraiment mon problème.
    J'utilise aussi les tableaux de vertex , je sais les activer et les appeller pour afficher le rendu.

    Ma structure n'est pas de moi . En faite j'essai de restituer la géométrie de l'exemple du fichier collada(un simple cube). Tous les fichiers collada sont basés sur le même principe.

    C'est a dire ca :
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    <geometry id="box" name="box">
          <mesh>
    	<source id="box-Pos">
    		<float_array id="box-Pos-array" count="24">
    			-0.5 0.5 0.5
    			0.5 0.5 0.5
    			-0.5 -0.5 0.5
    			0.5 -0.5 0.5
    			-0.5 0.5 -0.5
    			0.5 0.5 -0.5
    			-0.5 -0.5 -0.5
    			0.5 -0.5 -0.5
    		</float_array>
    		       <technique_common>
    		           <accessor source="#box-Pos-array" count="8" stride="3">
    				<param name="X" type="float" />
    				<param name="Y" type="float" />
    				<param name="Z" type="float" />
    			</accessor>
    			</technique_common>
    		</source>
    		<source id="box-0-Normal">
    		<float_array id="box-0-Normal-array" count="18">
    			1.0 0.0 0.0
    			-1.0 0.0 0.0
    			0.0 1.0 0.0
    			0.0 -1.0 0.0
    			0.0 0.0 1.0
    			0.0 0.0 -1.0
    		</float_array>
    		<technique_common>
    	<accessor source="#box-0-Normal-array" count="6" stride="3">
    				<param name="X" type="float"/>
    				<param name="Y" type="float"/>
    				<param name="Z" type="float"/>
    	</accessor>
    	</technique_common>
    	</source>
    	<vertices id="box-Vtx">
    		<input semantic="POSITION" source="#box-Pos"/>
    	</vertices>
    		<polygons count="6" material="WHITE">
    	<input semantic="VERTEX" source="#box-Vtx" offset="0"/>
    	<input semantic="NORMAL" source="#box-0-Normal" offset="1"/>
    	<p>0 4 2 4 3 4 1 4</p>
    	<p>0 2 1 2 5 2 4 2</p>
    	<p>6 3 7 3 3 3 2 3</p>
    	<p>0 1 4 1 6 1 2 1</p>
    	<p>3 0 7 0 5 0 1 0</p>
    	<p>5 5 7 5 6 5 4 5</p>
    	</polygons>
    </mesh>
    Mais mon soucis justement c'est que j'ai pas la structure que tu proposes :

    En effet, puisque tu as 8 sommets, il te faut :
    - 8 coordonnées de sommets;
    - 8 coordonnées de normales.
    stockées en mémoire (entrelacée ou pas)
    - 1 tableau de N indices de 0 à 7 qui définit tes polygones.
    Même constat pour un objet plus complexe par exemple:

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    <float_array id="F40tire-mesh-positions-array" count="2940">
    ....
     
    <accessor source="#F40tire-mesh-positions-array" count="980" stride="3">
                  <param name="X" type="float"/>
                  <param name="Y" type="float"/>
                  <param name="Z" type="float"/>
    ...
     
    <float_array id="F40tire-mesh-normals-array" count="5040">
    ...
    <accessor source="#F40tire-mesh-normals-array" count="1680" stride="3">
                  <param name="X" type="float"/>
                  <param name="Y" type="float"/>
                  <param name="Z" type="float"/>
     
    <float_array id="F40tire-mesh-map-channel1-array" count="5769">
    ...
    <accessor source="#F40tire-mesh-map-channel1-array" count="1923" stride="3">
                  <param name="S" type="float"/>
                  <param name="T" type="float"/>
                  <param name="P" type="float"/>
    ...
     
    <vertices id="F40tire-mesh-vertices">
       <input semantic="POSITION" source="#F40tire-mesh-positions"/>
    </vertices>
        <triangles material="F40tire" count="1680">
        <input semantic="VERTEX" source="#F40tire-mesh-vertices" offset="0"/>
        <input semantic="NORMAL" source="#F40tire-mesh-normals" offset="1"/>
        <input semantic="TEXCOORD" source="#F40tire-mesh-map-channel1" offset="2" set="1"/>
    <p>0 0 2 1 1 3 8 2 14 0 0 2 8 2 14 7 .....
    Et la on vois que le problème est le même :
    Un tableau de 980 vertex
    un tableau de 1680 normals
    un tableau de 1923 coordonnées de textures
    un tableau d'indices entrelacés (vertex,normal,coord) de 0 à 1679

    Et la c'est toute suite plus difficile pour arranger la géometrie afin de l'afficher correctement.

    Si la specification de Collada la choisie de cette manière c'est surement pour une bonne raison . (Group Khronos ceux qui gère aussi openGL)

    Pour éviter la redondance des infos afin que les fichiers soit moins gros.

    Si les données doivent etre restituées grâce à un tableau d'indices entrelacés, je me dit qu'ils ont surement prévus un mécanisme dans openGL pour traiter les données de cette manière sans que l'on soit obligé de les modifier.

    Mais le problème c'est qu'aucun des tableaux n'a la même taille.

  6. #6
    Membre éclairé Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Points : 693
    Points
    693
    Par défaut
    Effectivement c'est sans doute pour la taille du fichier que Khronos à du choisir cette spécification.

    Mais a priori le seul moyen de passer par un vertex array, est d'effectuer une "décompression" (au chargement) pour ne garder des indices que pour les sommets, et plus pour les informations des sommets.

    Si tu utilises GLSL, peut être que tu pourrais envoyer les indices directement dans le vertex array, et envoyer les tableaux d'informations correspondantes dans des uniforms à ton vertex shader. Cependant je ne crois pas que ce soit terrible niveau performances.


    Cependant il y a un truc que je ne comprends pas: comment sur un objet qui possède 980 sommets différents, il peut avoir 1680 normales différentes?
    Normalement il ne peut y avoir qu'une normale par sommets...

    A moins que ce fichier collada définisse plusieurs objets différents qui partagent certains sommets, mais pas forcément les même normales à ces sommets?

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Mars 2005
    Messages : 249
    Points : 349
    Points
    349
    Par défaut
    Regarde un peu ce lien, ça pourrait t'intéresser : http://www.blitzbasic.com/Community/...hp?topic=47065 (c'est pas en C++ mais les fonctions gl seront les mêmes)

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 351
    Points : 432
    Points
    432
    Par défaut
    Merci pour le lien (c'est pas grave je travail en java )

    Oui effectivement, le fichier est composé de nombreux objets.
    C'est constitué comme ça :

    Pour une voiture par exemple , il décompose en sous-objet , chassis, roue, volant, vitre ec ...

    Et chaque sous objet est definis comme plus haut , c'est a dire vertex,normals,coord et les indices entrelacés.Chaque sous objet à son propre tableau d'indice. Donc aucune réference vers les autres sommets des autres sous-objets.

    La raison me semble assez évidente(sous réserve que je fasse pas erreur), dans mon exemple l'objet en question s'appel "tire" je crois que ca veux dire roue. Donc un sommet va appartenir à plusieurs faces qui auront une orientation différente d'où plus de normales que de sommet.

    A la fin du fichier il ya la visual scène , ce sont les tranformations qui vont permettre de placer tous les sous objets afin de de représenter une voiture
    Les translations et rotations se font par rapport a l'origine pour la racine et par rapport a l'objet parent pour les autres.

    Mais bon c'est bien ça le problème je ne vois pas comment faire le rendu de la géométrie rapidement alors qu'aucun des tableaux n'a la même taille et qu'il peut avoir plus de normals que de vertex ou des fois moins ...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 351
    Points : 432
    Points
    432
    Par défaut Help please.
    Up! Toujours pas résolu mon problème.

    80% des meshs ont ce problème avec le format collada :

    C'est à dire style pour un cylindre :

    la géométrie
    110 sommets
    146 vecteurs normals
    127 coordonnées de textures

    comment l'utiliser
    216 triangles soit 648 sommets
    tableau d'indices taille 1944 , il contient les indices pour les sommets , les normals et le coordonées de mapping(648*3 = 1944)
    offset vertex = 0
    offset normals = 1
    offset textCoord = 2

    J'ai cherché partout sur le net , apparement c'est impossible à utiliser comme ca dans openGL , il faut obligatoirement "décompresser".

    J'ai pensé à une solution simple avec un tableau entrelacé:
    Je décompresse toutes données pour les mettre tous dans le meme tableau.
    Mais les performances vont en patir je pense ....

    Comment procéderiez-vous dans un cas comme ca ?

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

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 2 574
    Points : 5 323
    Points
    5 323
    Par défaut
    c'est très simple : en openGL, pour les vertex array/buffer, un vertex, c'est un groupe {vertex, normale, texcoord, couleurs etc }, donc si tu veut utiliser des tableau d'indes, il faut forcement créer un tableau qui contient tes données géometriques sous cette forme.

    typiquement, dans ton cas, il va falloir créer une structure (ou plusieurs tableaux) qui, pour chaque vertex (au sens position 3D) contiendra les normales/texcoord correspondantes, toute la difficulté étant de ne pas dupliquer inutilement ces données.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 351
    Points : 432
    Points
    432
    Par défaut
    Oui j'ai bien compris que pour chaque vertex on regroupe (vertex,normal,coordonné de texture et couleur)

    En faite la structure du fichier collada est déja comme ca , et les modeleurs quand ils exportent dans ce format font attention a ne pas dupliquer les données.

    Et donc on a :

    tab de vertex
    tab de normal
    tab de textCoord

    tab d'indices

    Dans mon exemple si on avait :

    110 sommets
    110 normals
    110 textCoord

    et le tab d'indices à 216 aucun soucis.

    Mais le prob on a plus de normals et de de coordonnées de texture que de sommet. Et c'est pour ca que dans le fichier collada le tableau d'indices indique les redondances pour les normals et textcoords.

    tab indices comme ca : 0 (case 0 du tab vertex) 2 (case 2 du tab normals) 8 (case 8 du tab textures)

    je ressaye en ce moment , en ne gérant que les vertexs , et je prend uniquement les indices pour les vertex. Mais j'obtiens un ecran noir.

    Es qu'on peut utiliser drawElement() avec juste le tableau de vertex activer sans les normals ?

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

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 2 574
    Points : 5 323
    Points
    5 323
    Par défaut
    Citation Envoyé par Elendhil Voir le message
    Es qu'on peut utiliser drawElement() avec juste le tableau de vertex activer sans les normals ?
    oui

Discussions similaires

  1. Utiliser opengl 2.x avec opengl 3.x
    Par Awakening dans le forum OpenGL
    Réponses: 2
    Dernier message: 22/04/2012, 21h08
  2. Réponses: 9
    Dernier message: 15/01/2010, 16h43
  3. tri croissant avec tableau d'indices
    Par salseropom dans le forum C++
    Réponses: 2
    Dernier message: 11/09/2009, 07h39
  4. peut-on faire de l'ettiquetage avec OpenGL ?
    Par arakiri dans le forum OpenGL
    Réponses: 4
    Dernier message: 19/12/2006, 15h36

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