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 :

C++ : Problème de libération de texture openGL


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    22
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 22
    Par défaut C++ : Problème de libération de texture openGL
    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 :
    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 ;
     
    }
    Ensuite voila ma fonction d'affichage de texture 2D OPENGL très classique :

    Fonction d'affichage de texutre :
    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 ?!?
    }
    Enfin voila un destructeur d'objet possédant une texture et surface :

    Destructeur d'objet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Entity::~Entity()
    {
        glDeleteTextures(1, &texture) ;
        SDL_FreeSurface(sprite) ;
    }
    Et donc pour tester voila :

    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) ;
     
    }

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    22
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 22
    Par défaut
    Après révision du code je me suis rappelé que ma fonction changeant la couleur des sprite s'exécuté jusqu'à 3 fois (rouge -> couleur x, bleu -> couleur y, vert --> couleur z) du coup en faite je faisais 3 glGenTexture() sur le meme GLuint, et contrairement a ce que je pensais cela n'efface pas la texture, qui n'est pas le GLuint mais une adresse que pointe le GLuint (un peu comme un pointeur).

    Bref en mettant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        glDeleteTextures(1, &id_texture) ;
        glGenTextures( 1, &id_texture)
    Dans mon code de conversion surface vers texture cela va beaucoup mieux niveau mémoire mais j'ai 1 autrs bug..

    - Les textures de mon second menu s'écrasent entre elles...

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    22
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 22
    Par défaut
    Si qulqu'un a la meme erreur....

    Si vous avez un objet avec une texture, n'appelez pas glGenTextures() dans le constructeur pour récupérer l'id de votre texture. En effet, le contecte opengl est pas lancé encore et vous aurez des chiffres delirants et probablement en double au redemarage du compteur de texture d'opengl une fois son contexte initialisé.

    J'ai contourné le soucis avec une methode setTexture que j'execute avant la creation de l'objet et donc une fois le contexte lancé.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème transparence texture (OpenGL + Qt)
    Par killerjeff dans le forum OpenGL
    Réponses: 2
    Dernier message: 25/02/2010, 15h24
  2. Réponses: 15
    Dernier message: 29/03/2008, 15h08
  3. OpenGL: problème pour incorporer des textures
    Par milena dans le forum OpenGL
    Réponses: 5
    Dernier message: 23/03/2008, 17h16
  4. Problèmes de libération de Dll en delphi7 sous windows XP
    Par Tardiff Jean-François dans le forum Langage
    Réponses: 5
    Dernier message: 10/01/2006, 15h30
  5. [Debutant(e)]problème de libération de mémoire
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 10/02/2005, 17h38

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