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

wxWidgets Discussion :

Technique de positionnement de l'image


Sujet :

wxWidgets

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 40
    Points : 19
    Points
    19
    Par défaut Technique de positionnement de l'image
    Bonjour à tous,

    J'ai développé sous wxwidgets 3.02 (+rad wxsmith et sous code::blocks 13.12 en C++), une petite application de calculs et de visualisations de surfaces mathématiques en 3D.

    Lorsque que je veux changer par exemple un paramétre de la position du point de vue, j'appuie sur une touche spécifique du clavier, et la surface est effacée (refresh du panel),
    recalculée puis réaffichée en fonction du nouveau paramétre ( fonction onpaint dans le panel d'affichage, appellée par le refresh).

    Ce procédé est consommateur de temps machine puisque la surface est recalculée pour un nouveau point de vue . Cela induit un effet de scintillements à l'écran, du à l'effacement suivit du réaffichage de l'image.

    Or, lorsque je vais sur des logiciels professionnels à caractéres mathématiques tels que scilab ou xcas, j'observe que l'on peut instantanément repositionner une surface mathématique 3D à la souris,
    en maintenant enfoncée la touche gauche de la souris. L'image de la surface semble alors se déplacer de maniére totalement fluide, comme si elle n'était pas recalculée.
    Il suffit de relacher la touche de la souris pour fixer l'image de la surface à sa nouvelle position.

    Quelqu'un pourrait-il tenter au moins de m'éclairer sur le genre de technique utilisée (bufférisation ? mais comment ?) afin de parvenir à ce type d'effet visuel svp ?
    Ensuite j'essaierai de me documenter.

    Par avance merci

  2. #2
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations forums :
    Inscription : Février 2006
    Messages : 562
    Points : 859
    Points
    859
    Par défaut
    Bonjour.

    Les logiciels de rendu 3D utilisent généralement OpenGL via wxGLCanvas https://wiki.wxwidgets.org/WxGLCanvas
    Pour éviter le scintillement, wxGLCanvas applique le procédé du DoubleBuffering qui consiste à dessiner des scènes 3D dans un buffer avant de les afficher à l'acran.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 40
    Points : 19
    Points
    19
    Par défaut
    Ok, merci pour votre réponse.
    Je me doutais bien qu'il y'avait forcément une technique de bufférisation.
    A présent, je vais tacher d'en savoir plus pour essayer de l'appliquer à mon appplication.
    Jc

  4. #4
    Futur Membre du Club
    Homme Profil pro
    administrateur Unix
    Inscrit en
    Août 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : administrateur Unix

    Informations forums :
    Inscription : Août 2011
    Messages : 6
    Points : 8
    Points
    8
    Par défaut
    Bonjour,

    Si, pour dessiner tes graphes, tu n'utilises pas OpenGL, mais plutôt wxDC, alors wxWidgets propose des classes qui gèrent automatiquement ce système de buffering :

    class wxBufferedDC
    This class provides a simple way to avoid flicker: when drawing on it, everything is in fact first drawn on an in-memory buffer (a wxBitmap) and then copied to the screen, using the associated wxDC, only once, when this object is destroyed...


    Personellement, j'utilise la classe wxAutoBufferedPaintDC, et je n'ai aucun problème de scintillement.

    A+
    Buzz.

  5. #5
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut
    Bonjour.

    Je pense que le problème n'est pas forcément dû uniquement à l'affichage de l'image : le calcul peut également prendre du temps.

    Il faut donc peut-être revoir le mode de fonctionnement : n'effacer l'image affichée pour redessiner la nouvelle que lorsque cette dernière est déjà calculée.

    Autre possibilité : avoir en mémoire une image plus grande que celle qui est affichée : ainsi, l'affichage après déplacement pourrait être instantané, et l'image en mémoire serait mise à jour en arrière plan.

    Ce ne sont que des possibilités à éventuellement tester.

    @+
    Xav'

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 40
    Points : 19
    Points
    19
    Par défaut
    Merci pour vos réponses pertinentes.

    En effet, les calculs sont assez lourds pour le calcul d'une surface (fonctions à 2 variables).
    Je viens de faire trois choses essentielles aprés investigations, et qui semblent donner de trés bons résultats en termes de fluidité et suppriment les scintillements :

    1. J'utilise wxBufferedPaintDC dc(Panelxx, wxBUFFER_CLIENT_AREA) dans la fonction principale OnPanelxxPaint() qui appelle le dessin de l'image.

    2. J'appelle une fonction de 'blanchiment' du fond de panel, à savoir PaintBackGroundPanel(wxDC& dc), trouvée à la page 137 du livre de Julian Smart (Cross-Platform GUI prog. with wxWidgets).

    3. Comme j'ai pu le lire dans le livre et sur le forum, je redéfini la fonction OnEraseBackground(wxEraseEvent& event) à vide aprés l'avoir connectée à l'appli afin d'éviter un effacement inutile du fond de plan et supprimer les scintillments.

    J'aurais encore deux questions :

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 40
    Points : 19
    Points
    19
    Par défaut
    Excusez moi, je pose mes questions complémentaires :

    1. Que fait la classe wxAutoBufferedPaintDC par rapport à la classe wxBufferedPaintDC ?

    2. Aprés appel à la fonction de blanchiment du fond j'observe un probléme de décalage de la poisition de l'image en mode fenetrée aprés un resize de la fenetre.
    Je pense que ce problème viens du fait que je n'arrive pas à appeller la fonction CalcUnscrolledPosition (référence irrésolue).
    Pourtant je fait bien le #include <wx/dcbuffer.h> censé contenir la definition de son prototype.
    A titre indicatif, voici le code de la fonction de blanchiment de fond :

    #include <ApplioutilsgensgraphMain.h>
    #include <wx/scrolwin.h>

    //
    void ApplioutilsgensgraphFrame:aintBackGroundPanel(wxDC& dc)
    {

    wxColour backgroundColour( GetBackgroundColour() );

    if (!backgroundColour.Ok()) backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);

    dc.SetBrush(wxBrush(backgroundColour));

    dc.SetPen(wxPen(backgroundColour,1));

    wxRect PanelRect(wxPoint(0,0),GetSize());

    // **** CalcUnscrolledPosition = REFERENCE IRRESOLUE POUR LE MOMENT !! *********************************
    // CalcUnscrolledPosition(PanelRect.x, PanelRect.y, & PanelRect.x, & PanelRect.y);

    dc.DrawRectangle(PanelRect);

    }

    Merci et bonne journée
    jcmic

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 40
    Points : 19
    Points
    19
    Par défaut
    Rectification : Je fait <wx/scrolwin.h> pour référencer CalcUnscrolledPOisition, mais la compil ne le voit quant meme pas.

  9. #9
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut
    Salut.
    Citation Envoyé par jcmic Voir le message
    Rectification : Je fait <wx/scrolwin.h> pour référencer CalcUnscrolledPOisition, mais la compil ne le voit quant meme pas.
    Si l'erreur que tu obtiens est un problème de référence non résolue, ce n'est pas un problème avec le compilateur, mais avec le linker. L'inclusion (ou non) du header "scrolwin.h" ne changera rien.

    Est-ce que c'est la seule erreur que tu obtiens ?
    Quelle version de wxWidgets utilises-tu, et avec quel compilateur ?

    @+
    Xav'

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 40
    Points : 19
    Points
    19
    Par défaut
    Bonjour,

    Merci pour ta réponse,

    Non c'est bien un problème de compilation, en fait je m'était mal exprimé, et mon message était ambigue .

    Le compilateur dit bien que 'CalcUnscrolledPosition was not declared in this scope', et ce malgré la présence de include <wx/scrolwin.h>

    J'utilse wxwidgets 3.02 sous code::blocks 13.12 (windows 7) et le compilateur est GNU CC COMPILER (avec option -std=gnu++11 dans compiler settings).

    En fait je me demande si mon problème de cadrage viens de là, car en réalité je ne suis pas trés clair sur la notion de scrollablewindow.

    Le cadrage(centrage) de la surface ne se fait pas correctement lorsque je réduit la fenetre de l'application aprés l'avoir agrandie.
    Le centrage se maintenait bien lorsque j'utilisait la classe wxPaintDC au lieu de la classe wxBufferedPaintDC dans la fonction OnPaint().

    Mais je vais réfléchir à ce pb.

    J'aurai quant meme aimé tester l'impact éventuel à l'appel de CalcUnscrolledPosition.

    jcmic

  11. #11
    Futur Membre du Club
    Homme Profil pro
    administrateur Unix
    Inscrit en
    Août 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : administrateur Unix

    Informations forums :
    Inscription : Août 2011
    Messages : 6
    Points : 8
    Points
    8
    Par défaut
    voici la réponse à ta question 1/ : La différence entre wxBufferedPaintDC et cette classe est que cette classe ne fera pas double-buffering sur les plateformes qui le font déjà en natif.

    A+
    Buzz

  12. #12
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Décembre 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 214
    Points : 354
    Points
    354
    Par défaut
    À voir le code que tu as posté précédemment, la fonction à partir de laquelle tu appelles CalcUnscrolledPosition appartient à ta classe dérivée de wxFrame, et non à une classe dérivée de wxScrolledWindow.
    C'est donc normal que tu ne puisses pas faire un appel direct à CalcUnscrolledPosition.

    Il faut que tu le fasses avec un pointeur vers ta classe dérivée de wxScrolledWindow (ou ton objet wxScrolledWindow).
    D'ailleurs, c'est pareil pour le GetSize qui précède : tel quel, tu récupère la taille de la fenêtre.

    @+
    Xav'

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 40
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Buzz57 Voir le message
    voici la réponse à ta question 1/ : La différence entre wxBufferedPaintDC et cette classe est que cette classe ne fera pas double-buffering sur les plateformes qui le font déjà en natif.

    A+
    Buzz
    Trés bien merci. Donc je garde le wwBufferedPaintDC . A+

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 40
    Points : 19
    Points
    19
    Par défaut
    Ok, le problème est résolu, et merci pour m'avoir fait remarqué que le GetSize() fournissait la taille de la fenetre et non de la zone client.

    C'est la raison pour laquelle mes calculs étaient faussés à la base, car mes transformations mathématiques travaillaient sur un rectangle de dimension incorrect.
    Je me demande meme comment ça pouvait fonctionner avant (sous wxPaintDC).

    En résumé, j'ai remplacé l'appel à GetSize() par un appel à GetClientSize() et moyennant un leger facteur d'ajustement théorique, je voit l'origine de mon repére absolu 3D constamment positionné
    au centre de sa fentere applicative, et ce quelle que soit la dimension de la fenetre.

    A+
    jcmic

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

Discussions similaires

  1. Problème technique pour la lié une image bitmap
    Par Jace le programmeur dans le forum Access
    Réponses: 1
    Dernier message: 22/05/2007, 16h11
  2. Positionnement Texte dans Image
    Par mulot49 dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 26/04/2007, 14h32
  3. Positionnement de deux images
    Par pierreonxbox dans le forum Balisage (X)HTML et validation W3C
    Réponses: 24
    Dernier message: 15/06/2006, 15h46
  4. [CSS] positionnement d'une image
    Par S~C dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 09/06/2006, 09h46
  5. [HTML][débutante] Positionnement fixe d'image
    Par khany dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 08/11/2004, 18h01

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