Jeux Libres
       
           

» Les Forums » Aide à propos de la création de jeux vidéo » [C++] importer des modelisations Blender dans un code C++


Aller à la page : 1, 2.

[C++] importer des modelisations Blender dans un code C++
Nicoco



Grade : Membre motivé
Inscrit le: 04 Août 2011, 13:41
Ecrit le: 09 Août 2011, 22:20             Message non corrigé

bonjour à tous,

David, tu m'as dit que mon projet t'intéressais donc voici une petite description de celui-ci :

le but serais de pouvoir modeliser des objets sous Blender pour ensuite les importer dans un code c++ .
pourquoi utiliser Blender?

imaginons que nous voulions créer un personnage...
bien sur, nous pourrions le faire en codant un cube pour le buste ,une sphère pour la tête et deux cylindres pour les jambes. quelques textures sur les surfaces et nous orrions un personnage. cette technique bien que simpliste est rapide et permet donc de gagner un temps précieux pour s'attarder sur d'autre partit du jeu.

maintenant, imaginons que nous voulions un vrais personnages qui puisse nous ressembler dans la forme.
il faudrait être fou pour vouloir écrire point par point la morphologie du corps et du visage. c'est pourquoi il existe des outils de modélisation et de rendu 3D tel que Blender, maya et 3ds max.
parmis ceux là, Blender est gratuit et pas trop lourd niveau ressource, le point négatif est qu'il est assez peut accueillant pour un débutant comme moi. mais quand on voit ce qu'il peut faire en regardant sur les forums...ça motive de suite !
vous savez maintenant mes motivations.

pour arriver à implémenter nos modélisation dans notre code, il nous faut les coordonnées de tout les sommets suivant un repère en 3 dimensions. pour cela, Blender ne manque pas de format mais le  plus universelle est le format wavefront(.obj) il est de plus assez facile à comprendre, c'est donc celui là que je vais utiliser.  

petite étude d'un fichier wavefront:



ce type de fichier ce présente de la manière suivante:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Blender v2.58 (sub 1) OBJ File: ''
# www.blender.org
mtllib cube.mtl
o Cube
v 1.000000 -1.000000 -1.000000  //1ere vectrice
v 1.000000 -1.000000 1.000000   //2eme vectrice
v -1.000000 -1.000000 1.000000  //3eme vectrice
v -1.000000 -1.000000 -1.000000 //etc...
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
usemtl Material
s off
f 1 2 3 4
f 5 8 7 6
f 1 5 6 2
f 2 6 7 3
f 3 7 8 4
f 5 1 4 8

lorsque les coordonnées commence par la lettre 'v', ce sont les coordonnées des sommets ont dit aussi que ce sont des vertices en anglais.
la lettre 'f' annonce en revanche les faces .

pour lire ce type de fichier, il faut commencer par regarder les faces.
avec Blender, toutes les faces sont constituées de 4 sommets .
et puisque les sommets sont des vertices, chaques faces se rapportent donc à 4 vertices.

en reprenant l'exemple si dessus:

f 5 8 7 6  
signifie que la 2eme face est constitué de la 5eme vertice puis de la 8eme vertice puis de la 7eme et enfin 6eme vertices .

ce qui donnerait sous opengl (en arrondissant un peu):
1
2
3
4
5
6
7
8
//face2

glBegin(GL_QUADS);
glvertex3d(1,1,-1);  //5eme v
glvertex3d(-1,1,-1); //8eme v
glvertex3d(-1,1,1);  //7eme v
glvertex3d(1,1,1);   //6eme v
glEnd();

rien de difficile en soit
il ne reste plus qu'à coder .

je poste mon code demain ainsi que toutes mes interrogations à propos de mon code.

j'ai quand même une question qui me trotte dans la tête :
David,juste par curiosité , est ce toi qui a fait ce site?
enfin...si ce n'est pas trop indiscret, tu l'as écrit ou tu t'es servis d'un logiciel?

en idée d'amélioration, je verrais bien quelque chose que l'on voit nul part. enfin...sur aucun autre forum.
ça serait une page éditable par tout le monde un peu comme wikipédia mais dédier aux programmeurs pour écrire du code.
je suis certain que ça pourrais être utile pour partagé du code, facilité les personnes à ce lancer à plusieurs dans un projet (même petit) et montrer au débutant qu'il ne vont pas pouvoir réécrit world of warcraft par exemple.
parfois même trouver des idéés dans le code des autres et voir nos lacune .
je pense que ça marchera parce que ça ne ce trouve nul part, et ça m'intéresserait.

dit moi ce que tu en pense surtout.

bonne soirée
Nico



  Profil
David



Grade : Maître
Inscrit le: 11 Mai 2005, 20:30
Ecrit le: 09 Août 2011, 23:47             Message non corrigé

Salut Nico,

  David,juste par curiosité , est ce toi qui a fait ce site?      


Oui c'est moi qui ai fait ce site. Pour l'idée, je me suis inspiré de siteduzero.com, je l'ai orienté vers le développement de jeux vidéo. Ma copine m'a aidé dans le nouveau design du forum. Thomas m'as aidé dans le design du titre (un après midi à la fac). Le code HTML, PHP, SQL, JavaScript est bien de moi. J'ai utilisé GeSHi pour le colorateur syntaxique et MathJax pour les formules.

Pour ce qui est du codage, j'au utilisé NotePad++ principalement. Le design a été fait à l'aide de Paint et PhotoFiltre. Les icones sont des icones généralement récupéré sur des sites d'images libres.

Pour ce qui est de la page de code éditable à plusieurs, je pense que le mieux est d'utiliser SVN. Je l'utilise pour développer le FPS. Un jour peut-être que quelqu'un me rejoindra sérieusement sur le projet.

J'aimerais faire d'autre tutoriel que celui du FPS mais je manque de temps. Le prochain tutoriel sera sans doute celui sur la programmation avec OpenGL (les bases). Et ensuite, je pense que je ferais un tutoriel sur l'utilisation de SVN qui est vraiment un outil formidable pour le développement à plusieurs et à distance.

Merci de me maintenir au courant de l'avancement de ta classe. Il n'est pas impossible, si tu fais tes preuves, que je t'intègre au projet du FPS pour implémenter ta classe. Je cherche quelqu'un capable de fournir du code propre, qui sache justifier chacune de ses lignes de code, que celui-ci soit propre, facile à comprendre, et bien commenté.

A très bientôt !

________
Apprenez à créer votre propre FPS en C++ avec OpenGL. C'est pas dur ! :-)
  Profil
David



Grade : Maître
Inscrit le: 11 Mai 2005, 20:30
Ecrit le: 10 Août 2011, 00:05             Message non corrigé

Les faces peuvent être composées de 3 ou 4 sommets.
Certain .obj comporte également le nom d'un fichier de texture, et il peut également y avoir des normales.

Le chargement du fichier consiste à ouvrire le fichier, lire chacune des lignes une par une.
S'il s'agit d'un sommet, on l'ajoute à la liste des sommets.
S'il s'agit d'une face, on l'ajoute à la liste des faces.

On s'appercois qu'il va falloir créer une structure Surface.
On s'appercois également, qu'il va falloir créer deux vector pour stocker toutes ces informations.

Ensuite, la méthode afficher() viendra parcourir le vector de surface et, à partir de chacune d'elle, viendra appeler chacun des points.

L'idéal ensuite, est de mémoriser tout ça dans une liste d'affichage pour accélérer le rendu.

Si tu as besoin d'aide que ce soit pour l'utilisation de la STL ou d'OpenGL, ou simplement pour une question d'algorithmique, surtout n'hésite pas à me contacter.

Bon courage.

________
Apprenez à créer votre propre FPS en C++ avec OpenGL. C'est pas dur ! :-)
  Profil
Nicoco



Grade : Membre motivé
Inscrit le: 04 Août 2011, 13:41
Ecrit le: 10 Août 2011, 01:06             Message non corrigé


j'ai déjà bien commencer.
je ne peux pas te donner tout le code, je le mettrais en forme demain .
pour info , j'utilise Qt mais je le recompilerais sous code::Blocks avec la sdl s'il le faut.(je n'ai encore intégrés auccune class propre à Qt donc... tout est encore possible)

j'avais envie de voir ce qu'était Qt et je n'en suis pas déçu !
ton projet, tu le fais avec la SDL/opengl?

voici mon header:
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
#ifndef EXTRACTION_H
#define EXTRACTION_H

#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <stdlib.h>



class Donnee
{
public:

   Donnee();

   void setNomFichier(const std::string& ); //mutateur qui pose problème
   void extractionVertice(); // met toute les coordonnées des vertices dans le tableau m_vertice.
   void extractionFace();    //___________________________des faces dans le tableau m_face.
    void verbose();         // detaille tout ce que font les methodes dans la console.
   void organisation();    // créé des donnees directement exploitable dans un autres tableaux
   void envoie();         // je n'ai encore rien mis mais j'avais prévue d'envoyer les donnees dans une autre
                         //class . je vais quand même pas tout modéliser ici  


private:


   double m_tamponVertice;
   int m_tamponFace;
   int m_i;
   int m_caseVertice;
   int m_caseFace;
   int m_caseTableau;
   std::string m_mot;
   std::string m_choix;
   std::string m_nomFichier;
   std::vector<double> m_vertice;
   std::vector<int> m_face;

   std::ifstream fichier;


};

#endif // EXTRACTION_H


j'ai rencontré quelques problèmes. mais il faudrait avoir toute la class pour en parler et je le ferais demain .
le code marche mais bon... je le refrait .
j'avais envie de séparer le travaille en plusieurs petites méthodes mais je m'aperçois que ça fait deux fois plus de boucle et donc de temps de perdu ...




  Profil
Nicoco



Grade : Membre motivé
Inscrit le: 04 Août 2011, 13:41
Ecrit le: 10 Août 2011, 01:43             Message non corrigé

je n'ai jamais fait de liste d'affichage mais le principe est d'écrire des lignes de code dans un fichier.non?
donc, une fois les données extraite, il faudrait les réécrire dans un fichier.cpp sous cette forme :
1
2
3
4
5
6
glBegin(GL_QUADS);
glvertex3d(1,1,-1);  
glvertex3d(-1,1,-1);
glvertex3d(-1,1,1);
glvertex3d(1,1,1);  
glEnd();

c'est bien ça le but à atteindre. non?

à propos de ton projet FPS, est ce que je peux le voir ou... c'est secret défense?
et...en ce moment, vous le faite à plusieurs ou tu es seul?
je peux poster mon code sur la SVN?
  Profil
Nicoco



Grade : Membre motivé
Inscrit le: 04 Août 2011, 13:41
Ecrit le: 10 Août 2011, 12:30             Message non corrigé


comme je le disais, j'ai rencontré un problèmes.

1
2
3
4
void Donnee::setNomFichier(const std::string& NomFichier)
{    
m_fichierLecture(NomFichier);
}
     
m_fichierLecture est un objet ifstream qui permet de lire le fichier.
je voudrais que l'utilisateur de ma class puisse envoyer le nom du fichier à ouvrir dans ma class, mais mon compilateur met:
"no match for call to '(std::ifstream)(const char[12])'"
ça veux dire que je peux pas modifier l'objet dans cette méthode? pourquoi?
               
  Profil
David



Grade : Maître
Inscrit le: 11 Mai 2005, 20:30
Ecrit le: 10 Août 2011, 12:57             Message non corrigé

Ton fstream n'a pas besoin d'être membre de ta classe.
Inspire toi du constructeur de la classe Objet3DStatique.

Tu ouvre le fichier, tu charge ce qu'il y a à récupérer, et tu referme le fichier immédiatement.
Ensuite, tu ne travailles que sur les données prélevés.

________
Apprenez à créer votre propre FPS en C++ avec OpenGL. C'est pas dur ! :-)
  Profil
Nicoco



Grade : Membre motivé
Inscrit le: 04 Août 2011, 13:41
Ecrit le: 10 Août 2011, 17:11             Message non corrigé

le problème c'est que le fichier doit être accessible par la méthode extractionVectice et extractionFace.
sinon, au lieu de faire un mutateur, je vais demander directement dans la console le nom du fichier...ça sera plus simple . non?

voilà ce que ça donne avec le fichier.obj que l'on voit dans le premier poste:

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
GlBegin(GL_QUADS);
(1,-1,-1);
(1,-1,1);
(-1,-1,1);
(-1,-1,-1);
GlEnd();

GlBegin(GL_QUADS);
(1,1,-0.999999);
(-1,1,-1);
(-1,1,1);
(0.999999,1,1);
GlEnd();

GlBegin(GL_QUADS);
(1,-1,-1);
(1,1,-0.999999);
(0.999999,1,1);
(1,-1,1);
GlEnd();

GlBegin(GL_QUADS);
(1,-1,1);
(0.999999,1,1);
(-1,1,1);
(-1,-1,1);
GlEnd();

GlBegin(GL_QUADS);
(-1,-1,1);
(-1,1,1);
(-1,1,-1);
(-1,-1,-1);
GlEnd();

GlBegin(GL_QUADS);
(1,1,-0.999999);
(1,-1,-1);
(-1,-1,-1);
(-1,1,-1);
GlEnd();

si la syntaxe n'est pas bonne ou s'il y à des choses à ajouter, il est très facile de  modifier l'écriture...
par contre, mon programme gère uniquement les quadrilatère . je travaille sur la version 'bêta' pour qu'il puisse gérer les triangles.

est ce que je doit faire une structure ou je peux laisser mes tableaux dans mon code?  
  Profil
David



Grade : Maître
Inscrit le: 11 Mai 2005, 20:30
Ecrit le: 10 Août 2011, 19:15             Message non corrigé

C'est pas comme ça qu'il faut que tu t'y prenne.

Pense à l'utilisateur de ta classe. Ta classe modélise un objet 3D, donc appel la "Objet3D".

Quand le mec va vouloir afficher son .obj à l'écran, il veut faire comme ceci :
1
2
Objet3D cube("cube.obj");
cube.afficher();

L'objet ne sera chargé qu'une fois et affiché beaucoup de fois. Arrange toi pour que les données qui constitue ton objet soit accessible rapidement. Il n'est pas question d'accéder au disque dur pendant un affichage.

Le constructeur de ton Objet3D doit lire chacune des lignes :
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
Objet3D::Objet3D(std::string nomFichier)
{
   // Ouverture du fichier
   std::fstream fichier(nomFichier.c_str(), std::fstream::in);
 
   // Ouverture ralise avec succs
   if (fichier.is_open())
   {
       std::string ligne;
 
       // Lecture de chaques lignes
       while(getline(fichier, ligne))
       {
 
           // Chargement d'un sommet
           if (0 == ligne.compare(0, 2, "v "))
           {
               // Ajout du sommet la liste des sommets
 
           }
 
           // Chargement d'une face
           else if (0 == ligne.compare(0, 2, "f "))
           {
               // Ajout de la face la liste des faces
 
           }
 
           // Commentaires et lignes vides
           else if (0 == ligne.compare(0, 1, "#") || ligne.empty())
           { }
 
       }
 
   }
}

Et pour l'affichage, tu boucles sur ta liste de faces
1
2
3
4
5
6
7
8
9
10
11
for (Faces::iterator face = this->faces.begin(); face != this->faces.end(); face++)
{
   glBegin(GL_POLYGON);
 
       for (Points:iterator point = face.begin(); point != face.end(); point++)
       {
            glvertex3f (point->x, point->y, point->z );
       }
 
   glEnd();
}

J'espère que ça t'aidera. Il y a sans doute des erreurs. Mais l'idée est là.

________
Apprenez à créer votre propre FPS en C++ avec OpenGL. C'est pas dur ! :-)
  Profil
Lo



Grade : Maître
Inscrit le: 26 Dec 2007, 17:33
Ecrit le: 11 Août 2011, 08:57             Message non corrigé

Ouarf j'ai déjà essayer de faire cela avec plusieurs format de fichiers... (3m2, 3ds, wavefront (.obj), etc...)

C'est pas que c'est difficile mais assez lourd à coder.

Cependant je n'ai pas utilisé les listes d'affichage mais les vertex buffer objects.

Et je te conseilles de faire des personnages simples avec le moins de poly possible (genre un cube pour le corps, une sphere pour la tete, enfin comme tu as dis plus haut quoi!) et faire tout le reste avec les textures, sinon : ton jeux risque de tourner à 1 fps...(Enfin moi c'est ce qui m'étais arrivé..., j'ai voulu chargé un modèle déjà existant mais il y avait trop de poly a afficher alors...)




________
Parce qu'on ne peut s'exprimer que par nos créations. ^^
  Profil
 


Aller à la page : 1, 2.


Hébergeur du site : David
Version PHP : 5.4.45-0+deb7u2
Uptime : 55 jours 17 heures 29 minutes
Espace libre : 1513 Mo
Dernière sauvegarde : inconnue
Taille de la sauvegarde : 1113 Mo


5888708 pages ont été consultées sur le site !
Dont 2713 pages pendant les 24 dernières heures.

Page générée en 0.983 secondes


Nos sites préférés
- Création d'un jeu de plateforme de A à Z avec SDL
- Zelda ROTH : Jeux amateurs sur le thème de Zelda
- Zeste de Savoir : la connaissance pour tous et sans pépins
- YunoHost : s'héberger soi-même en toute simplicité
- Site de Fvirtman : recueil de projets et de codes en C et C++
- Par ici la sortie : le site des idées de sorties


  © 2005-2020 linor.fr - Toute reproduction totale ou partielle du contenu de ce site est strictement interdite.