Partage
  • Partager sur Facebook
  • Partager sur Twitter

[openGL/SDL/...]Aider moi a la réalisation d'un importateur de fichier .obj

Peu- être un moteur 3D

    15 juillet 2007 à 16:42:32

    Salut a tous les zéros.

    Je suis nouveau sur ce forum, ça fait pas mal de temps que je surfe sur ce site que j'adore :D , je remercie tout ceux qui s'en occupe :) .

    Avant de commencer, je vais vous dire ou j'en suis au niveau programmation :euh: .
    Au début :D .
    Plus précisément.
    J'ai lu les tuto c/c++ de M@teo21 que je remercie énormément :D ,(enfin, je voulais voir à quoi que ça ressemble tout ça, sans l'intention de continuer, mais voila, s'était tellement bien écrit et expliqué que j'ai tout lu, maintenant, je ne peux plus m'en passer :-° ).
    Et puis, histoire de m'entrainer un peu, après, la lecture sur la SDL, j'ai voulu faire un petit jeu du snake ultrarévolutionnaire :p (si ça vous intéresse, il faut demander :) ).

    Et après, la 3D avec openGL, je remercie Kayl pour ces tuto.

    Des Bricoles à droite et à gauche.

    Et pour finir Quelques tutos des membres, que je remercie aussi :D .

    Et là, je crois que j'ai trouvé un deuxième M@teo21, surnommé Yno, que je remercie lui aussi énormément :D .
    Donc j'ai lu Rendus optimisés : DL, VA, VBOs.

    J'avais déjà réalisé une classe pour importer mes .obj (que j'ai fait avec blender :D ).
    Ca marche fonctionne \o/, mais pas terrible en fait :'( , quand il y a 2 textures, il y a une face qui ne s'affiche pas,(et en plus comme je trouve que je l'ai mal codée, comme tout ce que je code... :( ).

    J'ai décidé de me relancer dans l'ouverture de .obj.
    Mais cette fois je voudrais que ça soit bien codé et tout, alors s'est pour ça que j'ai besoin de votre aide charitable :D (surtout de votre expérience :p ).

    Je vais vous dire, mon avancement de mon importateur au fil des postes.
    Mais la je vais dire se que j'ai déjà fait, et s'est là, qu'il me faudrai une âme charitable :) qui me dise si s'est bien ou pas :) .

    Allé je me lance.

    En premier, il faut que je vous dise, que je vais essayer, de faire ce petit importateur, en parcourant en une seul fois le fichier .obj, pour minimiser le temps de chargement (enfin je pense que ça va le minimiser, mais je ne suis pas sûr :-° ).

    Donc je me suis fait une petite classe "objetChaine3D" qui va en fait gérer des éléments 3d (pour le moment se sont mes vertex).

    Si vous voulez du code, faut demander :D .
    Le but principale de cette classe et de relever les 3 valeurs (x, y, z) de mes vertex (pour le moment), au fil du défilement dans le fichier.
    Et après, une fois que le défilement et fini, on renvoie toutes les valeurs dans un tableau.

    Vous vous doutez surement, j'ai l'intention d'utiliser les VBOs :) .
    Mais pour le moment, j'en suis qu'a ma période de test.

    J'ai introduit ma classe "objetChaine3D" dans le constructeur d'une autre classe "mesh_obj".
    Son constructeur va enfette appeler une méthode.

    std::string chargementMesh(const std::string nomFichierMesh);
     


    Elle retourne un string, mais là, il faut que je vois, par la suite, si je modifie ça, où pas (j'avais l'idée de mettre tout le contenu du fichier .obj dans se string), mais avec mon "objetChaine3D" j'en ai pas besoin (enfin, pour le moment avec mes vertex).

    Et s'est dans cette méthode que je déclare ma classe "objetChaine3D".
    Je parcours mon fichier comme ça.

        while(fichier >> contenuFichier)
        {
            if(contenuFichier == "v")
            {
                fichier >> temporaire.x >> temporaire.y >> temporaire.z;

                if(m_nombreVertex == 0)
                {
                    donneeVertex.racineEdit(temporaire.x, temporaire.y, temporaire.z);
                }
                else
                {
                    donneeVertex.ajouter(temporaire.x, temporaire.y, temporaire.z);
                }

                m_nombreVertex++;
            }
        }
     


    "temporaire" et en fait un element3D qui me sert pour ma classe "objetChaine3D".
    Si "m_nombreVertex" = 0, alors on va éditer le premier "element3D" de la casse "objetChaine3D", qui a été créé lors de la création de l'objet, sinon on rajoute un "element3D" à la classe "objetChaine3D".
    Lorsque "contenuFichier" = "v" alors on met les 3 nombres suivant dans temporaire, pour ajouter correctement un "element3D" a ma classe "objetChaine3D".

    Mais là, j'ai un problème o_O .
    Une fois que j'ai fini de parcourir le fichier, que toutes les valeurs on bien étaient rentrées dans ma classe "objetChaine3D", je renvoie toutes les données dans un tableau.
    Je me suis fait une petite fonction provisoire, pour voir si ça marche bien :) , qui va afficher dans la console toutes les valeurs du tableau.
    Et s'est là, que ça ne va pas, ça me fait des arrondis que je ne veux pas.
    Voila une ligne d'un vertex.

    v -2.365669 0.400558 0.270156


    Et la console.

    -2.36567 : 0.400558 : 0.270156


    Bon là, se n'ai pas très très fla grand, mais dans d'autre cas ça peut s'avérer gênant.
    Comment remédier a ce problème ?


    Voila à peu pré ou j'en suis dans mon importateur :) .

    J'ai volontairement choisi de ne pas mettre le code en entier, mais pour faciliter la compréhension je ne sais pas, si il fallait, mettre le code ou pas, alors si vous le voulez je le mettrais, mais il faut demander :) .
    De toute façon une fois que j'aurai fini je mettrais tout le code, pour ceux qui le veulent :) )

    J'ai quelques questions diverses.

    Comment transformer se code c en c++ ?

    fprintf(stderr,"test");

    Je ne sais pas si s'est passible.

    Il y a un truc qui me tracasse, j'ai lu Installer et découvrir les "nightly builds" de Code::Blocks de Nesquik69 que je remercie :D .
    Cool ce nouveau Code::Blocks, mais je ne comprends pas à quoi peu bien servir la console en mode debug (a part afficher le temps d'exécution ...).

    Je pense que j'aurai d'autres questions par la suite.


    En espérant que vous ayez bien compris ce que je vous demande.
    Je vous remercie aussi d'avance :) .

    Il y a surement des choses qui mon échappées.

    A oui j'oubliai, je vous remercie :D .

    Après avoir fini, peut être que je ferai un mini moteur 3D, à voir :-° .

    A bientôt.
    M
    • Partager sur Facebook
    • Partager sur Twitter
      15 juillet 2007 à 17:28:29

      Salut,

      J'avais fait un exporteur .obj -> mon format, puis un loader pour mon format, mais bon, niveau qualité du code c'est pas le top hein, mais bon ça fonctionne... :
      http://www.siteduzero.com/forum-83-90217-presentation-visualiseur-de-fichiers-3d.html

      Citation : culte

      Et là, je crois que j'ai trouvé un deuxième M@teo21, surnommé Yno, que je remercie lui aussi énormément :D .


      Merci :D

      Citation : culte

      je vais essayer, de faire ce petit importateur, en parcourant en une seul fois le fichier .obj, pour minimiser le temps de chargement (enfin je pense que ça va le minimiser, mais je ne suis pas sûr :-° ).


      Bof, à mon avis tu vas te faire ch*** pour pas grand chose... Il faut bien que tu connaisse la taille que fera ton tableau de vertices avant de l'allouer, parce que bon, une réallocation à chaque lecture d'un vertex je le sens mal... ça va être moche et lourd.

      Citation : culte

      Elle retourne un string, mais là, il faut que je vois, par la suite, si je modifie ça, où pas (j'avais l'idée de mettre tout le contenu du fichier .obj dans se string)


      C'est pas une très bonne idée, je te conseille de changer ça :-°

      Citation : culte

      Si vous voulez du code, faut demander :D .


      Ben sans code on ne peut pas trop t'aider. En même temps, sois prévenu : je ne fais pas de C++.

      En fait je suis en ce moment entrain d'écrire un tuto sur le chargement de meshs .obj, il avance doucement mais comme tu es déjà la seconde personne que ça arrengerait, ça va peut-être me motiver pour accélérer la rédaction du tuto.
      • Partager sur Facebook
      • Partager sur Twitter
        15 juillet 2007 à 18:47:48

        Citation : Yno

        J'avais fait un exporteur .obj -> mon format, puis un loader pour mon format, mais bon, niveau qualité du code c'est pas le top hein, mais bon ça fonctionne... :
        http://www.siteduzero.com/forum-83-90217-presentation-visualiseur-de-fichiers-3d.html



        J'y est déjà regardé :) mais je n'ai pas compris grand chose :( .

        Citation : Yno

        Merci :D


        De rien :D .

        Citation : Yno

        Bof, à mon avis tu vas te faire ch*** pour pas grand chose... Il faut bien que tu connaisse la taille que fera ton tableau de vertices avant de l'allouer, parce que bon, une réallocation à chaque lecture d'un vertex je le sens mal... ça va être moche et lourd.



        Je crois, que tu n'as pas bien tout compris, comment je procède.
        Je ne fais pas de réallocation à chaque fois que "contenuFichier" contient "v"
        Mais je vais juste ajouter un "element3D" à ma classe "objetChaine3D".
        Je me suis inspiré des listes chaînées de lexou que je remercie ;) .
        Mais s'est après une fois que toutes les valeurs on été lu dans le .obj, une fois que le fichier .obj et fermé, que je renvoie un tableau, qui a été alloué (je connais donc sa taille avec "m_nombreVertex" que je multiplie par 3).
        Et une fois que j'ai le tableau, je le traite avec les VBOs (que je n'ai pas encore fait),(Et s'est là, aussi que j'ai l'arrondi que je ne veux pas).

        Citation : Yno

        C'est pas une très bonne idée, je te conseille de changer ça :-°



        ok ok je vais supprimer :) .

        Citation : Yno

        Ben sans code on ne peut pas trop t'aider. En même temps, sois prévenu : je ne fais pas de C++.



        Pour le code ok, mais avant, il faut que je fasse des commentaires pour que vous compreniez.
        Mais pourquoi ne fais tu pas de c++ ?
        Moi je trouve ça, plus simple.

        Citation : Yno

        En fait je suis en ce moment entrain d'écrire un tuto sur le chargement de meshs .obj, il avance doucement mais comme tu es déjà la seconde personne que ça arrengerait, ça va peut-être me motiver pour accélérer la rédaction du tuto.



        aïïïï, Mon plafond, il est tombé :lol: .
        Je fais quoi, je continue ou j'attends ?
        Je suppose que ton tuto sera écrit en c, mais se n'est pas un problème je ferai mes trucs en c++ :D (je pari que tes fichiers .obj seront fait avec blender :D ).
        Je fais quoi ? J'attends ton tuto sur le obj, ou je continu mon truc, (en sachant que si j'attends, ce sujet sera mort, et ça ne servirait à rien que je poste mon code).

        @@++
        E
        • Partager sur Facebook
        • Partager sur Twitter
          15 juillet 2007 à 19:15:44

          Citation : culte

          Mais je vais juste ajouter un "element3D" à ma classe "objetChaine3D".


          Et cet "element3D", il va bien falloir que tu alloues de la mémoire pour lui... ?

          Citation : culte

          Je fais quoi ? J'attends ton tuto sur le obj, ou je continu mon truc, (en sachant que si j'attends, ce sujet sera mort, et ça ne servirait à rien que je poste mon code).



          Continue bien sûr ;) (et oui, il sera en C)

          Citation : culte

          Mais pourquoi ne fais tu pas de c++ ?
          Moi je trouve ça, plus simple.


          Bah c'est peut-être plus simple d'un côté, mais plus dur d'un autre.
          • Partager sur Facebook
          • Partager sur Twitter
            15 juillet 2007 à 19:31:11

            Citation : Yno

            Et cet "element3D", il va bien falloir que tu alloues de la mémoire pour lui... ?



            Eeee oui :honte: .

            Citation : Yno

            Continue bien sûr ;)



            Ok mais si tu dis:

            Citation : Yno

            une réallocation à chaque lecture d'un vertex je le sens mal... ça va être moche et lourd


            Autant que j'écrase tout (enfin le peu que j'ai fait :euh: ), pour recommencer d'une autre manière.

            ++

            R
            • Partager sur Facebook
            • Partager sur Twitter
              15 juillet 2007 à 19:59:15

              Citation : culte

              Autant que j'écrase tout (enfin le peu que j'ai fait :euh: ), pour recommencer d'une autre manière.


              Oui :D Bah tu viens demander de l'aide, tu en a (enfin j'espère :-° ), donc profites-en.
              • Partager sur Facebook
              • Partager sur Twitter
                15 juillet 2007 à 20:30:31

                Citation : Yno

                Oui :D Bah tu viens demander de l'aide, tu en a (enfin j'espère :-° ), donc profites-en.



                Mais ne t'inquiètes pas j'en profite pleinement, et je t'en remercie :D .
                En fait, j'attendais, s'il fallait bien que je l'écrase ou pas :) (bon, bas, a parement oui :D ).

                Mais je viens d'avoir une idée :p .
                Au lieu de l'écraser tout de suite, je vais la garder, et je vais donc me faire un autre code (que je vous ferai voir aussi ;) ).
                Et après je garderais celui qui et le plus rapide.

                Donc je code et je vous fais voir le code (mais peut-être pas aujourd'hui ;) ).

                ++
                C
                • Partager sur Facebook
                • Partager sur Twitter
                  16 juillet 2007 à 21:28:42

                  Me re voici :) .

                  Je me suis créé une nouvelle classe (il n'y a pas grand chose pour le moment).

                  Je suis tes conseils Yno ;) .

                  Donc, je parcours dans un premier temps le fichier pour savoir le nombre de vertex, je fais une allocation pour mon tableau de vertex, puis je re parcoure un fois le fichier pour sauvegarder les vertex, et là j'ai un problème :'(:'( .

                  voila mon code.

                  main.cpp
                  #include <iostream>

                  #include "mesh_obj.h"

                  using namespace std;

                  int main()
                  {
                      //Creation d'un objet "mesh_obj"
                      mesh_obj test("test.obj");

                      //On regarde si tout et "ok"
                      cout << test.getErreur() << endl;

                          return 0;
                  }
                   


                  mesh_obj.h
                  #ifndef MESH_OBJ_H_INCLUDED
                  #define MESH_OBJ_H_INCLUDED

                  struct mesh_obj
                  {
                      public:
                      mesh_obj(std::string nomFichierMeshObj);
                      ~mesh_obj();

                      std::string getErreur();

                      private:
                      void chargementMesh(std::string nomFichierMeshObj);
                      void comptage(std::ifstream &fichier);
                      void allocationsTableaux(std::string &nomFichierMeshObj);
                      void releverDonnee(std::ifstream &fichier);

                      //Ce "string" va stoker un message d'erreur, s'il y a une erreur, sinon il vaudra "ok"
                      std::string m_erreur;

                      //Des variables pour compter
                      unsigned int m_nombreVertex;
                      unsigned int m_nombreCoordTexture;
                      unsigned int m_nombreNormale;
                      unsigned int m_nombreFace;

                      //Les tableaux
                      double *m_vertex;
                      double *m_coordTexture;
                      double *m_normale;
                      unsigned int *m_indexFace;
                  };

                  #endif // MESH_OBJ_H_INCLUDED
                   


                  mesh_obj.cpp
                  #include <iostream>
                  #include <fstream>
                  #include <string>

                  #include "mesh_obj.h"

                  using namespace std;

                  mesh_obj::mesh_obj(string nomFichierMeshObj)
                  {
                      //Initialisation
                      m_erreur = "ok";

                      m_nombreVertex = 0;
                      m_nombreCoordTexture = 0;
                      m_nombreNormale = 0;
                      m_nombreFace = 0;

                      m_vertex = NULL;
                      m_coordTexture = NULL;
                      m_normale = NULL;
                      m_indexFace = NULL;

                      //Chargement du modèle 3D
                      chargementMesh(nomFichierMeshObj);
                  }

                  mesh_obj::~mesh_obj()
                  {
                      //On détruit tous les tableaux s'ils ont été créés
                      if(m_vertex != NULL)
                      delete[] m_vertex;

                      if(m_coordTexture != NULL)
                      delete[] m_coordTexture;

                      if(m_normale != NULL)
                      delete[] m_normale;

                      if(m_indexFace != NULL)
                      delete[] m_indexFace;
                  }

                  void mesh_obj::chargementMesh(string nomFichierMeshObj)
                  {
                      //Ouverture du fichier
                      ifstream fichier;
                      fichier.open(nomFichierMeshObj.c_str(), ios::in);
                      if(!fichier)
                      {
                          m_erreur = "Impossible d'ouvrir le fichier : " + nomFichierMeshObj;
                      }
                      else
                      {
                          //Si tout s'est bien passé, on arrive ici
                          comptage(fichier);
                          allocationsTableaux(nomFichierMeshObj);

                          //Si l'allocation des tableaux ont fonctionné
                          if(m_erreur == "ok")
                          {
                              releverDonnee(fichier);
                          }

                          fichier.close();
                      }
                  }

                  string mesh_obj::getErreur()
                  {
                      return m_erreur;
                  }

                  void mesh_obj::comptage(ifstream &fichier)
                  {
                      string contenu = "";

                      fichier.seekg(0, ios::beg);
                      while(fichier >> contenu )
                      {
                          if(contenu == "v")
                          m_nombreVertex++;
                      }
                      //On lit tout le fichier et à chaque fois que "contenu" contient "v" alors on  incrémente "m_nombreVertex"
                  }

                  void mesh_obj::allocationsTableaux(string &nomFichierMeshObj)
                  {
                      //Allocation des tableaux
                      if(m_nombreVertex != 0)
                      {
                          m_vertex = new double[m_nombreVertex*3];

                          if(m_vertex == NULL)
                          m_erreur = "Impossible d'allouer de la memoire pour les vertex du fichier : " + nomFichierMeshObj;
                      }
                      else
                      {
                          m_erreur = "Le contenue du fichier : " + nomFichierMeshObj + " : n'est pas valide en tant que .obj";
                      }
                  }

                  void mesh_obj::releverDonnee(ifstream &fichier)
                  {
                      string contenu = "";
                      unsigned int iV = 0;

                      //On se place au debut du fichier
                      fichier.seekg(0, ios::beg);
                      while(fichier >> contenu)
                      {
                          if(contenu == "v")
                          {
                              fichier >> m_vertex[iV];
                              iV++;
                              fichier >> m_vertex[iV];
                              iV++;
                              fichier >> m_vertex[iV];
                              iV++;
                          }
                      }
                      //On re parcourt tout le fichier, pour cette fois sauvegarder les données dans les tableaux

                      for(unsigned int i = 0; i < m_nombreVertex*3; i++)
                      {
                          cout << m_vertex[i] << " : ";
                          i++;
                          cout << m_vertex[i] << " : ";
                          i++;
                          cout << m_vertex[i] << endl;
                      }
                      //Le "for" est juste un test, pour voir si toutes les valeurs on bien été rentrées
                  }
                   


                  Mon fichier .obj
                  # Blender3D v244 OBJ File: 
                  # www.blender3d.org
                  v 1.000000 1.000000 -1.000000
                  v 1.000000 -1.000000 -1.000000
                  v -1.000000 -1.000000 -1.000000
                  v -1.000000 1.000000 -1.000000
                  v 1.000000 0.999999 1.000000
                  v 0.999999 -1.000001 1.000000
                  v -1.000000 -1.000000 1.000000
                  v -1.000000 1.000000 1.000000
                  vn 0.000000 1.000000 0.000000
                  vn -1.000000 0.000000 0.000000
                  vn 0.000000 -1.000000 0.000000
                  vn -0.000001 -1.000000 0.000000
                  vn 1.000000 0.000000 0.000000
                  vn 1.000000 -0.000001 0.000000
                  vn 0.000000 0.000000 1.000000
                  vn 0.000000 0.000000 -1.000000
                  usemtl (null)
                  usemtl (null)
                  s 1
                  f 5//1 1//1 4//1
                  f 5//1 4//1 8//1
                  f 3//2 7//2 4//2
                  f 7//2 8//2 4//2
                  f 2//3 6//3 3//3
                  f 6//4 7//4 3//4
                  f 1//5 5//5 2//5
                  f 5//6 6//6 2//6
                  f 5//7 8//7 6//7
                  f 8//7 7//7 6//7
                  f 1//8 2//8 3//8
                  f 1//8 3//8 4//8


                  Et pour finir ma console.
                  1.66712e-307 : 1.4822e-322 : 1.4822e-323
                  0 : 2.01499e-317 : 0
                  2.01499e-317 : 6.36599e-314 : 1.68168e-307
                  1.68168e-307 : 6.23035e-307 : 1.60216e-306
                  1.60219e-306 : 9.34613e-307 : 4.03295e-308
                  4.17201e-309 : 0 : 1.16467e-021
                  3.06321-322 : 1.16467e-021 : 8.34535e-309
                  9.71373e-319 : 1.32058e-312 : 1.32059e-312
                  ok


                  Ou là! il y a comme un problème :( .

                  J'ai fais quelques tests.
                  J'ai constaté que si j'enlevais la boucle "while" de "releverDonnee" j'obtenais le même résultat.

                  Remarquez ce passage.
                  //On se place au debut du fichier
                      fichier.seekg(0, ios::beg);


                  Je ne suis pas sûr que ça revient au début.

                  Avez vous une solution à se problème ?


                  En vous remerciant d'avance (encore et toujours :D )

                  ++
                  I
                  • Partager sur Facebook
                  • Partager sur Twitter
                    17 juillet 2007 à 13:57:39

                    A mon avis, dans ta fonction "releverDonnees", il faut mettre un while(std::getline()) pour récupérer toute la ligne d'un coup, et la traiter correctement après (vérifier que le 1er caractère est bien "v", qu'il y a bien 3 composantes, etc...)

                    Moi j'ai poussé à l'extrême: je parcours le fichier une seule fois. Pour chaque ligne recuperée, je regarde la première lettre, et suivant ce que c'est (v, vt, f, vn, etc) je la mets dans un vecteur correspondant. Ensuite je parcours le vecteur des faces ("f"), et je remplis un buffer avec les info qui correspondent dans les autres vecteurs.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      17 juillet 2007 à 18:35:21

                      Citation : Gravstein

                      A mon avis, dans ta fonction "releverDonnees", il faut mettre un while(std::getline()) pour récupérer toute la ligne d'un coup, et la traiter correctement après (vérifier que le 1er caractère est bien "v", qu'il y a bien 3 composantes, etc...)



                      Je pense que s'est plus facile comme j'ai fait(mais ça ne marche pas :( ).
                      Mais quand tu dis :

                      Citation : Gravstein

                      pour récupérer toute la ligne d'un coup


                      Pour mes fichiers obj (exportés avec blender) il n'y a pas de problèmes, je vais faire ce que tu viens de dire :) .
                      Il n'y a pas si longtemps que ça, j'ai vu un fichier obj qui ne revient pas à la ligne, après le "V" et ses 3 composantes, dans ce cas, ta méthode ne fonctionne pas, mais bon, je fais mes modèles avec blender, il n'y a donc pas de souci.

                      Citation : Gravstein

                      Moi j'ai poussé à l'extrême: je parcours le fichier une seule fois. Pour chaque ligne recuperée, je regarde la première lettre, et suivant ce que c'est (v, vt, f, vn, etc) je la mets dans un vecteur correspondant. Ensuite je parcours le vecteur des faces ("f"), et je remplis un buffer avec les info qui correspondent dans les autres vecteurs.


                      C'est en quelque sorte se que je voulais faire, mais on m'a conseillé de faire autrement.

                      Sinon j'avais l'idée de le faire caractère par caractère.

                      ++
                      • Partager sur Facebook
                      • Partager sur Twitter
                        31 juillet 2007 à 19:17:44

                        Me re voila :o

                        Suite à ma conversation avec neuneutrinos que je remercie.
                        J'ai trouvé se qui n'allait pas, j'ai donc continué ma classe :D .

                        Et je suis arrivé au VBOs :D .

                        Je ne vais pas donner trop de code, parce que je suis sûr ou pratiquement sûr qu'il n'y a pas grand monde qui a pris le temps de lire mon code, (en même temps, je les comprends :p ).

                        Alors voila, je procède comma ça :

                        J'ai créé une classe mesh_obj (ça, vous le savez déjà :lol: ).
                        Lors de la création d'un objet "mesh_obj", dans le constructeur, l'utilisateur indique obligatoirement le nom du fichier .obj à charger.

                        Ensuite j'ouvre donc ce fichier:
                        _ 1 / Je le parcours une première fois, pour compter le nombre de "v", "f", "vt", "vn" et "usemtl" pour les matériaux, (enfin je ne sais pas encore comment fonctionne les matériaux avec opengl, je me contente, que des textures).

                        Une fois que j'ai tout compté, je vais allouer des tableaux.
                        Si il y en a qui on du courage, voici le code :) .
                        void mesh_obj::allocationsTableaux(const string &nomFichierMeshObj)
                        {
                            //Allocation des tableaux
                            if(m_nombreVertex != 0)
                            {
                                m_vertex = new double[m_nombreVertex*3];
                                if(m_vertex == NULL)
                                m_erreur = "Impossible d'allouer de la memoire pour les vertex du fichier : " + nomFichierMeshObj;
                            }

                            if(m_nombreFace != 0)
                            {
                                m_indexFace = new unsigned int[m_nombreFace*3];
                                if(m_indexFace == NULL)
                                m_erreur = "Impossible d'allouer de la memoire pour les Faces du fichier : " + nomFichierMeshObj;
                            }

                            if(m_nombreVertex < 3 || m_nombreFace == 0)
                            {
                                m_erreur = "Le contenue du fichier : " + nomFichierMeshObj + " : n'est pas valide en tant que .obj";
                            }
                            else
                            {
                                //Si tout s'est bien passé, alors on peut allouer d'autre tableaux
                                if(m_nombreCoordTexture != 0)
                                {
                                    m_coordTexture = new double[m_nombreCoordTexture*2];
                                    if(m_coordTexture == NULL)
                                    m_erreur = "Impossible d'allouer de la memoire pour les Coordonnés Textures du fichier : " + nomFichierMeshObj;

                                    m_indexTexture = new unsigned int[m_nombreFace*3];
                                    if(m_indexTexture == NULL)
                                    m_erreur = "Impossible d'allouer de la memoire pour les Index Texture du fichier : " + nomFichierMeshObj;
                                }

                                if(m_nombreNormale != 0)
                                {
                                    m_normale = new double[m_nombreNormale*3];
                                    if(m_normale == NULL)
                                    m_erreur = "Impossible d'allouer de la memoire pour les Normales du fichier : " + nomFichierMeshObj;

                                    m_indexNormale = new unsigned int[m_nombreFace];
                                    if(m_indexNormale == NULL)
                                    m_erreur = "Impossible d'allouer de la memoire pour les Index Normale du fichier : " + nomFichierMeshObj;
                                }

                                if(m_nombreMaterieau != 0)
                                {
                                    m_materieau = new string[m_nombreMaterieau];
                                    if(m_materieau == NULL)
                                    m_erreur = "Impossible d'allouer de la memoire pour les Materieaux du fichier : " + nomFichierMeshObj;

                                    m_nombreFaceTexture = new unsigned int[m_nombreMaterieau];
                                    if(m_nombreFaceTexture == NULL)
                                    m_erreur = "Impossible d'allouer de la memoire pour Nombre Face Texture du fichier : " + nomFichierMeshObj;

                                    m_textures = new GLuint*[m_nombreMaterieau];
                                    if(m_textures == NULL)
                                    m_erreur = "Impossible d'allouer de la memoire pour les Textures du fichier : " + nomFichierMeshObj;
                                }
                            }
                        }
                         


                        Pour un fichier obj, le minimum d'un modèle 3d, s'est d'avoir au moins une face et donc 3 sommets.
                        Après j'alloue des tableaux facultatif, dont les normales et les index normales, et aussi le nom des textures, le nombre de face à soumettre avec les textures (exemple : les 3 premières faces sont avec la texture 0, les 5 suivantes avec la texture 1 ...), et enfin, un tableau de pointeur sur les textures opengl.
                        Pourquoi un tableau de pointeur?
                        C'est pour que l'utilisateur gère lui même les textures, pour éviter les copies :D .

                        _ 2 / Je re parcours mon fichier, si tout s'est bien passé au par avant.
                        Mais cette fois en mettent les valeurs dans mes tableaux tout frais alloué :D .
                        J'obtiens :
                        Un tableau, de vertex, plein.
                        Un tableau, de face, plein.

                        Si, il y a des textures j'obtiens :
                        Un tableau, de nom des textures, plein.
                        Un tableau, de position des textures (vt), plein.
                        Un tableau, d'index de texture (comme pour les faces), plein.
                        Un tableau, un peu particulier, la case 0 contient le nombre de face à affecter avec la case 0 des textures, et s'est pareil pour les autres cases.

                        Si, il y a des normales j'obtiens :
                        Un tableau, de normales, plein.
                        Un tableau, d'index normales, plein.

                        Et je ferme enfin le fichier obj :) .
                        Si tout s'est bien passé, alors j'appelle une méthode pour organiser toutes ces données, enfin, juste pour les normales et les textures, s'il y en a ;) .
                        Car je ne sais pas, comment faire pour gérer les tableaux d'index de texture et normale avec les VBOs :( .

                        (Je vais me contenter que des textures pour le moment)
                        Donc je crée un nouveau tableau que j'alloue :) .
                        Ensuite avec mon tableau de "m_coordTexture" (vt) et mon tableau de "m_indexTexture"(qui ont été pris dans les lignes des faces), je remplis mon nouveau tableau, (exemple : m_indexTexture[0] si ceci est égal à 2, alors là, ça va remplir le nouveau tableau des valeurs de la case 2 du tableau
                        "m_coordTexture" (vt).
                        Pas très claire hun.
                        if(m_indexTexture != NULL)
                            {
                                m_coordTextureOrganiser = new double[m_nombreFace*3*2];
                                if(m_coordTextureOrganiser == NULL)
                                m_erreur = "Impossible d'allouer de la memoire pour les Coordonnés Textures Organiser du fichier : " + nomFichierMeshObj;
                                else
                                {
                                    unsigned int y = 0;
                                    for(unsigned int i = 0; i != m_nombreFace*3; i++)
                                    {
                                        m_coordTextureOrganiser[y] = m_coordTexture[m_indexTexture[i]*2];
                                        y++;
                                        m_coordTextureOrganiser[y] = m_coordTexture[m_indexTexture[i]*2+1];
                                        y++;
                                    }
                                }
                            }

                        Si ça peux vous édai a comprendre.

                        Ensuit jallou mais tableaux de VBOs.
                        void mesh_obj::AllocationVBOs()
                        {
                            glGenBuffers(1, &m_vertexVBOs);
                            glGenBuffers(1, &m_indexFaceVBOs);

                            //allocation
                            glBindBuffer(GL_ARRAY_BUFFER, m_vertexVBOs);
                            glBufferData(GL_ARRAY_BUFFER, m_nombreVertex*3*sizeof(double), m_vertex, GL_STREAM_DRAW);
                            glVertexPointer(3, GL_DOUBLE, 0, 0);

                            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexFaceVBOs);
                            glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_nombreFace*3*sizeof(unsigned int), m_indexFace, GL_STREAM_DRAW);

                            if(m_coordTextureOrganiser != NULL)
                            {
                                glGenBuffers(1, &m_textureVBOs);

                                glBindBuffer(GL_ARRAY_BUFFER, m_textureVBOs);
                                glBufferData(GL_ARRAY_BUFFER, m_nombreCoordTexture*2*sizeof(double), m_coordTextureOrganiser, GL_STREAM_DRAW);
                                glTexCoordPointer(2, GL_DOUBLE, 0, 0);
                            }

                            glBindBuffer(GL_ARRAY_BUFFER, 0);
                            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
                        }


                        Donc, pour le moment pas trop trop de souci :D .

                        Et pour finir, l'utilisateur doit demander à l'objet de créer un rendu, si il veut voir son modèle 3D à l'écran.
                        void mesh_obj::rendu(GLenum mode)
                        {
                            glEnableClientState(GL_VERTEX_ARRAY);

                            if(m_coordTextureOrganiser != NULL)
                            glEnableClientState(GL_TEXTURE_COORD_ARRAY);

                            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexFaceVBOs);

                            if(m_nombreMaterieau != 0)
                            {
                                int y = 0;
                                for(int i = 0; i != m_nombreMaterieau; i++)
                                {
                                    glBindTexture(GL_TEXTURE_2D, *m_textures[i]);
                                    glDrawElements(mode, m_nombreFaceTexture[i]*3, GL_UNSIGNED_INT, (char*)NULL + (sizeof*m_indexFace*y*3));

                                    y += m_nombreFaceTexture[i];
                                }
                            }
                            else
                            glDrawElements(mode, m_nombreFace*3, GL_UNSIGNED_INT, 0);

                            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
                            glBindTexture(GL_TEXTURE_2D, 0);

                            glDisableClientState(GL_VERTEX_ARRAY);

                            if(m_coordTextureOrganiser != NULL)
                            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                        }


                        Voyons voir se que j'obtiens.
                        Voila se que j'ai fait dans blender.
                        Ca donne:
                        Image utilisateur
                        Et
                        Image utilisateur

                        Puis dans mon application j'obtiens.
                        Image utilisateur
                        Et
                        Image utilisateur

                        Il y a des soucis là :( .
                        J'ai bien vérifié mon tableau "m_coordTextureOrganiser" mais ça ne vient pas de là, s'est tout correct, les valeurs sont bien à la bonne place.

                        Y a t'il quelqu'un qui saurait résoudre ce problème.
                        En le remerciant d'avance.

                        Si vous avez besoin de plus d'explication sur le code apporté ...

                        @@++
                        • Partager sur Facebook
                        • Partager sur Twitter
                          1 août 2007 à 9:49:42

                          Essaye sans les VBOs pour voir si tu ne t'es pas planté dans le chargement.
                          Je crois qu'il y a aussi un problème de Z-buffer. (mais je suis pas sûr, ça peut être des déformations de textures aussi)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            1 août 2007 à 10:42:01

                            Petite chose qui n'a rien à voir avec ton problème, mais qui peut t'être utile : les exceptions. Pourquoi ne pas les utiliser pour gérer tes erreurs ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                              1 août 2007 à 11:52:31

                              Citation : culte


                              void mesh_obj::AllocationVBOs()
                              {
                                  [...]
                                  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexFaceVBOs);
                                  glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_nombreFace*3*sizeof(unsigned int), m_indexFace, GL_STREAM_DRAW);
                                  [...]
                              }

                              Hum, je ne sais pas d'où tu sors ton tableau d'indices dans la mesure où un fichier OBJ n'en contient pas, en tout cas pas des indices utilisables directement de cette façon.
                              Les indices des fichiers OBJs sont différents pour chaque type de donnée (normale, position, etc...), il faut donc créer les sommets définitifs de ton mesh avec ces indices, pour ensuite pouvoir les afficher, et sans indices (càd avec glDrawArrays()).
                              • Partager sur Facebook
                              • Partager sur Twitter
                                1 août 2007 à 14:27:54

                                Merci de vaus réponses ^^ .

                                Pole -> Je suis entrain de créer une méthode pour ne pas utiliser les VBOs.
                                Pour le Z-buffer, dans le main, j'ai bien mis glEnable(GL_DEPTH_TEST); après la création de la fenêtre et glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); à chaque tour de boucle.

                                Elrond -> Je ne sais pas se que sont les exceptions, alors j'ai fait une petite recherche j'ai trouvé des choses intéressantes, mais je verrais ça de plus prés, une fois que j'aurais fini ma nouvelle méthode.

                                Yno -> Mon tableau d'indices vient :
                                Voila une face de mon fichier obj.
                                f 5/1/1 8/2/1 7/3/1
                                Enfaite je rempli mon tableau comme ça :
                                Je prends les premières valeurs, celles qui correspondent aux points (5, 8, 7).
                                Et je décrémente ces valeurs, parce que les tableaux commencent à la case 0.
                                Et voila mon tableau d'indice, est rempli.
                                Je ne sais pas si j'ai été bien claire.

                                Citation : Yno

                                il faut donc créer les sommets définitifs de ton mesh avec ces indices, pour ensuite pouvoir les afficher, et sans indices (càd avec glDrawArrays())


                                Ha ok, comme j'ai fait pour mes textures et mes normales :D , je fais pareil avec mes vertex.
                                Mais ça va faire des copies de vertex, se n'est pas mieux, de faire avec le tableau d'indice, et donc avec glDrawElements(); ?

                                En attendant je poursuis ma nouvelle méthode sans les VBOs.

                                ++
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  1 août 2007 à 18:23:13

                                  C'est precisement de la que vient ton erreur: Avec la manière que t'a choisi, il te faudrait un tableau d'indice par stream (position, normale, couleur, uv, etc.).

                                  Comme l'a dit Yno, tu peux faire comme ca. Le plus simple, c'est que tu remplisses UN seul VBO, interleaved, et ensuite que tu actives tous les ClientState avec le meme buffer, mais avec des strides differents. C'est le plus simple.
                                  Avec ce que te sorts Blender (ou plutot: le format .obj), c'est difficile de faire mieux. Et si tu reflechis, tu remarques en fait que 99.9% des vertices sont differents! (En considerent qu'un vertex, c'est pas juste une position, mais bien plus: position+couleur+normale+...) Deja, pour le cas du cube, si tu actives les normales sans smooth, ya pas 2 vertices identiques. Ensuite, si tu ajoutes les coordonnées de textures, la facon meme de plaquer ta texture t'empechera de faire des optimisations.

                                  Donc en gros, l'idee des IndiceBuffer est pas mauvaises, mais en pratique, c'est vraiment pas facil a utiliser pour voir un veritable gain de performances.

                                  Si tu veux rendre un terrain (c-t-d un grand quad, avec une resolution fixe, genre 1000x1000 vertex) tu peux utiliser le cas particulier et optimiser un poil. Mais pour des mesh complexes et qui forment des volumes fermé, c'est pas évident. Peut-etre qu'il existes des algorithme qui permette d'optimiser ca, mais je pense pas que ca vaille vraiment la peine de se casser la tete. (ou en tout cas dans un premier temps)
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    2 août 2007 à 0:28:38

                                    Citation : culte

                                    Mon tableau d'indices vient :
                                    Voila une face de mon fichier obj.
                                    f 5/1/1 8/2/1 7/3/1
                                    Enfaite je rempli mon tableau comme ça :
                                    Je prends les premières valeurs, celles qui correspondent aux points (5, 8, 7).
                                    Et je décrémente ces valeurs, parce que les tableaux commencent à la case 0.
                                    Et voila mon tableau d'indice, est rempli.
                                    Je ne sais pas si j'ai été bien claire.


                                    Tu as été très clair, et ce que j'essaye de te dire, c'est justement de ne PAS faire comme ça. Ce n'est pas un vrai tableau d'indices, ce sont des indices certes, mais différents pour chaque type de donnée (normale, position, texcoord) comme je te l'ai dit, donc inutilisables avec OpenGL ; car nous on veut des indices de sommet, et non des indices de donnée de sommet.

                                    Si tu vas jeter un oeil à mon loader (dont le code est illisible mais bon...) tu verras que j'ai créé un petit algo pour générer de vrais indices.

                                    Citation : culte

                                    Mais ça va faire des copies de vertex, se n'est pas mieux, de faire avec le tableau d'indice, et donc avec glDrawElements(); ?


                                    Tant pis pour la copie, tu ne perds pas trop de performances. Et sur un cube, tu ne peux qu'en gagner (tous les sommets sont différents).
                                    Mais il est vrai que dans la plupart des cas, l'utilisation d'indices est préférable.

                                    Citation : Pole

                                    Je crois qu'il y a aussi un problème de Z-buffer.


                                    Il faut vraiment y aller de bon cœur pour avoir du Z-fight sur un cube, non ? :D (ça me rappelle quelqu'un qui voulait assigner des LODs à un cube)

                                    Citation : Gravstein

                                    Le plus simple, c'est que tu remplisses UN seul VBO, interleaved, et ensuite que tu actives tous les ClientState avec le meme buffer, mais avec des strides differents. C'est le plus simple.


                                    Je déconseille personnellement l'utilisation des tableaux entrelacés mais bon... Et puis c'est pas forcément plus simple, les strides on s'y perd vite (si on a pas trop l'habitude).

                                    Citation : Gravstein

                                    Et si tu reflechis, tu remarques en fait que 99.9% des vertices sont differents!


                                    Euh, hum, pas du tout. Tu prends une sphere composée de triangles, par exemple : chaque sommet est utilisé par 5 triangles.
                                    De plus, l'utilisation d'indices permet d'exploiter le cache vertex de la carte graphique, et puis il vaut mieux dupliquer un entier (même sur 32 bits) qu'un sommet (plusieurs vecteurs de flottants).

                                    Citation : Gravstein

                                    Si tu veux rendre un terrain (c-t-d un grand quad, avec une resolution fixe, genre 1000x1000 vertex) tu peux utiliser le cas particulier et optimiser un poil.


                                    Dans le cas d'un mesh statique, il faut préférer avant tout les display lists.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      2 août 2007 à 14:16:01

                                      J'ai fini ma méthode sans les VBOs, et puis ça fonctionne ^^ .

                                      Citation : Yno

                                      Tu as été très clair, et ce que j'essaye de te dire, c'est justement de ne PAS faire comme ça. Ce n'est pas un vrai tableau d'indices, ce sont des indices certes, mais différents pour chaque type de donnée (normale, position, texcoord) comme je te l'ai dit, donc inutilisables avec OpenGL ; car nous on veut des indices de sommet, et non des indices de donnée de sommet.


                                      Ok, donc, de toute façon je suis obligé de les relever (indices de donnée de sommet) pour faire un tableau bien organisé (c'est ce que j'ai fait :p , et j'obtiens un tableau "m_verticesOrganiser" ^^ ), qui met bien mes vertices dons le bon ordre, en fonction de mon tableau qui contient les indices des faces (f)(m_indexFace, je devrai plutôt le nommer m_indexVertices, mais je verrai plus tard).

                                      Je ne comprends pas trop la différence entre "indice de sommet" et "indice de donnée de sommet"?
                                      Parce que, pour moi s'est la même chose et au début, sur mon poste avec les images, j'avais fait comme ce que Yno, m'a dit de ne pas faire :-° , et sa fonctionne, alors s'est pour ça, je ne comprends pas trop.

                                      Citation : Yno

                                      Si tu vas jeter un oeil à mon loader (dont le code est illisible mais bon...) tu verras que j'ai créé un petit algo pour générer de vrais indices.


                                      Je ne me suis pas encore trop penché sur ton code, s'est déjà mieux coder, que mon code à moi :D .
                                      Je n'ai pas trouvé l'algo, je verrai ça plus tard.

                                      Citation : Yno

                                      Mais il est vrai que dans la plupart des cas, l'utilisation d'indices est préférable.


                                      Il me vient une idée :p , et si je faisais plusieurs méthodes de rendu pour que l'utilisateur choisisse son mode de rendu (rendu classique, rendu VBOs, rendu display lists).

                                      Citation : Yno

                                      Citation : Gravstein

                                      Le plus simple, c'est que tu remplisses UN seul VBO, interleaved, et ensuite que tu actives tous les ClientState avec le meme buffer, mais avec des strides differents. C'est le plus simple.


                                      Je déconseille personnellement l'utilisation des tableaux entrelacés mais bon... Et puis c'est pas forcément plus simple, les strides on s'y perd vite (si on a pas trop l'habitude).


                                      J'avais commencé à faire qu'un VBO, et ça fonctionne, donc je vais recommencer avec plusieurs VBO ;) .

                                      Et pour les copies de vertices.
                                      Pour un cube, au départ il y a 8 sommets, donc 8 vertices.
                                      Pour une simple face du cube, donc 4 vertices.
                                      Comme j'utilise le mode GL_TRIANGLES, il me fait un rendu avec 3 vertices.
                                      Donc pour ma face j'aurai dans mon tableau "m_verticesOrganiser" déjà 2 vertices dupliqués.
                                      Alors, il faut imaginer pour tout le cube et après pour des meshs un peu plus volumineux ^^ .

                                      Et donc je vais déjà faire ce que j'ai dit pour choisir plusieurs types de rendu et après je ferai avec les indices, enfin du moins si j'y arrive :euh: .

                                      ++
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        2 août 2007 à 22:01:38

                                        Citation : culte

                                        Je ne comprends pas trop la différence entre "indice de sommet" et "indice de donnée de sommet"?


                                        Un sommet est un ensemble de données diverses, cf ma définition d'un sommet ici :
                                        http://www.siteduzero.com/tuto-3-18395-1-les-vertex-arrays.html#ss_part_1

                                        Une donnée est un vecteur, composant un type de données d'un sommet (la position d'un sommet sont des données, sa normale aussi, sa couleur, etc... chacune de type différent : l'une c'est la couleur, l'autre la position, ...).
                                        Les indices des fichiers OBJ pointent sur une donnée, et non sur un sommet.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          3 août 2007 à 11:53:19

                                          >> Yno: D'accord, pour les cas particuliers genre sphere, cylindres et autres mesh facilement generable par un petit algorithm de 3 ligne. Dans le cas du .obj, il faut quand meme identifier chaque sommet de chaque face, et voir s'il n'existe pas deja... Si on prend un mesh de 60 000 vertices, ca fait mal... (avec une approche naive en O(n²)...) Mais peut-etre qu'il y a mieux.

                                          En fait, c'est pas le bon problème que j'avais en tete. Je me demandais comment faire pour trouver la sequance qui minimise les redondances avec un rendu du type TRIANGLES_STRIP, et non TRIANGLES_LIST. Si quelqu'un a une idée, faites-moi signe!

                                          Sinon, pour les display list, je suis pas trop pour, dans le sens ou je ne connais pas d'equivalant chez directX (dans le cas d'un portage éventuelle, ca peux compilquer les choses..). Mais pourquoi est-ce que c'est mieux que les VBO? Moi, les VBO ca me paraissait etre le saint-graal, l'outil universel. Non?
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            3 août 2007 à 20:35:11

                                            Citation : Gravstein

                                            >> Yno: D'accord, pour les cas particuliers genre sphere, cylindres et autres mesh facilement generable par un petit algorithm de 3 ligne. Dans le cas du .obj, il faut quand meme identifier chaque sommet de chaque face, et voir s'il n'existe pas deja... Si on prend un mesh de 60 000 vertices, ca fait mal... (avec une approche naive en O(n²)...) Mais peut-etre qu'il y a mieux.


                                            Oui, mon algo de génération est très lent (je pense que c'est optimisable, je verrai ça à l'occaz'), mais en principe on s'arrange pour obtenir un format déjà indexé (ou on se passe de l'indexation). Et puis il n'y a pas que les spheres qui disposent de beaucoup de doublons ; examines bien n'importe quel modèle &#59;&#41;

                                            Citation : Gravstein

                                            En fait, c'est pas le bon problème que j'avais en tete. Je me demandais comment faire pour trouver la sequance qui minimise les redondances avec un rendu du type TRIANGLES_STRIP, et non TRIANGLES_LIST. Si quelqu'un a une idée, faites-moi signe!


                                            Hum, je ne connais pas le gain (ou la perte) de performance dû à l'utilisation de ce mode de rendu, il y a certes moins de données à envoyer, cela peut paraître bénéfique au premier abord, mais je me demande s'il n'y a pas des hacks foireux en internes, qui font que ça revient finalement au même (ou pire)...
                                            Et je ne connais aucun algo pour les générer, ni aucun format de fichier qui les utilise. Bon pour l'algo, tu peux en faire un sans trop de difficultés, par contre après ses performances, hum... ça risque d'être moyen.

                                            Citation : Gravstein

                                            Sinon, pour les display list, je suis pas trop pour, dans le sens ou je ne connais pas d'equivalant chez directX (dans le cas d'un portage éventuelle, ca peux compilquer les choses..). Mais pourquoi est-ce que c'est mieux que les VBO? Moi, les VBO ca me paraissait etre le saint-graal, l'outil universel. Non?


                                            Non, ce n'est pas le saint-graal, les DL c'est vraiment le pied pour tout objet statique (càd sans animation par bones) :

                                            Mode Vertices FPS
                                            VBO 2000000~ 24~
                                            DL 2000000~ 95~

                                            Franchement, j'ai failli m'évanouir quand j'ai fait ce test, mais c'est la vérité. À savoir que je possède une 6600GT avec un AMD Sempron 2200+.

                                            Pour la combatibilité avec DX, effectivement ce dernier ne possède pas d'équivalent, mais dans le cadre d'un moteur 3D multi-APIs, il peut tout même être intéressant de proposer les DL lorsqu'aucune animation n'est détectée et que l'API choisie est OpenGL &#58;&#41;
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              30 août 2007 à 11:33:26

                                              Re salut tout le monde.
                                              Après avoir fait reposer tout ça, je m'y remet peu à peu :) .


                                              Je poursuis mon idée de laisser le choix à l'utilisateur de choisir son mode de rendu.

                                              J'avais déjà réalisé le rendu classique.
                                              Alors pour faire le rendu Display Lists, ça a été vite fait :D .

                                              Mais J'ai une question.

                                              Le format .obj n'est pas fait pour les animations.
                                              Donc, "Yno" si tu dis que "c'est vraiment le pied pour tout objet statique".
                                              Alors je me dis pourquoi je ferai une méthode pour un rendu VBO ?


                                              Et un autre truc aussi :D .
                                              J'ai fait quelques tests, et avec 504482 Vertices, donc même pas la moitié de 2000000.
                                              En rendu classique, j'obtiens dans les alentours de 7 FPS :'( .
                                              Et en rendu DL dans les alentours de 15 FPS :'( .
                                              Pourtant j'ai une 7900GS et AMD64 4200+.

                                              Voilà, je ne comprends pas cette aussi grande marge, entre mes tests et ceux de Yno.
                                              J'ai peut-être très mal codé alors :'( ?

                                              merci
                                              ++
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                30 août 2007 à 20:01:19

                                                Citation : culte

                                                pourquoi je ferai une méthode pour un rendu VBO ?


                                                Parce que les displays lists vont être supprimées de OpenGL 3.0 :-°
                                                Mais bon, d'une manière générale utiliser les VBOs c'est beaucoup plus flexible.

                                                Citation : culte

                                                J'ai fait quelques tests, et avec 504482 Vertices, donc même pas la moitié de 2000000.
                                                En rendu classique, j'obtiens dans les alentours de 7 FPS :'( .
                                                Et en rendu DL dans les alentours de 15 FPS :'( .
                                                Pourtant j'ai une 7900GS et AMD64 4200+.

                                                Voilà, je ne comprends pas cette aussi grande marge, entre mes tests et ceux de Yno.
                                                J'ai peut-être très mal codé alors :'( ?


                                                Peut-être :D Montres-nous le code de construction de la liste.
                                                Sinon, ta carte n'est peut être pas très optimisée pour les displays lists, vu que c'est plutôt une carte "nouvelle génération" par rapport à OpenGL 2.1.
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  30 août 2007 à 21:13:11

                                                  itch_code(this, 1, ''); return false;" class="code_lien_numerotation">Afficher / masquer les numéros de ligne
                                                  1. void mesh_obj::renduDisplayLists()
                                                  2. {
                                                  3.     glCallList(m_displayLists);
                                                  4. }


                                                  Voila pour le code.
                                                  ++div class="code2 cpp">
                                                  1. void mesh_obj::renduClassique(bool afficherTextures)
                                                  2. {
                                                  3.     unsigned int i = 0;
                                                  4.     unsigned int y = 0;
                                                  5.     unsigned int v = 0;
                                                  6.     unsigned int n = 0;
                                                  7.     /*if(m_coordTextureOrganiser != NULL && m_normaleOrganiser != NULL && afficherTextures == true)
                                                  8.     {
                                                  9.         for(int t = 0; t != m_nombreMaterieau; t++)
                                                  10.         {
                                                  11.             glBindTexture(GL_TEXTURE_2D, *m_textures[t]);
                                                  12.                 glBegin(m_mode);
                                                  13.                 y = 0;
                                                  14.                 while(y != m_nombreFaceTexture[t])
                                                  15.                 {
                                                  16.                     glNormal3d(m_normaleOrganiser[n], m_normaleOrganiser[n+1], m_normaleOrganiser[n+2]);
                                                  17.                     glTexCoord2d(m_coordTextureOrganiser[v],m_coordTextureOrganiser[v+1]);
                                                  18.                     glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  19.                     i += 3;
                                                  20.                     v += 2;
                                                  21.                     glTexCoord2d(m_coordTextureOrganiser[v],m_coordTextureOrganiser[v+1]);
                                                  22.                     glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  23.                     i += 3;
                                                  24.                     v += 2;
                                                  25.                     glTexCoord2d(m_coordTextureOrganiser[v],m_coordTextureOrganiser[v+1]);
                                                  26.                     glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  27.                     i += 3;
                                                  28.                     v += 2;
                                                  29.                     n += 3;
                                                  30.                     y++;
                                                  31.                 }
                                                  32.                 glEnd();
                                                  33.         }
                                                  34.         glBindTexture(GL_TEXTURE_2D, 0);
                                                  35.     }
                                                  36.     else if(m_coordTextureOrganiser != NULL && afficherTextures == true)
                                                  37.     {
                                                  38.         for(int t = 0; t != m_nombreMaterieau; t++)
                                                  39.         {
                                                  40.             glBindTexture(GL_TEXTURE_2D, *m_textures[t]);
                                                  41.                 glBegin(m_mode);
                                                  42.                 y = 0;
                                                  43.                 while(y != m_nombreFaceTexture[t])
                                                  44.                 {
                                                  45.                     glTexCoord2d(m_coordTextureOrganiser[v],m_coordTextureOrganiser[v+1]);
                                                  46.                     glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  47.                     i += 3;
                                                  48.                     v += 2;
                                                  49.                     glTexCoord2d(m_coordTextureOrganiser[v],m_coordTextureOrganiser[v+1]);
                                                  50.                     glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  51.                     i += 3;
                                                  52.                     v += 2;
                                                  53.                     glTexCoord2d(m_coordTextureOrganiser[v],m_coordTextureOrganiser[v+1]);
                                                  54.                     glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  55.                     i += 3;
                                                  56.                     v += 2;
                                                  57.                     y++;
                                                  58.                 }
                                                  59.                 glEnd();
                                                  60.         }
                                                  61.         glBindTexture(GL_TEXTURE_2D, 0);
                                                  62.     }
                                                  63.     else if(m_normaleOrganiser != NULL)
                                                  64.     {
                                                  65.         glBegin(m_mode);
                                                  66.         while(y != m_nombreFace)
                                                  67.         {
                                                  68.             glNormal3d(m_normaleOrganiser[n], m_normaleOrganiser[n+1], m_normaleOrganiser[n+2]);
                                                  69.             glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  70.             i += 3;
                                                  71.             glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  72.             i += 3;
                                                  73.             glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  74.             i += 3;
                                                  75.             n += 3;
                                                  76.             y++;
                                                  77.         }
                                                  78.         glEnd();
                                                  79.     }*/
                                                  80.     else
                                                  81.     {
                                                  82.         glBegin(m_mode);
                                                  83.         while(y != m_nombreFace)
                                                  84.         {
                                                  85.             glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  86.             i += 3;
                                                  87.             glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  88.             i += 3;
                                                  89.             glVertex3d(m_verticesOrganiser[i], m_verticesOrganiser[i+1], m_verticesOrganiser[i+2]);
                                                  90.             i += 3;
                                                  91.             n += 3;
                                                  92.             y++;
                                                  93.         }
                                                  94.         glEnd();
                                                  95.     }
                                                  96. }


                                                  Puis l'utilisateur va faire appel à cette méthode pour dire qu'il va utiliser les DL.
                                                  1. void mesh_obj::utiliserDisplayLists(bool afficherTextures)
                                                  2. {
                                                  3.     m_displayLists = glGenLists(1);
                                                  4.     if(m_displayLists == 0)
                                                  5.     {
                                                  6.         m_erreur = "erreur lors de la creation de la Display Liste";
                                                  7.     }
                                                  8.     else
                                                  9.     {
                                                  10.         glNewList(m_displayLists, GL_COMPILE);
                                                  11.         renduClassique(afficherTextures);
                                                  12.         glEndList();
                                                  13.     }
                                                  14. }


                                                  Et enfin le rendu.
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    30 août 2007 à 23:49:12

                                                    -Pourquoi ne pas faire les tests pour les normales/textures dans la boucle? Ca fait bien moins de code pour un mini ralentissement.
                                                    -Il faut mettre le bind texture juste avant le dessin et non pendant la création de la display list.
                                                    - Pour les performances, Vista?
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      3 septembre 2007 à 14:35:08

                                                      S'est encore moi ^^ .

                                                      Citation : Pole

                                                      Pourquoi ne pas faire les tests pour les normales/textures dans la boucle? Ca fait bien moins de code pour un mini ralentissement.


                                                      Eeeee, à vrai dire je ne sais pas trop. Mais si tu dis que cela ferais un mini ralentissement, je ne vais pas y toucher :) .

                                                      Citation : Pole

                                                      Il faut mettre le bind texture juste avant le dessin et non pendant la création de la display list.


                                                      Ha, ok je ne savais pas, mais dans ce cas, il va falloir que je crée une liste pour chaque texture.
                                                      Pourtant, se que j'ai fait, ça fonctionne. Je vais modifier tout ça :) .

                                                      Citation : Pole

                                                      Pour les performances, Vista?


                                                      Non, j'ai XP, mais je sais, j'avais vu sur un poste, qu'il y avait des problèmes avec openGL sous vista.


                                                      Bon ba, en fait j'ai bientôt fini mon importateur :D .
                                                      voila quelques images.
                                                      image 1
                                                      image 2

                                                      Le char, se n'est pas moi qui l'ai fait, je l'ai trouvé par ici.

                                                      Et j'ai refait quelques tests, avec 504482 Vertices.
                                                      Rendu classique, avec 7 FPS.
                                                      Image utilisateur

                                                      Rendu DL, avec 15 FPS.
                                                      Image utilisateur

                                                      Rendu VBOs, avec 12 FPS.
                                                      Image utilisateur

                                                      Il ne me reste plus qu'à modifier les DL comme Pole à dit, et après il va falloir que je me penche vers les fichiers .mtl, mais pas encore tout de suite, parce que je ne sais pas encore comment fonctionnent les matériaux avec openGL.

                                                      Et je me disais, dans blender pour lisser les faces, je clique sur "set smooth", alors je me demandais si il n'y avait pas une fonction openGL qui permettrait de faire la même chose, donc j'ai cherché un peu, mais je n'ai pas trouvé :'( .

                                                      ++

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        3 septembre 2007 à 22:50:33

                                                        Citation : culte

                                                        il va falloir que je crée une liste pour chaque texture.


                                                        Comment ça ? Ceci ne convient pas :

                                                        1. glBindTexture (GL_TEXTURE_2D, texid);
                                                        2. glCallList (list);
                                                        3. glBindTexture (GL_TEXTURE_2D, 0);

                                                        ?
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          4 septembre 2007 à 9:33:55

                                                          Peut-être qu'une mise à jour du driver ne ferait pas de mal?
                                                          (Pour 263 000 vertices, j'ai 3~4 FPS en DL)
                                                          (J'ai une Mobile Intel(R) 915GM/GMS, 910GML Express Chipset Family)
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            4 septembre 2007 à 9:41:36

                                                            263 000 vertex ? ça commence a faire ! Meme si normalement, c'est supportable par une carte graphique.
                                                            par contre, si tu as un PC portable, avec un chipset graphique qui partage la RAM, la tu n'as rien de bon sous le capot, et les 3-4 FPS s'expliquent.
                                                            Vérifie a tout hasard les drivers OpenGL, mais bon.

                                                            Il est a noter que 263 000 polygones, c'est violent quand meme (pour ta statue)
                                                            Le "modeleur moyen" modeleur est celui qui arrive a faire un tres joli modele
                                                            Le "tres bon modeleur" est celui qui arrive a faire, visuellement, un modele aussi joli, mais avec 10 fois moins de polygones :)
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                                                              4 septembre 2007 à 9:50:59

                                                              Mode Vertices FPS
                                                              VBO 2000000~ 24~
                                                              DL 2000000~ 95~


                                                              Quand je vois ça je suis deg même quand je sais que je suis sur un portable qui a plus de 3 ans avec une mémoire partagée avec la carte graphique. :(
                                                              Avec 8 fois moins de vertices, je vais 30 fois plus lentement :colere2:
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              [openGL/SDL/...]Aider moi a la réalisation d'un importateur de fichier .obj

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown