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 :

Exporter une animation Blender vers OpenGL


Sujet :

OpenGL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 29
    Points : 17
    Points
    17
    Par défaut Exporter une animation Blender vers OpenGL
    Bonjour,

    Je conçois des animations 3D avec Blender et j'aimerais les importer dans un programme OpenGL/SDL simple. Auriez-vous une idée/tuto/programme/lien permettant ou indiquant comment faire cela ?

    J'insiste bien sur le fait que je ne veux pas seulement importer des objets mais également pouvoir charger les animations/mouvements de ces objets. Pour l'instant j'ai envisagé un export des objets au format .obj ; ensuite il parait que Blender a la capacité de produire des scripts Python, qui j'imagine pouvoir utiliser pour "décrire" l'animation de l'objet. J'ai également vu le format VRML. Il semble qu'il permette de décrire un mouvement mais je n'en suis pas sur.

    Voilà, je suis donc preneur de tout renseignement pertinent sur le sujet.

    Merci de vos futures réponses et bonne journée.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 29
    Points : 17
    Points
    17
    Par défaut
    Bon.

    Suite à la lecture de cet article http://jeux.developpez.com/faq/3d/?p..._format_modele , à une meilleure prise en main de Blender et à plusieurs heures de recherches, j'ai identifié quelques pistes qui pourraient m'être utiles. Aussi je vous expose l'avancée de mon enquête et d'avance je vous remercie de m'indiquer tous les indices/impasses/trucs-à-savoir/tutoriaux/solutions que vous pourriez avoir en tête/

    D'abord je n'ai selectionné que les formats d'export proposé par Blender, proposant la gestion des animations, et pour lesquels il existe des lib permettant de les "parser". (J'essaie d'abord cela avant de coder mon propre parseur. J'aime le principe de réutilisation : à mon sens c'est plus propre et de toutes façons ce n'est pas l'objet du débat.)

    Voici certains des formats que j'ai identifiés :

    Collada
    Structure XML (donc j'aime bien).
    J'ai trouvé ce tuto http://www.everita.com/lightwave-col...-on-the-iphone mais il ne donne pas de solution pour gérer les animations.
    J'ai trouvé la lib OpenCOLLADA ( http://www.opencollada.org/ ) qui semble gérer les animations mais malheureusement ils ne proposent pas de version Linux (oui c'est encore une de mes contraintes).

    VRML
    Un format vieillissant (à mon sens) mais si ça marche bien je n'y vois aucun inconvénient.
    Il existe OpenVRML ( http://openvrml.org/ ). Malheureusement il n'existe pas de paquet .deb pour Ubuntu (mais ça à la limite je peux m'en arranger) et je ne sais pas si cette lib gère les animations.

    X3D
    Semble être un futur standard (donc j'aime bien, même si ce sera sans doute plus pour le Web).
    J'ai trouvé cette lib : http://libx3d.sourceforge.net/ mais elle ne semble plus trop maintenue.

    MD2
    Enfin j'ai trouvé un code de gestion du MD2 sur la page http://jeux.developpez.com/sources/opengl/?page=modeles . L'inconvénient de ce format est qu'il ne gère les animations que par "keyframes" et pas en "skeletal". Accessoirement j'obtiens une erreur de Blender quand j'exporte en MD2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      File "/home/test/.blender/scripts/blender/md2_export.py", line 152, in bevent
        save_md2(g_filename.val)
      File "/home/test/.blender/scripts/blender/md2_export.py", line 1257, in save_md2
        fill_md2(md2, mesh_obj)
      File "/home/test/.blender/scripts/blender/md2_export.py", line 807, in fill_md2
        tex_key=(uv_coord[0],uv_coord[1])
    UnboundLocalError: local variable 'uv_coord' referenced before assignment
    Libg3d
    J'ai également trouvé le couple libg3d / g3dviewer ( http://automagically.de/g3dviewer/ ). A priori il ne permet d'importer que les objets et pas les animations. Maintenant si quelqu'un pouvait me confirmer cela...


    Je continue mes recherches...

  3. #3
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    Bonjour, il existe également Open Asset Import libray (Assimp), une librairie Opensource qui gère une trentaine de formats (dont .blender)

    http://assimp.sourceforge.net/index.html


  4. #4
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut great
    Salut,

    Juste un simple merci pour ton lien coda_blank. Je ne connaissais pas cette librairie et elle est tout simplement géniale. Je n'ai pas encore trop approfondi mes recherches sur son utilisation mais je dois dire que pour le peu que j'ai vu c'est très prometteur :

    - simplicité d'installation et compilation.
    - très simple d'utilisation.
    - documents très bien détaillés. Exemple de code, info classe ....
    - simplicité d’implémentation avec opengl/ directx



    Tout simplement ce que je cherchais depuis un moment. Je ne comprends pas comment je n'ai pas pu la trouver avant ça m'aurait fait gagner un temps fou sur l'ensemble de mes projets persos à faire des pseudo-importers bien moins performants et bien moins complets. Je ne comprends pas vu l'efficacité de la librairie qu'elle n'apparaît pas (pas du tout même) dans les moteurs de recherche en fesant des recherches du type "librairy c/c++ importer 3D model" ou je ne sais pas quoi.

    D'ailleurs si un responsable de la section 2D-3D-Jeux à du temps pour regarder un peu cette lib et la valider. Je pense qu'elle a toute sa place dans la section OUTILS/BIBLIOTHÈQUES étant donné que tout projet 3D digne de ce nom se voit dans l'obligation de charger des models provenant d'au moins un logiciel de modélisation. Ou au moins la mentionner quelque part.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 29
    Points : 17
    Points
    17
    Par défaut
    @coda_blank,
    Merci infiniment pour le lien. Cela ressemble exactement à ce que je recherche.

    @Robxley,
    Je suis entièrement d'accord. J'ai fait les mêmes recherches et ne l'ai pas trouvée. Vu ses capacités j'estime que cette lib devrait être référencée sur ce site dans la section 2D - 3D - Jeux.
    Seul bémol pour moi : je n'ai pas trouvé d'exemple simple d'importation d'une animation. L'exemple SimpleOpenGL ( http://assimp.svn.sourceforge.net/vi.../SimpleOpenGL/ ) ne semble pas les gérer. J'ai testé avec le *.blend de ce personnage ( disponible ici : http://www.katsbits.com/files/md5/an...der-source.zip ) mais je n'obtiens pas le résultat escompté. Par conséquent si quelqu'un a une idée ou un tuto...

    Merci. :]

  6. #6
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Salut poliok,

    As-tu téléchargé la sdk qui se trouve sur le site et pas seulement le fichier.c SimpleOpenGL.c que tu présentes dans ton lien ? http://sourceforge.net/projects/assi...k.zip/download



    Sinon, pour ma part les quelques tests rapides que j'ai pu faire durant mon temps libre ne m'ont posés aucun souci pour une éventuelle utilisation dans mon projet avec une idée bien précise de ce dont j'ai besoin. C'est à dire l'importation d'objets au format wavefront .obj et collada principalement qui ont fonctionnait correctement pour ces formats. Après je dois dire que dans ton cas, pour des objets animés, je ne peux pas trop me prononcer n'ayant fait aucun test valable dans cette optique.

    Peut être si ce n'est que le format collada qui peut contenir aussi une partie animation a à première vu un bon comportement ne serait-ce que pour la partie statique, donc peut être il en ai de même pour le dynamique.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2010
    Messages : 96
    Points : 72
    Points
    72
    Par défaut
    Bonjour tout le monde

    J'ai decouvert il y a de sa 3 jours la fameuse bibliotheque "ASSIMP" que je dois avouer est suberbe, simple à installer et apperement complete sans oublier qu'elle est parfaitement monté pour travailler avec opengl .

    Le hic c'est que je suis bloqué pour afficher le rendu de l'objet.
    J'ai réussi à exporter mon projet " Blender " sous format .mesh avec l'exporteur oracle puis le l'importer dans mon programme comme structure/objet ,avec la fonction [ aiImportFile ] puis de recuper [aiScene decor] après je n'ai aucune idée comment faire pour afficher le resutat sous forme graphique !!

    Je ne sais si plusieurs personnes sont bloqué à ce stade comme moi, cependant je post ce prôbleme pour moi ainsi que plusieurs amis qui n'arrivent pas plus loin..
    Malgré les bonnes explications donné sur les differentes fonctions que propose la librairie assimp je ne sais pas laquelle utiliser
    http://translate.google.com/translat...ogle.com&twu=1

    Si quelqun a deja réussi à importer son projet et de l'ouvrir/afficher graphiquement quelque chose sur sa fenetre, je lui en serait très reconnaissant de la faire partager

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 29
    Points : 17
    Points
    17
    Par défaut
    @Robxley,
    J'ai bien téléchargé le SDK. Maintenant j'en ai discuté avec un membre de l'équipe d'Assimp : l'import d'animations en *.blend n'est pas encore géré. A priori je dois effectivement me tourner vers les fichiers Collada. Ça n'a pas l'air simple et un tutoriel sur "comment importer et afficher une animation Collada en 20 lignes avec Assimp" me manque... Mais j'ai vu 2-3 trucs sur le forum qui pourraient m'aider.

    Je tiens au courant, et si en attendant quelqu'un veut se lancer : qu'il/elle n'hésite pas!

  9. #9
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    j'imagine que quelqu'un a déjà jeté un coup d'oeil à des liens

    je les reposte au cas ou :

    http://assimp.sourceforge.net/lib_html/usage.html
    http://assimp.sourceforge.net/lib_ht...ter_notes.html

  10. #10
    Membre régulier
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2010
    Messages : 96
    Points : 72
    Points
    72
    Par défaut
    Oui Coda_blank justement j'ai utiliser ce type de model pour importer..
    Mais cependant qu'en faire après ?
    Y a t-il une fonction special qui permet de lire les positions de la structure aiScene que j'ai créer ?

    Voici l'importateur que j'ai utiliser , après je ne sais pas quoi faire...snif

    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
    #include <iostream>
    #include < assimp.h > // C + + importateur interface
    #include < aiScene.h > // / / sortie des données de structure
    #include < aiPostProcess.h > // Post processing flags / / drapeaux de traitement du courrier
     
    bool Importer(const char * pfile)
    { 
      // Create an instance of the Importer class / / Création d'une instance de la classe de l'importateur
     
     
      // And have it read the given file with some example postprocessing / / Et l'ai lu le fichier donné avec quelques exemples de post-traitement
      // Usually - if speed is not the most important aspect for you - you'll / / En général - si la vitesse n'est pas l'aspect le plus important pour vous - vous
      // propably to request more postprocessing than we do in this example. / / Propably pour demander plus de post-traitement que nous faisons dans cet exemple.
      const aiScene *scene = aiImportFile (pfile, 
        aiProcess_CalcTangentSpace       |
            aiProcess_Triangulate            | 
            aiProcess_JoinIdenticalVertices  | 
            aiProcess_SortByPType );
     
     
      // If the import failed, report it / / Si l'importation a échoué, en faire rapport
      if ( !scene)
      { 
       std::cout <<"Erreur lors de l'importation du fichier "<< pfile<<std::endl;
        return false ; 
      } 
     
     
     
      // We're done. / / Nous avons terminé. Everything will be cleaned up by the importer destructor Tout sera nettoyé par le destructeur importateur
       aiReleaseImport (scene);
    return true ;
    }

  11. #11
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    Citation Envoyé par middle6 Voir le message
    Oui Coda_blank justement j'ai utiliser ce type de model pour importer..
    Mais cependant qu'en faire après ?
    Y a t-il une fonction special qui permet de lire les positions de la structure aiScene que j'ai créer ?

    Voici l'importateur que j'ai utiliser , après je ne sais pas quoi faire...snif

    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
    #include <iostream>
    #include < assimp.h > // C + + importateur interface
    #include < aiScene.h > // / / sortie des données de structure
    #include < aiPostProcess.h > // Post processing flags / / drapeaux de traitement du courrier
     
    bool Importer(const char * pfile)
    { 
      // Create an instance of the Importer class / / Création d'une instance de la classe de l'importateur
     
     
      // And have it read the given file with some example postprocessing / / Et l'ai lu le fichier donné avec quelques exemples de post-traitement
      // Usually - if speed is not the most important aspect for you - you'll / / En général - si la vitesse n'est pas l'aspect le plus important pour vous - vous
      // propably to request more postprocessing than we do in this example. / / Propably pour demander plus de post-traitement que nous faisons dans cet exemple.
      const aiScene *scene = aiImportFile (pfile, 
        aiProcess_CalcTangentSpace       |
            aiProcess_Triangulate            | 
            aiProcess_JoinIdenticalVertices  | 
            aiProcess_SortByPType );
     
     
      // If the import failed, report it / / Si l'importation a échoué, en faire rapport
      if ( !scene)
      { 
       std::cout <<"Erreur lors de l'importation du fichier "<< pfile<<std::endl;
        return false ; 
      } 
     
     
     
      // We're done. / / Nous avons terminé. Everything will be cleaned up by the importer destructor Tout sera nettoyé par le destructeur importateur
       aiReleaseImport (scene);
    return true ;
    }
    et bien après il faut chercher tout ce dont tu as besoin dans l'objet *scene

    d'après http://assimp.sourceforge.net/lib_ht...tai_scene.html, aiScene contient un tableau de pointeurs sur des objets aiMesh

    de même d'après http://assimp.sourceforge.net/lib_ht...ctai_mesh.html
    aiMesh contient un attribut mVertices, c-a-d un tableau d'objets aiVector3d, qui a comme attributs x, y, z

    lire les positions consiste à parcourir ces différents tableaux

    pour ce faire un tutoriel parmi d'autres : http://wasaproject.net16.net/?p=175

  12. #12
    Membre régulier
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2010
    Messages : 96
    Points : 72
    Points
    72
    Par défaut
    Ok je te remercie beaucoup Coda_Blank !

    Sa fesait un moment que je cherchais un tutoriel sur "ASSIMP" J'y vai de ce pas y jeter un oeil

    Encore mille fois merci , je viendrai reposter mes nouvelles par après

  13. #13
    Membre régulier
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2010
    Messages : 96
    Points : 72
    Points
    72
    Par défaut
    Me revoilà ^^

    J'ai juste un petit souci , j'importe mon fichier blender comme ci dessous:

    const aiScene*scene=aiImportFile(pfile,aiProcess_CalcTangentSpace|aiProcess_Triangulate|aiProcess_JoinIdenticalVertices |aiProcess_SortByPType );

    Jusqu'à là tout va bien mais après lorsque je fais apel a une methode de ma structure ( scene) cela me dit que l'apel de la methode est incorrect ....Voici comment je procede à l'apel.

    scene.HasAnimations() ;

    j'ai donc ecris "scene" suivi d'un point pour appeler les methode de celle-ci mais sa me repond:

    -l'expression scene doit avoir un type de classe ?!?!? même en mettant un "*" sa ne joue pas....pourtant j'ai bien construit une nouvelle classe scene je ne comprend d'ou vien mon erreur de code.

    Si quelqun pourait m'aider sa serait génial je vous en remercie d'avance merci, sa fais 1 semaine que je bloque la dessus argghhh

    Je voulais rajouter que je venais de ramarquer que si je declare une nouvelle structure aiScene sans le pointeur "*". j'arrive a appeler les methodes:
    si je fais


    const aiScene scene;

    j'arrive a faire

    scene.HasMateriel ...par exemple, mais pourquoi je ne peux pas si j'utilise un pointeur : const aiScene * scene ?!?!? Alors que je suis obligé d'utiliser un pointeur pour faire apel a la fonction aiImportFIle()...

  14. #14
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Re, dsl pour ma réponse tardive. Beaucoup de boulot cette semaine.


    Donc si non pour ton erreur sur :
    scene.HasAnimations() ;
    Ca vient du fait que scene est un pointeur et non un objet, donc pour accéder au méthodes et attributs il faut utiliser "->" et non "." soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scene->HasAnimations() ;
    Par contre apres pour ce qui est de passer par un objet const aiScene scene et non un pointeur const aiScene *scene, je suis pas sur que ce soit la bonne méthode car il y a une copie des données soit un doublon d'information. Et de plus il est marqué dans la doc que la globalité des données est gérée par une structure particulière Assimp::Importe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Assimp::Importer importer;
    Notamment pour l'allocation/désallocation des données, qui est sensé libérer toutes les données utilisés à la fin de l’exécution.

    Si non je me suis fait une classe pour simplifier l'importation puis l'affichage pour mon projet. Je la retouche vite fait pour la rendre plus général et je te la poste si besoin. Par contre c'est pour du Opengl 2.x.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 29
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par Robxley Voir le message
    Si non je me suis fait une classe pour simplifier l'importation puis l'affichage pour mon projet. Je la retouche vite fait pour la rendre plus général et je te la poste si besoin. Par contre c'est pour du Opengl 2.x.
    Cela m'intéresse également en fait. Ça me permettrait d'avoir une bonne base.
    Aussi, par "Opengl 2.x" tu entends "Opengl 2.x et supérieurs" ou "Opengl 2.x uniquement" ?

  16. #16
    Membre régulier
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2010
    Messages : 96
    Points : 72
    Points
    72
    Par défaut
    Waouhh merci beaucoup Robxley !! effectivement sa marche impeccable avec le -> !!

    Quand a la proposition de ta class pour importer et afficher du contenue je serais vraiment interessé si tu es toujours ok

    Veux tu me l'envoyer pas mail ou l'afficher sur le forum ? je comprendrais que tu ne veuilles pas partager au yeux de tous..

    En attendant de tes nouvelles je te remercie deja beaucoup pour ta réponse très clair

  17. #17
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Quand je parlais de Opengl 2.x, j'excluais toutes versions supérieures à la version 2 (cad Opengl3 et 4), en effet ma classe utilise les glVertex, glNormal et autre fonction dépréciée.

    Pour info ma classe c'est à 90% du code repris dans la SDK de assimp, je l'ai juste faite à titre "d'apprentissage/découverte" de Assimp, je n'ai pas réinventé la roue.

    Donc pour un projet digne de ce nom faudra bien évidement l'améliorer notamment avec un affichage par VBO. Mais rien de compliquer à changer si besoin.


    le header

    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
     
    #include <GL/gl.h>
    #include <map>
    #include <iostream>
     
    #include "assimp.hpp"
    #include "aiPostProcess.h"
    #include "aiScene.h"
     
    using namespace std;
     
    /*	Fonction de chargement de texture :					*/   
    /*		in : chemin d'accès à la texture				*/
    /*		out : id Opengl de la texture					*/
    GLuint LoadTexture(const char *filename);
     
    //logger simple
    #define LOGGER cout
     
    //retourne le chemin du dossier du fichier.
    string Dir(const string m_Name)
    {
    	string::size_type Pos = m_Name.find_last_of("\\/");
        if (Pos != string::npos)
            return m_Name.substr(0, Pos);
        else
            return "";
    }
     
    class RxAssimpLoader
    {
     
     
    	public:
    		RxAssimpLoader();
    		RxAssimpLoader(const string &pFile, unsigned int flags = aiProcessPreset_TargetRealtime_Quality);
     
     
    		bool Import3DFromFile(const string &pFile, unsigned int flags = aiProcessPreset_TargetRealtime_Quality);
    		void Draw(float scale);
     
     
    		const aiScene* getaiScene();
     
     
    	private:
     
    		//charge l'ensemble des textures nécessaires à l'objet à l'aide de la fonction LoadTexture
    		int LoadGLTextures(); 
     
    		//Fonctions issues de la SDK ASSIMP - (ne pas réinventer la roue)
    		void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float scale = 1.0f);
    		void apply_material(const struct aiMaterial *mtl);
    		void Color4f(const struct aiColor4D *color);
    		void set_float4(float f[4], float a, float b, float c, float d);
    		void color4_to_float4(const struct aiColor4D *c, float f[4]);
     
     
    	private:
    		//Si il y a une erreur
    		bool erreur;
     
    		//Creation d'une instance de la classe importer qui gére l'ensemble des objets
    		static Assimp::Importer importer;
     
    		// classe de type aiScene de notre objet
    		const aiScene* scene;
     
    		// images / textures
    		map<string,GLuint> textureFile;	// map des textures chargées 
     
    		string cfile;//direction du fichier de l'objet
     
    };

    le fichier sources de la classe

    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
     
     
     
    #include "RxAssimpLoader.h"
     
    Assimp::Importer RxAssimpLoader::importer;
     
    RxAssimpLoader::RxAssimpLoader()
    {
    	scene = NULL;
    }
    RxAssimpLoader::RxAssimpLoader(const string &pFile, unsigned int flags)
    {
    	scene = NULL;
    	Import3DFromFile(pFile,flags);
    }
     
     
    const aiScene* RxAssimpLoader::getaiScene()
    {
    }
     
    bool RxAssimpLoader::Import3DFromFile(const string &pFile, unsigned int flags)
    {
    	cfile = pFile;
     
    	//Vérification de l'existance du fichier
    	ifstream fin(cfile.c_str());
    	if(!fin.fail())
    	{
    		fin.close();
    	}
    	else
    	{
     
    		LOGGER<<"ERREUR LOADER ASSIMP : "<<importer.GetErrorString()<<endl;
    		return erreur=false;
    	}
     
    	//importation de la scène
    	scene = importer.ReadFile( pFile, flags);
     
    	// si erreur
    	if( !scene)
    	{
    		LOGGER<<"ERREUR LOADER ASSIMP : "<<importer.GetErrorString()<<endl;
    		return erreur=false;
    	}
     
    	// pas d'erreur
    	LOGGER<<"LOADER ASSIMP : Import of scene " + pFile + " succeeded.";
     
     
    	//on charge l'ensemble des textures
    	LoadGLTextures();
     
    	return erreur=true;
    }
     
    int RxAssimpLoader::LoadGLTextures()
    {
     
    	if (scene->HasTextures()) return 0; //pas de texture
     
    	/* Relève le filename des textures */
    	for (unsigned int m=0; m<scene->mNumMaterials; m++) //pour chacune des texture
    	{
    		int texIndex = 0;
    		aiReturn texFound = AI_SUCCESS;
     
    		aiString path;	// filename
     
    		while (texFound == AI_SUCCESS)
    		{
    			texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
                //enregiste le filename de la texture dans la structure map 
    			//(clé sans valeur pr l'instant, le chargement ce fera ensuite)
    			textureFile[path.data] = 0; 
    			texIndex++;
    		}
    	}
     
    	int numTextures = textureFile.size();
     
    	/* define texture path */
    	//std::string texturepath = "../../../test/models/Obj/";
     
    	map<string,RxTexture>::iterator itr = textureFile.begin();
     
     
    	for (; itr != textureFile.end(); itr++)
    	{
    		string filename = itr->first;  // chemin d'accès de l'image
     
    		string fileloc = Dir(cfile)+"/" + filename;	// chargement de l'image
     
    		if (itr->second = LoadTexture(fileloc.c_str())) //Si erreur de chargement texture 
    		{
    			LOGGER<<"ERREUR : Chargement impossible : " + fileloc<<endl;
    		}
     
    	}
     
    	//retourne le nombre de texture
    	return numTextures;
    }
     
     
    // Can't send color down as a pointer to aiColor4D because AI colors are ABGR.
    void RxAssimpLoader::Color4f(const struct aiColor4D *color)
    {
    	glColor4f(color->r, color->g, color->b, color->a);
    }
     
    void RxAssimpLoader::set_float4(float f[4], float a, float b, float c, float d)
    {
    	f[0] = a;
    	f[1] = b;
    	f[2] = c;
    	f[3] = d;
    }
     
    void RxAssimpLoader::color4_to_float4(const struct aiColor4D *c, float f[4])
    {
    	f[0] = c->r;
    	f[1] = c->g;
    	f[2] = c->b;
    	f[3] = c->a;
    }
     
    void RxAssimpLoader::apply_material(const struct aiMaterial *mtl)
    {
    	float c[4];
     
    	GLenum fill_mode;
    	int ret1, ret2;
    	struct aiColor4D diffuse;
    	struct aiColor4D specular;
    	struct aiColor4D ambient;
    	struct aiColor4D emission;
    	float shininess, strength;
    	int two_sided;
    	int wireframe;
    	unsigned int max;	// changed: to unsigned*/
     
    	int texIndex = 0;
    	aiString texPath;	//contains filename of texture
     
    	if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath))
    	{
    		//bind texture
    		glBindTexture(GL_TEXTURE_2D, textureFile[texPath.data]);
    	}
     
    	set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
    	if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
    		color4_to_float4(&diffuse, c);
    	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);
     
    	set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
    	if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
    		color4_to_float4(&specular, c);
    	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
     
    	set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
    	if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
    		color4_to_float4(&ambient, c);
    	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);
     
    	set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
    	if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
    		color4_to_float4(&emission, c);
    	glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);
     
    	max = 1;
    	ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
    	max = 1;
    	ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
    	if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS))
    		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
    	else {
    		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
    		set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
    		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
    	}
     
    	max = 1;
    	if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
    		fill_mode = wireframe ? GL_LINE : GL_FILL;
    	else
    		fill_mode = GL_FILL;
    	glPolygonMode(GL_FRONT_AND_BACK, fill_mode);
     
    	max = 1;
    	if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
    		glEnable(GL_CULL_FACE);
    	else
    		glDisable(GL_CULL_FACE);
    }
     
     
    void RxAssimpLoader::recursive_render (const struct aiScene *sc, const struct aiNode* nd, float scale)
    {
    	unsigned int i;
    	unsigned int n=0, t;
    	struct aiMatrix4x4 m = nd->mTransformation;
     
    	m.Scaling(aiVector3D(scale, scale, scale), m);
     
    	// update transform
    	m.Transpose();
    	glPushMatrix();
    	glMultMatrixf((float*)&m);
     
    	// draw all meshes assigned to this node
    	for (; n < nd->mNumMeshes; ++n)
    	{
    		const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
     
    		apply_material(sc->mMaterials[mesh->mMaterialIndex]);
     
     
    		if(mesh->mNormals == NULL)
    		{
    			glDisable(GL_LIGHTING);
    		}
    		else
    		{
    			glEnable(GL_LIGHTING);
    		}
     
    		if(mesh->mColors[0] != NULL)
    		{
    			glEnable(GL_COLOR_MATERIAL);
    		}
    		else
    		{
    			glDisable(GL_COLOR_MATERIAL);
    		}
     
     
     
    		for (t = 0; t < mesh->mNumFaces; ++t) {
    			const struct aiFace* face = &mesh->mFaces[t];
    			GLenum face_mode;
     
    			switch(face->mNumIndices)
    			{
    				case 1: face_mode = GL_POINTS; break;
    				case 2: face_mode = GL_LINES; break;
    				case 3: face_mode = GL_TRIANGLES; break;
    				default: face_mode = GL_POLYGON; break;
    			}
     
    			glBegin(face_mode);
     
    			for(i = 0; i < face->mNumIndices; i++)		// go through all vertices in face
    			{
    				int vertexIndex = face->mIndices[i];	// get group index for current index
    				if(mesh->mColors[0] != NULL)
    					Color4f(&mesh->mColors[0][vertexIndex]);
    				if(mesh->mNormals != NULL)
     
    					if(mesh->HasTextureCoords(0))		//HasTextureCoords(texture_coordinates_set)
    					{
    						glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, 1 - mesh->mTextureCoords[0][vertexIndex].y); //mTextureCoords[channel][vertex]
    					}
     
    					glNormal3fv(&mesh->mNormals[vertexIndex].x);
    					glVertex3fv(&mesh->mVertices[vertexIndex].x);
    			}
     
    			glEnd();
     
    		}
     
    	}
     
     
    	// draw all children
    	for (n = 0; n < nd->mNumChildren; ++n)
    	{
    		recursive_render(sc, nd->mChildren[n],scale);
    	}
     
    	glPopMatrix();
    }
     
     
    void RxAssimpLoader::Draw(float scale)
    {
    	if(scene)
    		recursive_render(scene, scene->mRootNode,scale);
     
    }

    Voila donc, la classe dépend d'une fonction pour charger une texture, à vous de la remplacer par la votre, et dépendait aussi d'un logger perso que j'ai remplacer par un simple pseudo logger à la Define.

    Pour info j'ai trouvé tout ça dans le dossier "samples" du SDK de Assimp, ou des exemples VC sont présentés.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  18. #18
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    Franchement, merci pour le lien!!

    Ce soir je retouche mon gestionnaire de ressources pour l'adapter à assimp!

    C'est super

  19. #19
    Membre régulier
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2010
    Messages : 96
    Points : 72
    Points
    72
    Par défaut
    Yess merci Robxley

    Cette fois-ci j'ai exactement tout ce qu'il me faut c genial

    J'y vai de ce pas tapper du code ^^ ahhlalaaa comme c'est magnifique quand sa marche

    Encoooooooore mille merciiii people

  20. #20
    Membre régulier
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2010
    Messages : 96
    Points : 72
    Points
    72
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    void RxAssimpLoader::Draw(float scale)
    {
    	if(scene)
    		recursive_render(scene, scene->mRootNode,scale);
     
    }
    OUps je reformule ma question , j'ai utiliser ta classe pour importer et tout a l'air de fonctionner cependant je n'arrive pas a afficher un decor sur la fenetre mais seulement l'importer.
    Voici l'ordre des operation que jai utiliser...

    1. Appel du Constructeur RxAssimpLoader
    2. Appel fonction getaiScene();
    3. Terminer avec la fonction Draw();

    Est-ce correct et suffisant pour charger et afficher quelque chose ?

Discussions similaires

  1. [VBA-E] Exporter une page Excel vers un Fichier Txt
    Par mamantins dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 08/06/2006, 12h09
  2. Problème pour exporter une table Access vers Excel
    Par PAULOM dans le forum Access
    Réponses: 22
    Dernier message: 02/05/2006, 14h42
  3. Exporter une base ORACLE vers ACCESS
    Par cquadjul dans le forum Access
    Réponses: 3
    Dernier message: 30/03/2006, 18h04
  4. Exporter une base MSDE vers SQL Server
    Par Noodles dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 20/01/2005, 14h56
  5. [FLASH MX] Lien d'une animation Flash vers une page html
    Par tinkye_winkye dans le forum Flash
    Réponses: 10
    Dernier message: 19/01/2005, 11h11

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