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

C++ Discussion :

problème de mémoire outils de dessins graphiques


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 6
    Par défaut problème de mémoire outils de dessins graphiques
    tout le monde

    Pour réaliser un programme de cartographie, je dois afficher dans une fenêtre une carte représentée par plusieurs polygones (vecteurs de points). J'ai donc un objet CARTEVECTORIELLE contenant un vecteur d’objet ZONE. Un objet ZONE contient 2-3 infos (string, int, … ) et … le polygone à tracer.

    A chaque rafraîchissement de la fenêtre, je retrace toute la carte. Or, au bout d'un certain nombre de rafraîchissement de la fenêtre (événement WM_PAINT), mes polygones qui étaient avant dessinés pleins ne sont dessinés que par leurs bordures.
    En plus, il devient impossible de faire des « imprim écran » parce qu’il me dit qu’il manque de mémoire.

    En supprimant des lignes tour à tour, il s’avère que c’est l’appel des 4 lignes suivantes qui font exploser la consommation de mémoire et génère le bug (on passe de 5000ko à 5300ko en une cinquantaine de rafraîchissements, 5300ko il jette l’éponge) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    hbrush =CreateHatchBrush(6,couleur);
    SelectObject(hdc,hbrush); 
     
    hpen=CreatePen(0,0,couleur);
    SelectObject(hdc,hpen);

    Auriez vous une solution miracle ? Est-ce que le problème vient vraiment de là ou vous pensez que déjà, à votre avis, il y a des choses à corriger dans mes méthodes de dessin ?

    Voici le code pour tracer la carte (c’est la méthode ‘tracer’ de la carte vectorielle qui est appelée dans le block case WM_PAINT: … break ; )
    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
     
    void CarteVectorielle::tracer(HDC hdc,CanevasMercator* cm)
    {
                HBRUSH hbrush;
    	HPEN hpen;
    	for (int i=0;i<zones.size();i++)
         {
    		COLORREF couleur=zones.at(i).getColor();
    		hbrush =CreateHatchBrush(6,couleur); //les 4 lignes qui font planter
    		SelectObject(hdc,hbrush); 
     
    		hpen=CreatePen(0,0,couleur);
    		SelectObject(hdc,hpen);
     
    		zones.at(i).tracer(hdc,cm);
         }
    }
     
    void zone::tracer(HDC hdc,CanevasMercator* cm)
    {
         Polygone* ptemp=new Polygone();
         *ptemp = cm->projette(polygone); // projette le polygone dans un canevas de mercator
         ptemp->tracer(hdc);
         delete ptemp;
    }
     
    void Polygone::tracer(HDC hdc)
    {
            POINT pt;
            POINT *p=new POINT[nbpoints+1];
            for (int i=0;i<points.size();i++)
            {
                pt=POINT();
                pt.x=points.at(i).x;
                pt.y=points.at(i).y;
                p[i]=pt;
            }
            Polygon(hdc,p,nbpoints);
            delete p;
    }
    En vous remerçiant par avance pour vos idées

    marco

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    A chaque appel à tracer puis pour chaque tour de boucle tu crées deux nouveaux objets hbrush et hpen.
    Outre le fait que c'est vraisemblablement particulièrement inefficace (il faudrait sans doute les créer une seule fois pour toute), et sans trop connaitre ces fonctions, je me doute qu'il faut les détruire quand on n'en a plus besoin...

    D'ailleurs c'est marqué là : http://msdn2.microsoft.com/en-us/library/ms532561.aspx
    Citation Envoyé par MSDN
    When you no longer need the brush, call the DeleteObject function to delete it.
    Sinon tu en crées, tu en crées, tu en crées, etc....

    MAT.

  3. #3
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Ah sinon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    POINT *p=new POINT[nbpoints+1];
    ...
    delete p;
    C'est incorrect, ça, jette un oeil dans la FAQ à Comment libérer un tableau alloué dynamiquement.

    Et puis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Polygone* ptemp=new Polygone();
    *ptemp = cm->projette(polygone); // projette le polygone dans un canevas de mercator
    ptemp->tracer(hdc);
    delete ptemp;
    C'est aussi à moitié surréaliste
    Je ne sais pas ce que renvoit projette mais sans doute que ça serait plus simple ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cm->projette(polygone).tracer(hdc);
    Bon ou si tu tiens vraiment à la variable intermédiaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Polygone temp(cm->projette(polygone));
    temp.tracer(hdc);

    MAT.

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    (désolé pour le spam...)

    J'avais pas fait gaffe mais ça aussi c'est bien alambiqué :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    POINT pt;
    POINT *p=new POINT[nbpoints+1];
    for (int i=0;i<points.size();i++)
    {
    pt=POINT();
    pt.x=points.at(i).x;
    pt.y=points.at(i).y;
    p[i]=pt;
    }
    Ca se fait beaucoup plus simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    POINT *p=new POINT[nbpoints+1];
    for (int i=0;i<points.size();++i)
      p[i]=points[i];
    D'ailleurs au passage ça ne vérifie pas trop que nbpoints vaut points.size()...

    Mais bon dans l'absolu il faudrait sans doute que le constructeur de Polygon prenne un vecteur de points directement plutôt qu'un tableau + sa taille.

    MAT.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 6
    Par défaut
    Merci pour tes conseils MAT.
    C'est vrai, j'ai zappé les crochets pour libérer la mémoire d'un tableau dynamique. Grossière erreur, en plus c'était dans mon bouquin... aucune excuse.
    Pour les HBRUSH / HPEN, les supprimer à chaque iterration a été une bonne solution. Par contre si j'en fait un pour tous mes tracés et que je le supprime à la fin, la ça ne passe plus. Enfin bon, l'essentiel c'est que ça marche.

    Autre chose, je suis en fait en train de passer un ancien projet java en C++ et il se trouve que ces méthodes de tracés sont beaucoup plus lentes que celles en java (pourtant équivalentes du point de vue du code). Connais tu des tuyau pour accélerer tout ça ? Pourtant je vois pas comment je pourrais simplifier plus les méthodes, surtout élaguées comme tu me l'as trés justement suggéré.

    ++
    Marco

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Désolé, je connais très peu l'API Windows, peut-être aurais-tu plus de chance dans la section du forum sur la programmation Windows ?

    MAT.

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

Discussions similaires

  1. [Crystal Report]Problème de mémoire avec le moteur RDC
    Par sur_uix dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 26/05/2005, 09h09
  2. Problème de mémoire avec BDE
    Par Machuet dans le forum Bases de données
    Réponses: 3
    Dernier message: 13/07/2004, 10h11
  3. Problème de mémoire Affichage images
    Par Repti dans le forum C++Builder
    Réponses: 6
    Dernier message: 29/03/2004, 20h06
  4. Réponses: 2
    Dernier message: 29/03/2004, 18h29

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