Bonsoir, je tente en ce moment de coder un programme capable de lire un fichier .obj et de l'afficher dans une fenêtre 3D. Mais comme vous vous en doutez sûrement, il y a un nombre considérable de polygones et cela a tendance à poser problème. Pour info, voici le code simplifié de mon programme :

Le fichier d'en-tête :

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
typedef struct Vertex
{
    float x;
    float y;
    float z;
    float xTex;
    float yTex;
    float zTex;
}Vertex;
 
typedef struct Face
{
    Vertex vertices[10];
    int nbVertices;
}Face;
 
typedef struct Principale
{
    SDL_Surface *caracteres[68];
    char nomFichier[50];
    int nbFaces;
    Face *liste_faces;
}Principale;
 
int Menu(SDL_Surface *ecran,Principale *ptr);
void chargeImages(Principale *ptr);
int selectFichier(SDL_Surface *ecran,Principale *ptr);
void affichNomFichier(SDL_Surface *ecran,SDL_Surface *caracteres[],char *nomFichier,SDL_Rect *position);
void lectureFichierObj(Principale *ptr);
void analyseFace(char *chaine,float *xVertex,float *yVertex,float *zVertex,float *xTex,float *yTex,Face *face);
Le main :

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
int main(int argc,char *argv[])
{
    SDL_Surface *ecran;
    SDL_Event evenement;
    int retourMenu;
    Principale infos;
 
    chargeImages(&infos);		//Chargement des SDL_Surface
    strcpy(infos.nomFichier,"");	//Initialisation chaîne
 
    infos.liste_faces=(Face*)malloc(50000*sizeof(infos.liste_faces));	//Allocation de 50000 faces
 
    if(SDL_Init(SDL_INIT_VIDEO)!=0)
        return -1;
 
    SDL_WM_SetCaption("Lecteur fichiers .obj",NULL);
    putenv("SDL_VIDEO_CENTERED=1");
 
    ecran=SDL_SetVideoMode(800,600,32,SDL_HWSURFACE);       //Menu
    retourMenu=Menu(ecran,&infos);
    if(retourMenu==-1)
    {
        SDL_Quit();
        return 0;
    }
 
    lectureFichierObj(&infos);		//Lecture du fichier
 
    ecran=SDL_SetVideoMode(800,600,32,SDL_OPENGL);	//Partie 3D
 
    glLoadIdentity();
    glMatrixMode(GL_PROJECTION);
    gluPerspective(70,4.0/3,0.01,100);
 
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
 
    while(1)
    {
        SDL_PollEvent(&evenement);
        if(evenement.type==SDL_QUIT)
            break;
 
        glFlush();
        SDL_GL_SwapBuffers();
    }
 
    SDL_Quit();
    return 0;
}
La fonction de lecture du fichier :

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
void lectureFichierObj(Principale *ptr)
{
    char caracteresLus[500]="",chaineFgetc[200]="";
    int compteurChaine=0,compteurVertex=0;
    int compteurCoordTex=0,entier,compteurFace=0;
    int tailleFichier;
    float xVertex[30000],yVertex[30000],zVertex[30000];
    float xTex[40000],yTex[40000];
    bool finFichier=false;
 
    FILE *fichier=fopen(ptr->nomFichier,"r");	//Détermination taille fichier
    fseek(fichier,0,SEEK_END);
    tailleFichier=ftell(fichier);
    fclose(fichier);
 
    fichier=fopen(ptr->nomFichier,"rb");       //Ouverture fichier
 
    while(1)
    {
        while(1)        //En-tête fichier
        {
            caracteresLus[compteurChaine]=fgetc(fichier);
            if(caracteresLus[compteurChaine]=='v'&&caracteresLus[compteurChaine-1]=='\n')
                break;
 
            compteurChaine++;
        }
        fseek(fichier,-1,SEEK_CUR);
 
        while(1)        //Lecture coordonnées vertices
        {
            compteurChaine=0;
            while(1)
            {
                chaineFgetc[compteurChaine]=fgetc(fichier);
 
                if(chaineFgetc[compteurChaine]=='\n')
                {
                    chaineFgetc[compteurChaine]='\0';
                    break;
                }
 
                compteurChaine++;
            }       //Lecture d'UNE ligne
 
            if(chaineFgetc[0]!='v'||chaineFgetc[1]!=' ')
                break;
 
            sscanf(chaineFgetc,"v %f %f %f",&xVertex[compteurVertex],&yVertex[compteurVertex],&zVertex[compteurVertex]);
            strcpy(chaineFgetc,"");
 
            compteurVertex++;
        }
 
        while(1)        //Lecture coordonnées de texture
        {
            compteurChaine=0;
            while(1)
            {
                chaineFgetc[compteurChaine]=fgetc(fichier);
 
                if(chaineFgetc[compteurChaine]=='\n')
                {
                    chaineFgetc[compteurChaine]='\0';
                    break;
                }
 
                compteurChaine++;
            }       //Lecture d'UNE ligne
 
            if(chaineFgetc[0]!='v'||chaineFgetc[1]!='t')
                break;
 
            sscanf(chaineFgetc,"vt %f %f %d",&xTex[compteurCoordTex],&yTex[compteurCoordTex],&entier);
 
            strcpy(chaineFgetc,"");
 
            compteurCoordTex++;
        }
 
        while(1)
        {
            compteurChaine=0;
            caracteresLus[0]='\0';
            while(1)
            {
                caracteresLus[compteurChaine]=fgetc(fichier);
                if(caracteresLus[compteurChaine]=='\n')
                {
                    caracteresLus[compteurChaine]='\0';
                    break;
                }
 
                compteurChaine++;
            }
            analyseFace(caracteresLus,xVertex,yVertex,zVertex,xTex,yTex,&ptr->liste_faces[compteurFace]);
	    //Analyse de la chaîne 'caracteresLus' et assignation des paramètres de la face (Coordonnées des vertices et nombre de sommets)
 
            if(ftell(fichier)>=tailleFichier)	//Si on a dépassé la taille du fichier
            {
                finFichier=true;
                break;
            }
            printf("%d\n",compteurFace);	//Test
 
            compteurFace++;
            if(caracteresLus[0]!='f')
                break;
        }
 
        strcpy(caracteresLus,"");
        strcpy(chaineFgetc,"");
 
        if(finFichier==true)
            break;
    }
 
    fclose(fichier);
}
Le problème de base, c'est que si je fais :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
typedef struct Principale
{
    SDL_Surface *caracteres[68];
    char nomFichier[50];
    int nbFaces;
    Face liste_faces[50000];
}Principale;
Le programme plante dès la déclaration de la structure de type 'Principale', ce problème ne se pose en revanche pas avec malloc() et la déclaration d'un pointeur *liste_faces. Mais bien que la taille allouée soit de 50000 fois la taille d'une structure de type 'Face', le programme plante au bout de 1240 cases remplies dans le tableau en renvoyant la valeur 3 ; pourtant, il y a bien 50000 cases allouées.
Le problème ne vient pas de la fonction analyseFace() car il a lieu même en mettant cette fonction en commentaire.

Je ne vois vraiment pas où est le problème.

Petite question au passage qui n'a rien à voir : Dans un fichier .obj sont indiquées les coordonnées de texture, mais à aucun endroit n'est précisé quelle texture on utilise. Comment savoir dans ce cas quelle texture il va falloir plaquer sur le polygone ??