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

GTK+ avec C & C++ Discussion :

Comment fonctionne gtk_widget_queue_draw_area()


Sujet :

GTK+ avec C & C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre confirm�
    Homme Profil pro
    chercheur
    Inscrit en
    D�cembre 2012
    Messages
    195
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : chercheur

    Informations forums :
    Inscription : D�cembre 2012
    Messages : 195
    Par d�faut Comment fonctionne gtk_widget_queue_draw_area()
    Bonjour � tous,

    Ma question aujourd'hui est juste aliment�e par ma curiosit� personnelle. J'utilise (abondement) gtk_widget_queue_draw_area() pour �crire des codes au cours desquels je fait bouger des choses (en cin�matique) sur une drawing area. Ca marche tr�s bien, mais je ne comprends pas (et suis �pat� par) comment cette fonction gtk_widget_queue_draw_area() fonctionne algorithmiquement (je veux dire, comment a t-elle �t� cod�e par les d�veloppeurs de GTK).

    Prenons un exemple, et imaginons que j'ai une drawing area carr� de 500 sur 500 pixels. Sur cette drawing area j'ai plusieurs centaines de lignes de code qui conduisent � y dessiner progressivement des choses (une s�rie de pixels, de diff�rentes couleurs, etc.). A un certain moment, dans une zone identifi�e de - disons 10 sur 10 pixels - quelque chose change de place, et j�appelle donc gtk_widget_queue_draw_area() sur cette zone particuli�re pour la r�actualiser. Comment cette fonction fait-elle pour redessiner correctement cette zone ? Comment "sait-elle" ce qui a chang� ou pas ? Il n'est pas possible que l'ensemble de la chaine algorithmique qui ait abouti � ce qui est pr�sent ou pas dans cette zone soit recalcul�e.

    Il y a quelque chose qu'il m'�chappe ici (peut-�tre quelque chose de simple et �vident?), et je suis preneur d'une explication.

    Encore une fois, juste pour assouvir ma curiosit�.

    Cordialement, Eric.

  2. #2
    Expert confirm�
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    F�vrier 2008
    Messages
    2 315
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 55
    Localisation : France, C�te d'Or (Bourgogne)

    Informations professionnelles :
    Activit� : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 2 315
    Billets dans le blog
    5
    Par d�faut
    Bonjour.

    Voila le code source de la dite fonction :
    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
    void
    gtk_widget_queue_draw_area (GtkWidget *widget,
                                gint       x,
                                gint       y,
                                gint       width,
                                gint       height)
    {
      GdkRectangle rect;
      cairo_region_t *region;
      g_return_if_fail (GTK_IS_WIDGET (widget));
      g_return_if_fail (width >= 0);
      g_return_if_fail (height >= 0);
      if (width == 0 || height == 0)
        return;
      rect.x = x;
      rect.y = y;
      rect.width = width;
      rect.height = height;
      region = cairo_region_create_rectangle (&rect);
      gtk_widget_queue_draw_region (widget, region);
      cairo_region_destroy (region);
    }
    Comme tu peux le voir elle cr�e une r�gion puis appelle gtk_widget_queue_draw_region ();. Cela � pour effet d'invalider cette dite r�gion. Lors de l'appel � "expose-event" dans la boucle principale gtk_main(); toutes les r�gions d�clar�es invalides sont redessin�es.

    Dans les faits ta fonction callback attach�e au signal "draw" est appel�e � ce moment l�. Elle va naturellement calculer toute l'image mais seule la r�gion invalide sera actualis�e � l'�cran.

  3. #3
    Membre confirm�
    Homme Profil pro
    chercheur
    Inscrit en
    D�cembre 2012
    Messages
    195
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : chercheur

    Informations forums :
    Inscription : D�cembre 2012
    Messages : 195
    Par d�faut
    Citation Envoy� par gerald3d Voir le message
    Comme tu peux le voir elle cr�e une r�gion puis appelle gtk_widget_queue_draw_region ();. Cela � pour effet d'invalider cette dite r�gion. Lors de l'appel � "expose-event" dans la boucle principale gtk_main(); toutes les r�gions d�clar�es invalides sont redessin�es.

    Dans les faits ta fonction callback attach�e au signal "draw" est appel�e � ce moment l�. Elle va naturellement calculer toute l'image mais seule la r�gion invalide sera actualis�e � l'�cran.
    C'est ce que je pensais, mais j'ai du mal � imaginer que toute l'image soit recalcul�e. La drawing area peut �tre tr�s grande, et la chaine de calcul tr�s longue. Ca prendrait � chaque fois de longues minutes de calcul pour savoir ce qui a chang� ou non. Par ailleurs, si tout �tait recalcul�, le temps d�ex�cution de gtk_widget_queue_draw_area() serait grossi�rement le m�me si je demande de r�actualiser une petite zone ou l'ensemble de la drawing area (sauf le temps de tra�age qui est infime par rapport au temps de calcul qui y aboutie). Il y a quelque chose de pas clair (pour moi en tout cas).

    Eric.

  4. #4
    Expert confirm�
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    F�vrier 2008
    Messages
    2 315
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 55
    Localisation : France, C�te d'Or (Bourgogne)

    Informations professionnelles :
    Activit� : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 2 315
    Billets dans le blog
    5
    Par d�faut
    Voila un petit exemple qui te montre bien que le callback associ� au signal "draw" est appel� � chaque fois.

    C'est d'ailleurs pour cette raison qu'il est d�conseill� de dessiner directement dans ce callback. Il vaut mieux dessiner dans une surface en dehors du callback. Le callback ne sert alors que pour afficher cette surface.

    Code exemple :
    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
    #include <stdlib.h>
    #include <gtk/gtk.h>
     
     
    gboolean drawing_draw_CB (GtkWidget *drawing, cairo_t *cr, gpointer userdata)
    {
      g_print ("appel du callback drawing_draw_CB ();\n");
      return FALSE;
    }
     
    void button_clicked_CB (GtkButton *button, GtkWidget *drawing)
    {
      g_print ("appel du callback button_clicked_CB ();\n");
      gtk_widget_queue_draw_area (drawing, 10, 10, 50, 50);
    }
     
    gint
    main (gint argc, gchar *argv[])
    {
      GtkWidget *window = NULL;
      GtkWidget *box = NULL;
      GtkWidget *drawing = NULL;
      GtkWidget *button = NULL;
     
      /* init gtk */
      gtk_init(&argc, &argv);
     
      /* Création de la fenêtre principale */
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
      gtk_container_add (GTK_CONTAINER (window), box);
     
      /* Création du drawingarea */
      drawing = gtk_drawing_area_new ();
      gtk_widget_set_size_request (drawing, 200, 200);
      g_signal_connect (G_OBJECT (drawing), "draw", G_CALLBACK (drawing_draw_CB), NULL);
      gtk_box_pack_start (GTK_BOX (box), drawing, FALSE, FALSE, 4);
     
      /* Création d'un bouton. À chaque clique on lance gtk_widget_queue_draw_area ();
       * sur le drawing */
      button = gtk_button_new_with_label ("Active queue_draw");
      g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (button_clicked_CB), drawing);
      gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 4);
     
       /* Signaux */
      g_signal_connect (G_OBJECT(window) , "destroy", G_CALLBACK (gtk_main_quit) , NULL);
     
      /* Affichage de la fenêtre */
      gtk_widget_show_all (window);
     
      gtk_main ();
     
      return EXIT_SUCCESS;
    }
    P.S. : gtk_widget_queue_draw(); appelle gtk_widget_queue_draw_area(); pour invalider toute l'image.

  5. #5
    Membre confirm�
    Homme Profil pro
    chercheur
    Inscrit en
    D�cembre 2012
    Messages
    195
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : chercheur

    Informations forums :
    Inscription : D�cembre 2012
    Messages : 195
    Par d�faut
    Oui, merci. J'ai bien compris (je crois). Mais je trouve �tonnant que - donc - l'ensemble de la chaine de calcul (i.e., donc n�cessairement sur l'ensemble de la drawing area) soit recalcul�e � chaque fois, y compris pour r�actualiser une petite zone seulement. En plus du fait que je ne comprenne pas comment GTK fait ceci (en stockant toute la chaine de calcul??), je continue � penser que �a devrait prendre un temps �norme si cette chaine de calcul est longue et compliqu�e (comme c'est le cas dans mes codes), ce qui n'est pas le cas.

    On peut arr�ter cette discussion ici, si n�cessaire, mais �a continue � ne pas �tre clair pour moi.

    Eric.

  6. #6
    Mod�rateur

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par d�faut
    De ce que j'en sais:

    - tu invalides une zone. Si plusieurs �v�nements d'invalidation d'une zone de l'�cran sont dans la boucle d'�v�nements, GTK+ peut les fusionner en un seul d'une zone plus grande si cela a du sens.
    - GTK appelle la callback associ�e au signal "draw". La zone que tu as invalid�e est indiqu�e comme zone de clipping dans le contexte cairo.
    - tu dessines ce que tu veux o� tu veux. C'est � toi de regarder quelles zones sont invalid�es (et ont donc besoin d'�tre redessin�es) si tu veux optimiser ton temps de rendu. Ainsi, peut �tre que tu sais que certains des objects que tu dessines se trouvent hors de la zone de clipping, et tu peux donc par un simple test ignorer tout le code qui permet de dessiner ces objets. le fait qu'il n'y a que la zone de clipping qui sera mise � jour permet � cairo de faire des optimisations : pas besoin de tracer et redessiner ce qui n'est pas visible.
    - une fois tes op�rations de dessin effectu�es, GTK+ demande � cairo d'appliquer la nouvelle image sur l'ancienne, par blitting. Ce blitting se fera uniquement sur la zone de clipping, il n'y a donc qu'elle qui sera modifi�e.
    - une couche de double buffering ? (c'est le cas pour � peu pr�s touts les widgets, mais je ne sais plus si GtkDrawingArea est une exception)
    - Il faut ensuite envoyer la sc�ne � la carte graphique (et le hardware �a prend aussi du temps)

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [JSF] comment fonctionne <h:message> ?
    Par anitshka dans le forum JSF
    R�ponses: 5
    Dernier message: 29/06/2005, 17h36
  2. Comment fonctionne TXmlDocumment ????
    Par almisuifre dans le forum C++Builder
    R�ponses: 8
    Dernier message: 18/02/2005, 12h54
  3. comment fonctionne une interface graphique???
    Par elekis dans le forum Langages de programmation
    R�ponses: 2
    Dernier message: 27/10/2004, 23h10
  4. Comment fonctionne le ClassExplorer ?
    Par borisd dans le forum C++Builder
    R�ponses: 7
    Dernier message: 30/09/2004, 17h44
  5. Comment fonctionne le CVS ?
    Par mathieu dans le forum CVS
    R�ponses: 6
    Dernier message: 23/03/2004, 11h26

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