Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

GRAPHIQUE UTILISANT LE DOUBLE BUFFERING (ENLÉVE L'EFFET DE CLIGNOTEMENT)


Information sur la source

Catégorie :Graphique Source .NET ( DotNet ) Classé sous : doublebuffering, graphique, clignotement, image, gdi Niveau : Débutant Date de création : 10/10/2007 Date de mise à jour : 08/04/2008 15:36:09 Vu / téléchargé: 7 561 / 404

Note :
9,6 / 10 - par 5 personnes
9,60 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (21)
Ajouter un commentaire et/ou une note

Description

Cliquez pour voir la capture en taille normale
Beaucoup se demande pourquoi l'image clignote dès que l'on surcharge un peu trop un graphique, et surtout comment éviter cela.

Eh bien cette source montre comment résoudre ce problème en utilisant le "Double buffering", grâce à la classe .NET "BufferedGraphics"

Cette source redonne de l'espoir à tous ceux qui croyaient (à tords) que le GDI++ était une librairie mal étudiée et lente par-dessus tout.

Pour illustrer le problème de la lenteur j'ai décidé d'ajouter des formes de toutes les couleurs s'agitant dans un panel, le nombre de fps souhaités est réglable et le nombre de formes dessinées à l'écran s'adaptent automatiquement, j’atteins pour ma part ~40-50 FPS avec 100 formes dessinées.

J'ai choisi de commenter mon code au maximum pour qu'il soit accessible à tous.
 

Source

  • Public Class Form1
  • ''' C'est le graphique avec lequelle on va dessiner dans un premier temps, puis afficher
  • Private BufferredGraphic As BufferedGraphics
  • ''' C'est l'objet qui permet d'allouer de la mémoire tampon pour stockage du bitmap de dessin
  • Private CurrentContext As BufferedGraphicsContext
  • Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  • 'On alloue la mémoire tampon de dessin
  • BufferredGraphic = Me.CurrentContext.Allocate(Me.CreateGraphics(), Me.DisplayRectangle)
  • End Sub
  • Private Sub Dessin()
  • 'On dessine dans la mémoire
  • BufferredGraphic.Graphics.Clear(Color.White)
  • 'Déclenche l'évenement OnPaint de la fenêtre
  • Me.Form1_Paint(Me, New PaintEventArgs(Me.BufferredGraphic.Graphics, Me.Form1.DisplayRectangle))
  • End Sub
  • Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Form1.Paint
  • 'Affiche enfin à l'écran le graphique contenue dans la mémoire, de manière persistante
  • BufferredGraphic.Render()
  • End Sub
  • End Class
   Public Class Form1

        ''' C'est le graphique avec lequelle on va dessiner dans un premier temps, puis afficher
        Private BufferredGraphic As BufferedGraphics

        ''' C'est l'objet qui permet d'allouer de la mémoire tampon pour stockage du bitmap de dessin
        Private CurrentContext As BufferedGraphicsContext

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

            'On alloue la mémoire tampon de dessin
            BufferredGraphic = Me.CurrentContext.Allocate(Me.CreateGraphics(), Me.DisplayRectangle)

        End Sub

        Private Sub Dessin()

            'On dessine dans la mémoire
            BufferredGraphic.Graphics.Clear(Color.White)

            'Déclenche l'évenement OnPaint de la fenêtre
            Me.Form1_Paint(Me, New PaintEventArgs(Me.BufferredGraphic.Graphics, Me.Form1.DisplayRectangle))

        End Sub

        Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Form1.Paint

            'Affiche enfin à l'écran le graphique contenue dans la mémoire, de manière persistante
            BufferredGraphic.Render()

        End Sub

    End Class

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

10 octobre 2007 15:54:07 :
petite faute d'ortographe ^^ il y en a suremement plein d'autres je m'en excuse.
11 octobre 2007 16:17:49 :
- Suite à un commentaire, le graphique est maintenant dessiné dans l'événement OnPaint. - Encore des fautes d'orthographes ;)
11 octobre 2007 16:19:33 :
Suite à un commentaire, le dessin de graphique se fait maintenant dans l'événement OnPaint.
11 octobre 2007 18:32:22 :
Mise a jour de la source exemple.
02 avril 2008 23:09:12 :
Suite aux commentaires : - Utilisation de la classe BufferedGrahics (Gain de 10fps) et quelques autres améliorations : - Optimisation du nombre de formes dessinées a l'écran en fontion des FPS. - Ajout d'un icône - Utilisation de la compliation conditionnelle pour choisir le mode de fonctionement A venir : - Adaptation en écran de veille (complet, avec aperçu) - Amélioration de la fonction de dégradé
03 avril 2008 18:22:04 :
Ajout d'une classe dégrader, qui permet de mieu gérer les couleurs, et de créer ses propres dégradés. cette classe est Serializable pour pouvoir sauvergarder et charger les dégradés créés
03 avril 2008 18:24:59 :
Ajout d'une classe dégrader, qui permet de mieu gérer les couleurs, et de créer ses propres dégradés. cette classe est Serializable pour pouvoir sauvergarder et charger les dégradés créés
03 avril 2008 18:30:33 :
Correction d'une erreur
03 avril 2008 18:33:09 :
Mise a jour de la capture.... lol
03 avril 2008 19:34:37 :
Re modification de la capture, je m'y prend comme un pied...
07 avril 2008 20:26:54 :
Suite à un commentaire: - Lissage des FPS (avec moyenne glissante) Et: - Suppression de la compilation conditionelle car inadapté - Optimisation du chargement des dégradés (passage en Shared) - Lorsque on appuis sur la touche espace les informations sur les formes s'affichent
08 avril 2008 15:36:10 :
Optimisation dans l'affichage des couleurs. La palette n'est calculée qu'une seul fois pour toutes les formes.

Commentaires et avis

signaler à un administrateur
Commentaire de FREMYCOMPANY le 10/10/2007 19:27:38 8/10

Intéressant !

Dommage que tu ne donne pas d'exemple concret utilsant l'évènement onPaint ;)

signaler à un administrateur
Commentaire de guillaume1136 le 10/10/2007 20:09:54

C'est ce que je voulais faire au départ mais à ma grande déception lorsque on déssine sur avec l'événement OnPaint l'image clignote à nouveau...

Explication: au déclanchement de l'évenement OnPaint le graphique est effacer.
Le temps que l'on affiche notre image, une image toute blanche qu vien se glisser.
Cela est du au taux de rafraichisement de l'écran, le temps entre l'effacement du graphique et l'affichage de notre image éxéde le temps qu'il faut à l'écran pour afficher une image, d'ou l'image blanche.

Il est dailleur interessent de constater que plus l'instruction avant l'affichage de notre image est longue plus le temps d'affichage de l'image blanche est long.

J'espère que mon explication est compréhensible.

Tu peu t'en faire la démonsration en ajoutant le sub :

    Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
        e.Graphics.DrawImage(Me.BackBuffer, 0, 0)
    End Sub

et en suprimant le : Viewable.DrawImageUnscaled(BackBuffer, 0, 0)
a la fin du Sub Timer1.Tick



signaler à un administrateur
Commentaire de guillaume1136 le 10/10/2007 20:12:38

Excuse moi j'ai oublier.

Pour que la demonstration ci-dessus marche il faut aussi ajouter Me.Panel1.Refresh()
a la fin du Sub Timer1.Tick

signaler à un administrateur
Commentaire de Adn56 le 11/10/2007 08:14:27

salut, je vais de ce pas étudier ton code,
mais perso je fais tout un tas de dessin dans le forms.paint et cela ne clignote pas. J'ai positionné le double buffer dans les propriétés et j'utilise un invalidate() à la place du refresh().
Conclusion, cela reste tout de même assez chaud pour un noob comme moi de trouver une méthode fiable et passe partout pour simplement faire un dessin -_-'
Merci pour ta source qui devrait me permettre d'avancer un peu. ++

signaler à un administrateur
Commentaire de Adn56 le 11/10/2007 11:59:01

le code est tres bien commenté, mais en revanche j'ai un bug de nom trop long !

Erreur 1 Impossible d'écrire dans le fichier de sortie "obj\Debug\Double_Buffered_Panel_Exemple.Resources.resources". Le chemin d'accès spécifié, le nom de fichier ou les deux sont trop longs. Le nom de fichier qualifié complet doit comprendre moins de 260 caractères et le nom du répertoire moins de 248 caractères. Double Buffered Panel Exemple
et ce trois fois de suite, plus un plantage du Svhost au lancement de VB studio, cela sens l'archive conrompue ! Peux tu la DL et regarder cela ? merci +++

signaler à un administrateur
Commentaire de Adn56 le 11/10/2007 12:02:59

Ok dsl, j'ai trouvé ^^ il suffit de raccourcir le nom de ton dossier ou de le placer vers un chemin plus cours (style C:\soft\ et non pas c\docu & sett\utilisateur\bureau\prog....qui prends plus de 260 caractéres :p)

signaler à un administrateur
Commentaire de guillaume1136 le 11/10/2007 16:14:30

Tout d'abord merci de tes commentaires,

Je viens de tester de déclencher l'événement OnPaint à partir de Panel1.Invalidate ()
mais le problème reste apparemment le même chez moi le graphique clignote toujours.

En revanche la solution pour déclencher cet événement sans que son graphique soit effacé est d'appeler l'événement en lui passant les bons paramètres:

Me.Panel1_Paint(Me, New PaintEventArgs(Viewable, New Rectangle(0, 0, Me.Panel1.Width, Me.Panel1.Height)))

J'ai mis à jour ma source avec ceci.

signaler à un administrateur
Commentaire de TigerFab le 11/10/2007 19:39:22 10/10

Bravo, bel exemple concret et efficace ! 10/10 pour moi

signaler à un administrateur
Commentaire de Adn56 le 11/10/2007 19:54:45 10/10

+10 pour moi aussi (même si j'ai pas encore tout pigé au code lol, j'suis trop noob ^^)

signaler à un administrateur
Commentaire de apxa le 11/10/2007 20:26:15

iop all,
C'est très bien ca.
De toute facon il est bien connu que le principe de double buffering s'avere le plus efficace pour une fluidité d'animation.

Have Fun ;)

signaler à un administrateur
Commentaire de Arnal88 le 13/10/2007 15:43:05

Bon programme. C'est vraiment bien fait.

J'ai pour ma part déjà été confronté au scintillement, et j'ai trouvé la solution dans l'aide MSDN. Mais le mécanisme de double buffer qu'elle décrit n'est pas le même que le tien.

Ton programme utilise deux Graphics, un en liaison avec un Bitmap pour dessiner dedans, et l'autre en liaison avec la surface de la Form pour transférer l'image à l'écran.

Le mécanisme que j'avais trouvé est le suivant :

''' Initialisation :
  Dim currentContext As BufferedGraphicsContext
  Dim myBuffer As BufferedGraphics

  currentContext = BufferedGraphicsManager.Current

  myBuffer = currentContext.Allocate(Me.CreateGraphics, Me.DisplayRectangle)
  myBuffer.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality

''' On effectue les opérations de dessin
  myBuffer.Graphics.Clear(Color.LightYellow)
  myBuffer.Graphics.DrawRectangle(Pens.Blue, 10, 50, 60, 100)

''' On transfère ensuite le contenu de la mémoire tampon à l'écran
  myBuffer.Render()

Je tire cet exemple d'ici :
http://msdn2.microsoft.com/fr-fr/library/b367a457(VS.80).aspx
http://msdn2.microsoft.com/fr-fr/library/ka0yazs1(VS.80).aspx

Avec ce mécanisme, on utilise vraiment une mise en mémoire tampon. C'est donc plus rapide et moins gourmand en ressources processeur.

Essaye de te pencher là dessus, mais je suis sûr que tu peux encore accélérer ton prog avec cette méthode.

signaler à un administrateur
Commentaire de guillaume1136 le 13/10/2007 18:01:43

Merci de ton commentaire.

Ta méthode est très interressante, et bien plus logique au niveau de se qui se passe en mémoire en effet, c'est se que je voulait faire avec ma source, mais je m'en été juste aproché.

Je vais mettre à jour ma source avec ta méthode, j'ai constaté son efficacité avec ta source sur la chimie, c'est du joli boulot !!

signaler à un administrateur
Commentaire de Arnal88 le 13/10/2007 20:26:54

Merci pour tes encouragements..
Et bon courage pour la mise à jour de ta source...

signaler à un administrateur
Commentaire de Ahweb le 14/10/2007 21:08:04

Excellente source ;)

J'attendrai moi aussi la mise à jour :)

signaler à un administrateur
Commentaire de Arnal88 le 05/04/2008 17:48:35 10/10

Salut!

C'est cool que t'ai mis à jour ton code.
Excellent code.

Mais j'ai pas gardé l'ancienne version.. Est-ce que tu as constaté une augmentation du FPS ?
Ou alors tu as aussi changé ce qui doit être affiché... Il y avait déjà la transparence des formes ?

Sinon une dernière suggestion :
La valeur du FPS change vraiment rapidement, c'est impossible à lire.
Essaye de la stabiliser en faisant une "moyenne glissante" sur les 100 dernières valeurs par exemple. Cette moyenne devrait changer moins vite..

En tout cas, pour moi, c'est 10/10

signaler à un administrateur
Commentaire de guillaume1136 le 06/04/2008 12:49:33

Salut

Merci, on peu dire que j'ai mis le temps sa fesait 6 mois que je devais le faire.
Oui en effet il y a une augmentation d'environ 10 fps.
Sinon le contenu dessiné est resté le même, il y avais déja la transparence des formes.
Par contre il y a une nouvelle classe pour l'affichage des couleurs.

Merci pour ta suggestion je vais corriger ça, et merci pour tes encouragements.



signaler à un administrateur
Commentaire de The Meteorologist le 01/06/2008 15:37:59

Bonjour guillaume1136,
Chez moi les polygones sont tous en noir et blanc ? Est-ce un bogue ou est-ce normal ?

Simon

signaler à un administrateur
Commentaire de The Meteorologist le 01/06/2008 15:44:43 10/10

Je n'ai pas pris assez le temps de regarder le code excuse-moi, ça m'a juste surpris en ayant vu la capture. En tout cas c'est très intéressant, je passais toujours par la case C++ pour programmer mes jeux étant donné que le rendu était toujours horrible avec GDI+. Maintenant j'y réfléchirais à deux fois, merci.

Simon

signaler à un administrateur
Commentaire de guillaume1136 le 03/06/2008 20:54:10

Bonjour, merci pour tes commentaires, en faite oui c'est normal, pour que les formes soit en couleur tu dois changer la ligne suivante : Private Const DEGRADE_NAME As String = "Black and White" par Private Const DEGRADE_NAME As String = "Arc en ciel", elle se trouve dans le fichier FormMain, ligne 20. Oui d'autant plus que certaines fonctions du GDI+ sont très puissantes, comme celle qui permet de faire des dégradés dans un polygone, mais il n'y a pas d'exemple dans cette source.

signaler à un administrateur
Commentaire de nicolassan551 le 03/07/2008 16:19:08

oui, joli boulot Guillaume :)

c'est interessant de voir que l'on peut faire une animation sympa avec GDI+, je vais peut être me décider, j'hésitais entre wpf et directX !

Le code est propre, c'est sympa !

signaler à un administrateur
Commentaire de larryj le 28/07/2008 13:13:28

merci beaucoup pour cette source
Ça va me permettre de terminé ma petite application.
10/10

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Sorties graphiques un un picture [ par paskal ] 'Jour m'sieurs et dams...Une petite question très bête : Sur une feuille, j'ai une 'image' placée dans un 'frame'....L'action d'un bouton également su Comment enregistrer une forme en une image de type graphique (bmp,jpg...) ? [ par muzza ] Question dans le sujet merci Graphique [ par simofid ] Je me demande comment changer la taille d'une image, ex:Nous avons une image (foto.jpg) de taille 800x600 et nous voulons transformer sa taille et la Image et graphique [ par ERICVB7 ] Bonjour,Je programme en VB.NET (sous XP) et je cherche un code source me permettant de remplir une zone de couleur uniforme dans une image (type bitma Comment enregistrer une form en une image de type graphique (bmp,jpg...) ? [ par sbouquet ] Ben voila la question est dans le sujet, j'ai vu qu'elle avait deja était posée de la meme facon mais personne n'avait repondu et comme j'ai le meme p [GDI / GDI+] Besoin d'aide urgent [ par lcprog ] Salut tout le monde!Alors si quelqu'un pouvait me sauver la vie, je bloque sur un problème depuis bientot 20h...j'utilise l'api gdi+je voudrai récupér MSCHART, comment supprimer le clignotement ? [ par denis21 ] Bonjour à tous, je souhaite faire un graphique à l'aide du composant MSCHART, ce graphique doit etre en temps reel !Et c'est là le probleme, qd j'ai Exporter un graphique excel [ par Draconagi ] Voila j'ai un document excel sur lequel il y a plusieurs tableaux et je g&#233;n&#233;re un graphique &#224; partir de ceux la. Le graphique est sur s Sauver, restaurer image graphique ecran Vb2005 [ par alainvolatile ] Bonjour &#224; tous, <P class=MsoNormal style="MARGIN: 0cm Comment exporter un graphique en fichier image ? [ par GetheBeber ] Bonjour &#224; tous,Malgr&#233; bien des efforts, je n'arrive pas &#224; trouver comment exporter un graphique (contr&#244;le MSChart) en fichier imag


Nos sponsors

Sondage...

CalendriCode

Janvier 2009
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,452 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.