Bonjour à tous,
Cela fait maintenant quelques jours que je tripatouille OpenGL et je rencontre un problème dépassant ma compréhension...
Dans mon application je créé des surfaces SDL_Surface que je peux facilement afficher, si je détruit les objets possédants une surface leur destructeur s'occupe de libérer la mémoire et je la récupere bien.
Mais si j'affiche 1000 surfaces sur une zone avec la transparence, SDL tombe a 25FPS... après pas mal de galère j'ai fais un deuxième rendu en OpenGL qui tourne a 3300 FPS. Mais voila le soucis : je n'arrive pas a des-allouer mes textures OpenGL avec glDeleteTextures(int,&texture) ;
Je vous épargne le listing de tout mon code source et vous montre la partie que j'ai identifier comme étant le problème :
J'ai un objet ayant une SDL_surface *surface s'affichant sans soucis et un GLuint texture qui recevra lidentifiant de la texture. Ci dessous la fonction renvoyant l'identifiant de texture a partir de ma surface :
Fonction de création de texture à partir d'une surface SDL :
Ensuite voila ma fonction d'affichage de texture 2D OPENGL très classique :
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 GLuint surface2Texture(SDL_Surface *surface) { // mon ID texture et des variable pour le traitement GLuint texture ; GLenum texture_format; GLint nOfColors; // get the number of channels in the SDL surface nOfColors = surface->format->BytesPerPixel; if (nOfColors == 4) // contains an alpha channel { if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGBA; else texture_format = GL_BGRA; } else if (nOfColors == 3) // no alpha channel { if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGB; else texture_format = GL_BGR; } else { //fprintf(stderr,"waring: the image is not truecolor.. this will probably break\n"); } //creation de la texture en memoire glGenTextures( 1, &texture) ; glBindTexture( GL_TEXTURE_2D, texture ); // Set the texture's stretching properties glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // Edit the texture object's image data using the information SDL_Surface gives us glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels ); //retour du texture ID //!\ Si je fais un glDleteTextures(1,&texture) ici je recupere bien ma memoire mais forcement j'affiche un carre blanc return texture ; }
Fonction d'affichage de texutre :
Enfin voila un destructeur d'objet possédant une texture et surface :
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 void blitTexture(GLuint texture, int vertX, int vertY, int vertW, int vertH, int cutTextX, int cutTextY , int TextW , int TextH ) { //la masse de parametre servent a positioner la texture sur l'ecran et definisse la zone de la texture a afficher (utile pour les animations) glTranslated(vertX,vertY,0); glBindTexture( GL_TEXTURE_2D, texture ); glBegin( GL_QUADS ); //Bottom-left vertex (corner) glTexCoord2f( 0 + (float)cutTextX/TextW, 0 + (float)cutTextY/TextH ); glVertex2i( 0, 0 ); //Bottom-right vertex (corner) glTexCoord2f( (float)vertW/TextW + (float)cutTextX/TextW, 0 + (float)cutTextY/TextH ); glVertex2i( vertW, 0 ); //Top-right vertex (corner) glTexCoord2f( (float)vertW/TextW + (float)cutTextX/TextW, (float)vertH/TextH + (float)cutTextY/TextH); glVertex2i( vertW, vertH ); //Top-left vertex (corner) glTexCoord2f( 0 + (float)cutTextX/TextW, (float)vertH/TextH + (float)cutTextY/TextH); glVertex2f( 0, vertH ); glEnd(); glLoadIdentity(); //!\ Si je fais un glDeleteTextures(1,&texture) je ne libère pas la texture en mémoire mais j'ai un carré blanc à la place de la texture QUID : elle est supprimer ou pas ?!? }
Destructeur d'objet :
Et donc pour tester voila :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Entity::~Entity() { glDeleteTextures(1, &texture) ; SDL_FreeSurface(sprite) ; }
Je commence avec 100 élément avec leur texture unique dans ma zone => 45Mo en mémoire
J'en creer 1000 => 239Mo en mémoire
J'en detruit 1100 => 179Mo en mémoire
Note importante :
Si je ne fais pas de glGenTextures( 1, &texture2) ; alors tout mes objets se retrouvent avec la même texture dans leur GLuint mais j'ai plus de soucis de mémoire :
Je commence avec 100 élément avec leur texture unique dans ma zone => 19Mo en mémoire
J'en créer 1000 => 60Mo en mémoire
J'en détruit 1100 => 15Mo en mémoire
Donc voila je pense que je gere tres mal glGenTextures et glDeleteTextures.
Mon moteur a 2 rendus et le SDL n'a aucun soucis, et opengl a part le fait que je n'arrive plus a libérer mes textures (ou autre chose : erreur de comprehension de glGenTextures ?) il fonctionne très bien.
Merci à tous !
PS :
J'ai essayé de passer mon ID de texture en paramètre par pointeur (en référence ca devrai faire pareil) mais même soucis avec un delete en fin. Je commence a me dire qu'il faut générer toute mes texture avant les afficher et les effacer dans la foulé et a chaque boucle... car le seul endroit ou j'arrive a les supprimer et après leur création.
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 void surface2Texture(SDL_Surface *surface, GLuint * IDtexture) { // mon ID texture et des variable pour le traitement GLuint texture ; GLenum texture_format; GLint nOfColors; // get the number of channels in the SDL surface nOfColors = surface->format->BytesPerPixel; if (nOfColors == 4) // contains an alpha channel { if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGBA; else texture_format = GL_BGRA; } else if (nOfColors == 3) // no alpha channel { if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGB; else texture_format = GL_BGR; } else { //fprintf(stderr,"waring: the image is not truecolor.. this will probably break\n"); } //creation de la texture en memoire glGenTextures( 1, &texture) ; glBindTexture( GL_TEXTURE_2D, texture ); // Set the texture's stretching properties glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // Edit the texture object's image data using the information SDL_Surface gives us glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels ); //!\ Si je fais un glDleteTextures(1,&texture) ici je recupere bien ma memoire mais forcement j'affiche un carre blanc *IDtexture = texture ; glDeleteTextures(1, &texture2) ; }
Partager