[C/C++] Histoire de scintillement

Histoire de scintillement [C/C++] - C++ - Programmation

Marsh Posté le 13-02-2003 à 13:55:44    

Comment éviter le scintillement dans une fenêtre GUI ?


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 13-02-2003 à 13:55:44   

Reply

Marsh Posté le 13-02-2003 à 13:56:49    

double buffer

Reply

Marsh Posté le 13-02-2003 à 14:08:21    

Lol ok, mais on fait ça comment ?


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 13-02-2003 à 14:12:59    

ben je suppose que la tu barbouilles directement dans le gdi de ta fenetre, non ? ben t'en fais un autre (de GDI) que tu recopie et heuh, attends, je me perds, me demande si g pas ca qqpart

Reply

Marsh Posté le 13-02-2003 à 14:47:27    

Le double buffer consiste à dessiner l'image dans une zone non visible, puis à chaque début de rafraichissement d'une image écran (VBL), à échanger le contenu de cette zone avec celle affichée à l'écran.
 
Etant donné que le scintillement est provoqué par l'effacement répété de l'écran, le fait d'appliquer cette méthode rend cet effacement invisible (puisque réalisé hors écran).
 
Tu dois récupérer le contexte de la fenêtre, créer une zone de dessin hors écran, puis à chaque VBL faire pointer le contexte de fenêtre avec l'adresse de la zone mémoire hors écran.
 
Il ne te reste plus qu'a appliquer tout ça à Win 32 :)

Reply

Marsh Posté le 13-02-2003 à 14:55:03    

Y'a un exemple dans la msdn.
http://msdn.microsoft.com/library/ [...] licker.asp
Faut simplement créer un bitmap de la taille de ta zone client, et faire un blit lors de WM_PAINT.
Faut aussi dessiner dans le bitmap au lieu de directement dans la fenetre.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 13-02-2003 à 15:15:49    

Si t'es en C++Builder tu fous DoubleBuffer = true; dans le constructeur de ta Form :D


Message édité par antp le 13-02-2003 à 15:16:03
Reply

Marsh Posté le 13-02-2003 à 15:29:16    

Oki merci bien mais je débute en GUI, donc j'aurai aimé un bout de code à utiliser.


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 13-02-2003 à 15:30:01    

ce sont des contrôles usuels qui scintillent?  genre des combos, zones textes, listes, ou bien carrément des images ou animations?
 
Parce que en général, quand une interface commence à scintiller, c'est qu'il est temps de la recoder proprement :whistle:


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
Reply

Marsh Posté le 13-02-2003 à 15:41:30    

Bah là, je met une vidéo dans ma Form et la vidéo scintille quand je redimensionne la fenêtre.


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 13-02-2003 à 15:41:30   

Reply

Marsh Posté le 13-02-2003 à 15:45:02    

Nerocro a écrit :

Bah là, je met une vidéo dans ma Form et la vidéo scintille quand je redimensionne la fenêtre.


ok ma remarque n'est certainement pas valable dans ce cas là alors ;)


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
Reply

Marsh Posté le 13-02-2003 à 16:34:14    

Bon ! en farfouillant dans du vieux code pas beau a moi j'ai ca:
 

Code :
  1. HBITMAP backBuffer;
  2. HWND mainhWnd;
  3. ...
  4. void createBackBuffer()
  5. {
  6. wdc = GetDC(mainhWnd);
  7.  
  8. RECT rect;
  9. GetClientRect(mainhWnd,&rect); 
  10.    
  11. if (backBuffer)
  12. DeleteObject(backBuffer);
  13. backBuffer = CreateCompatibleBitmap(wdc,rect.right,rect.bottom);
  14. dc =CreateCompatibleDC(wdc);
  15. SelectObject(dc,backBuffer);
  16. }


 
tu barbouilles dans dc, et lors du WM_PAINT, tu fais:
 

Code :
  1. case WM_PAINT:
  2.         PAINTSTRUCT paint;
  3.         BeginPaint(hWnd,&paint);
  4.         RECT paintRect;
  5.         paintRect = paint.rcPaint;
  6.         BitBlt(wdc,
  7.             paintRect.left,
  8.             paintRect.top,
  9.             paintRect.right-paintRect.left,
  10.             paintRect.bottom-paintRect.top,
  11.             dc,
  12.             paintRect.left,
  13.             paintRect.top,SRCCOPY);
  14.         EndPaint(hWnd,&paint);
  15.         break;


 
Avec appel a createBackBuffer a chaque WM_SIZE


Message édité par chrisbk le 13-02-2003 à 16:36:23
Reply

Marsh Posté le 13-02-2003 à 17:38:06    

Citation :

Bah là, je met une vidéo dans ma Form et la vidéo scintille quand je redimensionne la fenêtre.

 
 
Ah ! Ca me dit quelque chose ca !
Voici pourquoi je ne met pas les styles CS_VREDRAW et CS_HREDRAW dans mes classes de fenetres. Des que tu redimensionne, ca provoque l'effacement complet de ta fenetre, et ca redessine tout. => Ca clignote.
Sans ces styles, ta fenetre n'est pas effacee quand tu redimensionne. Ca redessine par dessus, on voit pas le fond de la fenetre qui s'efface, ca clignote plus. Comme je n'utilise que des controles (je ne dessine rien lors de WM_PAINT), ces styles me sont d'aucune utilite et je m'en passe sans pblm.
Dans ton cas, apparement tu codes avec une lib genre VCL.
Heu je sais pas trop. Soit y'a possibilite de desactiver ca, soit faut te gerer le message qui efface (WM_ERASEBKGROUND je crois) en l'empechant de faire ce qu'il ets cense faire, ou alors un SetWindowsLong sur ta fenetre pour supprimer ces styles ...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 13-02-2003 à 18:43:12    

HelloWorld a écrit :

Citation :

Bah là, je met une vidéo dans ma Form et la vidéo scintille quand je redimensionne la fenêtre.

 
 
Ah ! Ca me dit quelque chose ca !
Voici pourquoi je ne met pas les styles CS_VREDRAW et CS_HREDRAW dans mes classes de fenetres. Des que tu redimensionne, ca provoque l'effacement complet de ta fenetre, et ca redessine tout. => Ca clignote.
Sans ces styles, ta fenetre n'est pas effacee quand tu redimensionne. Ca redessine par dessus, on voit pas le fond de la fenetre qui s'efface, ca clignote plus. Comme je n'utilise que des controles (je ne dessine rien lors de WM_PAINT), ces styles me sont d'aucune utilite et je m'en passe sans pblm.
Dans ton cas, apparement tu codes avec une lib genre VCL.
Heu je sais pas trop. Soit y'a possibilite de desactiver ca, soit faut te gerer le message qui efface (WM_ERASEBKGROUND je crois) en l'empechant de faire ce qu'il ets cense faire, ou alors un SetWindowsLong sur ta fenetre pour supprimer ces styles ...


 
Pour ce qui est de CS_VREDRAW | CS_HREDRAW, ma fenêtre par défaut ne les utilise pas, donc j'ai pas compris ce que tu voulais dire.


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 13-02-2003 à 18:44:24    

Nerocro a écrit :


 
Pour ce qui est de CS_VREDRAW | CS_HREDRAW, ma fenêtre par défaut ne les utilise pas, donc j'ai pas compris ce que tu voulais dire.


 
ben si tu les utilises pas alors tout ce qu'il a dit ne s'applique pas a ton cas [:ddr555]

Reply

Marsh Posté le 13-02-2003 à 18:56:06    

chrisbk a écrit :

Bon ! en farfouillant dans du vieux code pas beau a moi j'ai ca:
 

Code :
  1. HBITMAP backBuffer;
  2. HWND mainhWnd;
  3. ...
  4. void createBackBuffer()
  5. {
  6. wdc = GetDC(mainhWnd);
  7.  
  8. RECT rect;
  9. GetClientRect(mainhWnd,&rect); 
  10.    
  11. if (backBuffer)
  12. DeleteObject(backBuffer);
  13. backBuffer = CreateCompatibleBitmap(wdc,rect.right,rect.bottom);
  14. dc =CreateCompatibleDC(wdc);
  15. SelectObject(dc,backBuffer);
  16. }


 
tu barbouilles dans dc, et lors du WM_PAINT, tu fais:
 

Code :
  1. case WM_PAINT:
  2.         PAINTSTRUCT paint;
  3.         BeginPaint(hWnd,&paint);
  4.         RECT paintRect;
  5.         paintRect = paint.rcPaint;
  6.         BitBlt(wdc,
  7.             paintRect.left,
  8.             paintRect.top,
  9.             paintRect.right-paintRect.left,
  10.             paintRect.bottom-paintRect.top,
  11.             dc,
  12.             paintRect.left,
  13.             paintRect.top,SRCCOPY);
  14.         EndPaint(hWnd,&paint);
  15.         break;


 
Avec appel a createBackBuffer a chaque WM_SIZE


 
J'ai essayé ton bout de code mais ça na rien changé.


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 14-02-2003 à 19:07:08    

Precise ton langage, poste un peu de code (creation fenetre, reponse a WM_PAINT notamment).


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 17-02-2003 à 11:45:58    

Bah mon langage est le C et le bout de code est celui de chrisbk ou du lien, tout deux marchent pas. Je dois mal m'y prendre.


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 17-02-2003 à 17:46:02    

Ben il est la le prblm, ces codes (en tous cas celui du lien) fonctionnent tres bien.
Comment as-tu ajouté une video à ta "Form" ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 17-02-2003 à 17:55:09    

Le mieux pour utiliser du "multimedia" dans une fenetre est d utiliser directX SDK...
 
 le double (et meme triple) buffer est deja implementé (primary surface, offscreen surface, flip) dans le cas d application graphique 2D (et meme 3D vu que l objet directdraw n existe plus)
 
L inscrustation de video est mieux géré avec DirectShow
 
 
Perso , je fais mes applications avec, et j ai beaucoup moins de mal a dessiner (et du coup je peux meme rajouter des effets grace a directX)

Reply

Marsh Posté le 17-02-2003 à 17:58:21    

Oui j'y est pensé car je fais un peu de Direct X mais là je veux programmer qu'en Win32 alors il me faut cette solution !!!!!


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 17-02-2003 à 18:03:37    

et la SDL ne te conviendrait pas ? ou allégro ?


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-02-2003 à 18:10:59    

DirectX fait partie de Win32 :)
Mais faut passer au C++.
Comment fais-tu alors pour lire une video ?
Tu veux pas donner de code, n'attend pas de miracles.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 17-02-2003 à 18:27:00    

HelloWorld a écrit :

DirectX fait partie de Win32 :)
Mais faut passer au C++.
Comment fais-tu alors pour lire une video ?
Tu veux pas donner de code, n'attend pas de miracles.


Je te l'es envoyé en PV.


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 18-02-2003 à 00:16:34    

T'utilises donc un dialog.
Je viens de tester, et par défaut, en tous cas sous XP, les dialogue box n'ont pas style CS_HREDRAW | CS_VREDRAW dans leur classe.
Car je te parle de style de classe, ce qui est différent du style utilisé lors de la création (WS_XXX).
Mais comme tu programmes pas en "Raw API" et que tu passes par "BCX", peut etre qu'il magouille un truc.
J'avais farfouillé dans les sources de la VCL une fois, et ils subclassent toutes les classes.
Peut etre qu'ils en font autant pour les dialogues, et qu'ils modifient le style.
Peut etre donc que tu utilises ces 2 styles sans le savoir.
Car j'ai rajouté ces 2 styles, et y'a pas photo, ca clignote dès que je resize.
Créé une dialogue vide, intercepte WM_PAINT, fait un TextOut et test.
Si ca clignote quand tu resize, alors ces styles y sont.
Il suffit alors de les gercler (GetClassLong, enlever les 2 flags, SetClassLong).
Sinon, faut passer par le double buffer.
Mais quand meme, avoir ce comportement là sans ces styles, je vois pas trop ...


Message édité par HelloWorld le 18-02-2003 à 00:19:36

---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 18-02-2003 à 19:13:22    

Oki merci bien HelloWorld, j'aime quand c'est des réponses comme ça, des petites soluces rapides, rien à voir avec tous les codes qui m'ont filé lol, mais bon merci à tous quand même.


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 18-02-2003 à 19:16:46    

Comme je vois que tu es chaud, je me permet de te demander autre chose : http://forum.hardware.fr/forum2.ph [...] subcat=386
 
Merci encore pour tes réponses.


---------------
Mieux vaut partir sur des rires de qualités que sur un silence de quantité.
Reply

Marsh Posté le 18-02-2003 à 23:31:17    

HelloWorld a écrit :

DirectX fait partie de Win32 :)
Mais faut passer au C++.
Comment fais-tu alors pour lire une video ?
Tu veux pas donner de code, n'attend pas de miracles.


 
on peut le programmer en C ... mais effectivement c mieux en C++ :)

Reply

Marsh Posté le 18-02-2003 à 23:34:37    

Nerocro a écrit :

Oki merci bien HelloWorld, j'aime quand c'est des réponses comme ça, des petites soluces rapides, rien à voir avec tous les codes qui m'ont filé lol, mais bon merci à tous quand même.


la prochaine fois, on te filera les opcodes en hexa, ça sera plus rapide


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 19-02-2003 à 02:01:45    

Citation :

on peut le programmer en C ... mais effectivement c mieux en C++ :)


Lorsque je me suis initié à DirectDraw, j'ai passé une après midi entière à chercher d'où venait l'erreur du code d'exemple que j'avais récupéré ...
Quand, finalement, j'ai capté que c'était parce que j'avais appelé mon fichier source main.c au lieu de main.cpp, j'ai :crazy: :cry: :gun: [:louloup2]


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed