Bonjour à tous, je code en ce moment un petit simulateur avec une map contenant un nombre relativement élevé de vertices (Plusieurs dizaines de milliers), et force est de constater que mon PC atteint vite ses limites en terme de performances, la map est en fait constituée de plusieurs massifs et lorsqu'ils sont tous dessinés, ça lague comme pas possible, tous est saccadé ! Mon PC est un HP Pavilion G6 tournant sous Windows 8, j'ai testé sur un autre PC (Un Asus F541U sous Windows 10) et la différence est flagrante : C'est bien plus fluide, mais on sent quand même la différence selon si un seul massif est dessiné ou bien tous.
Mon programme utilise SDL et OpenGL et est écrit en C, on y trouve une structure "Principale" contenant tous les paramètres du simulateur (Paramètres écran, caméra) notamment une structure de type "Terrain". Le tout est lu dans un fichier .obj créé avec Blender. Pour résumer :
Fichier d'en-tête :
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 typedef struct Vertex //Sommet des polygones { float x; float y; float z; float xTex; float yTex; }Vertex; typedef struct Face //Polygones constituée de vertices { Vertex *vertices; int nbVertices; GLint texture; float couleur[3]; }Face; typedef struct Objet //Objet constituée de polygones { Face *faces; int nbFaces; bool textures; }Objet; typedef struct Massif //Massif constitué d'objets { Objet Meshes[MAX_OBJETS]; int nbObjets; float X; float Y; }Massif; typedef struct Terrain //Terrain constitué de massifs { Massif liste_massifs[NB_MASSIFS]; }Terrain; typedef struct Principale { /*...*/ Terrain Map; }Principale;
Fonction chargement() :
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 int main(int argc,char *argv[]) { SDL_Surface *fenetre; SDL_Event evenement; Principale infos; //Tous les paramètres du simulateur if(SDL_Init(SDL_INIT_VIDEO)<0) return -1; Init(&infos); fenetre=SDL_SetVideoMode(800,600,32,SDL_OPENGL); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(FOVY_INIT,4.0/3,NEAR,FAR); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); chargeTextures(&infos); chargement(&infos); while(1) { SDL_PollEvent(&evenement); if(evenement.type==SDL_QUIT) break; if(evenement.type==SDL_KEYDOWN) { if(evenement.key.keysym.sym==SDLK_ESCAPE) break; } gestionCam(&infos,&evenement); Dessiner(&infos); SDL_GL_SwapBuffers(); glFlush(); } SDL_Quit(); return 0; }
La fonction chargeMassif() parcourt ensuite le fichier .obj et liste tous les vertices et toutes les coordonnées de textures pour tout stocker en mémoire.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 { chargeMassif(&ptr->Map.liste_massifs[0],"Massif1"); chargeMassif(&ptr->Map.liste_massifs[1],"Massif2"); chargeMassif(&ptr->Map.liste_massifs[2],"Massif3"); }
Fonction Dessiner() :
Fonction dessinMap() :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); gluLookAt(ptr->xCam,ptr->yCam,ptr->zCam,ptr->xCible,ptr->yCible,ptr->zCible,0,0,1); glClearColor(0,0.5,1,1); dessinMap(ptr); }
Fonction dessinMassif() :
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 { int compteurMassifs=0; const float tailleMap=100000; const int multiplTex=10000; dessinTerrain(&ptr->Map); while(1) { glPushMatrix(); glTranslated(ptr->Map.liste_massifs[compteurMassifs].X,ptr->Map.liste_massifs[compteurMassifs].Y,0); glScalef(1000,1000,1000); //Echelle en mètres dessinMassif(&ptr->Map.liste_massifs[compteurMassifs]); glPopMatrix(); compteurMassifs++; if(compteurMassifs==NB_MASSIFS) break; } }
Alors effectivement ça fait beaucoup de while dans un while ... Je me doute que ça contribue à ralentir l'exécution mais je ne vois pas d'autre solution à moins peut-être d'utiliser les shaders, mais avant de me lancer là-dedans, j'aimerais avoir des avis pour savoir si les shaders sont une solution pour ce problème.
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 { int compteurMeshes=0,compteurFaces,compteurVertices; while(1) //Dessin des objets { compteurFaces=0; while(1) { if(massif->Meshes[compteurMeshes].faces[compteurFaces].texture!=-1) //Si la face est texturée { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,(GLuint)massif->Meshes[compteurMeshes].faces[compteurFaces].texture); } if(massif->Meshes[compteurMeshes].faces[compteurFaces].texture==-1) //Si la face n'est pas texturée glDisable(GL_TEXTURE_2D); glColor3d(massif->Meshes[compteurMeshes].faces[compteurFaces].couleur[0], //Coloration massif->Meshes[compteurMeshes].faces[compteurFaces].couleur[1], massif->Meshes[compteurMeshes].faces[compteurFaces].couleur[2]); //Dessin des polygones if(compteurFaces==0) { if(massif->Meshes[compteurMeshes].faces[compteurFaces].nbVertices==3) glBegin(GL_TRIANGLES); if(massif->Meshes[compteurMeshes].faces[compteurFaces].nbVertices==4) glBegin(GL_QUADS); if(massif->Meshes[compteurMeshes].faces[compteurFaces].nbVertices>=5) glBegin(GL_POLYGON); } if(compteurFaces!=0) { if(massif->Meshes[compteurMeshes].faces[compteurFaces].nbVertices!=massif->Meshes[compteurMeshes].faces[compteurFaces-1].nbVertices|| massif->Meshes[compteurMeshes].faces[compteurFaces].texture!=massif->Meshes[compteurMeshes].faces[compteurFaces-1].texture) { if(massif->Meshes[compteurMeshes].faces[compteurFaces].nbVertices==3) glBegin(GL_TRIANGLES); if(massif->Meshes[compteurMeshes].faces[compteurFaces].nbVertices==4) glBegin(GL_QUADS); if(massif->Meshes[compteurMeshes].faces[compteurFaces].nbVertices>=5) glBegin(GL_POLYGON); } } compteurVertices=0; //Dessin des vertices while(1) { glTexCoord2f(massif->Meshes[compteurMeshes].faces[compteurFaces].vertices[compteurVertices].xTex, massif->Meshes[compteurMeshes].faces[compteurFaces].vertices[compteurVertices].yTex); glVertex3f(massif->Meshes[compteurMeshes].faces[compteurFaces].vertices[compteurVertices].x, massif->Meshes[compteurMeshes].faces[compteurFaces].vertices[compteurVertices].y, massif->Meshes[compteurMeshes].faces[compteurFaces].vertices[compteurVertices].z); compteurVertices++; if(compteurVertices==massif->Meshes[compteurMeshes].faces[compteurFaces].nbVertices) break; } if(compteurFaces!=massif->Meshes[compteurMeshes].nbFaces-1) { if(massif->Meshes[compteurMeshes].faces[compteurFaces].nbVertices!=massif->Meshes[compteurMeshes].faces[compteurFaces+1].nbVertices|| massif->Meshes[compteurMeshes].faces[compteurFaces].texture!=massif->Meshes[compteurMeshes].faces[compteurFaces+1].texture) glEnd(); } if(compteurFaces==massif->Meshes[compteurMeshes].nbFaces-1) glEnd(); compteurFaces++; if(compteurFaces==massif->Meshes[compteurMeshes].nbFaces) break; } compteurMeshes++; if(compteurMeshes==massif->nbObjets) break; } glEnable(GL_TEXTURE_2D); glColor3d(1,1,1); }
Petite parenthèse aussi : Je remarque qu'à chaque fois que mes programmes tournent sous Windows 10, la visibilité est réduite et la précision de l'affichage réduite (On voit les surfaces à travers les autres).
Merci d'avance.
Partager