Bonjour,
je cherche à créer un code d'exemple ultra minimaliste qui expose la technique d'affichage avec double buffer.
Je me limite à l'API de base de <windows.h> (pas de MFC ni autres classes avancées).
Voici le code auquel je suis arrivé (c'est du c++ mais je ne fais rien d'autre que du c) :
L'idéal serait d'avoir un code conditionnel : avec ou sans double buffer.
Dans mon code, j'ai un booléen doublebuffer qui définit cette condition.
J'ai une boucle qui, à chaque tour, affiche des cercles en ligne (juste histoire d'avoir beaucoup d'objets graphiques).
Quand le lance l’exécution sans double buffer, j'ai un effet de clignotement très désagréable.
Mais quand j'active le double buffer, j'ai la même chose !
A croire que je me suis trompé quelque part...
D'ailleurs, je ne comprends pas bien ce que OpenGL vient faire là dedans.
Enfin, en double buffer, il y a 2 dll (opengl32 et glu32) qui sont chargées et déchargées aussitôt à chaque tour...
Extrait de la fenêtre de sortie avec les dll chargées/déchargées à chaque tour.
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
55
56
57
58
59
60
61
62
63 #include <windows.h> #include <crtdbg.h> void main () { const bool doublebuffer = true ; const int size = 300 ; const int r = 30 ; WNDCLASSEX wcx ; memset( &wcx,0,sizeof( wcx )) ; wcx.cbSize = sizeof( wcx ) ; wcx.lpszClassName = "foo" ; wcx.lpfnWndProc = DefWindowProc ; RegisterClassEx( &wcx ) ; HWND hwnd = CreateWindowEx( NULL,"foo",NULL,WS_POPUP,10,10,size,size,NULL,NULL,NULL,NULL ) ; ShowWindow( hwnd,TRUE ) ; HDC dc = GetWindowDC( hwnd ) ; if (doublebuffer) { PIXELFORMATDESCRIPTOR pfd ; memset( &pfd,0,sizeof( PIXELFORMATDESCRIPTOR )) ; pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR ) ; pfd.nVersion = 1 ; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER ; pfd.iPixelType = PFD_TYPE_RGBA ; pfd.cColorBits = 24 ; pfd.cDepthBits = 24 ; int iPixelFormat = ChoosePixelFormat( dc,&pfd ) ; PIXELFORMATDESCRIPTOR bestMatch_pfd ; DescribePixelFormat( dc,iPixelFormat,sizeof( pfd ),&bestMatch_pfd ) ; SetPixelFormat( dc,iPixelFormat,&pfd ) ; } PAINTSTRUCT paint ; for ( int loop = 0 ; loop < 1000 ; loop++ ) { int y = loop%(size-2*r)+r ; BeginPaint( hwnd,&paint ) ; // fonctionne aussi sans ça... Rectangle( dc,0,0,size,size ) ; for ( int x = r ; x < size-r ; x += 2 ) Ellipse( dc,x-r,y-r,x+r,y+r ) ; EndPaint( hwnd,&paint ) ; if (doublebuffer) { _RPT1(0,"------------------- %d\n",loop ) ; SwapBuffers( dc ) ; } else Sleep( 50 ) ; // ~ la même durée que le 'SwapBuffers' (sur mon PC) } DeleteDC( dc ) ; DestroyWindow( hwnd ) ; }
Donc, à vous les experts de la programmation windowsienne, je pose toutes ces questions :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 ------------------- 94 'foo.exe' : Chargé 'C:\Windows\SysWOW64\opengl32.dll', Cannot find or open the PDB file 'foo.exe' : Chargé 'C:\Windows\SysWOW64\glu32.dll', Cannot find or open the PDB file 'foo.exe' : Déchargé 'C:\Windows\SysWOW64\opengl32.dll' 'foo.exe' : Déchargé 'C:\Windows\SysWOW64\glu32.dll' ------------------- 95
- comment faire du double buffer qui me donne une animation fluide ?
- à quoi servent les BeginPaint + EndPaint ? (puisque je n'observe pas de différence en les supprimant)
- comment éviter ce manège de dll ?
- mes pratiques sont-elles bonnes ? (sachant que veux éviter la programmation par événements et les WM_PAINT)
Merci d'avance !
Partager