Для собственного удовольствия я создаю программу трехмерной графики на C ++ с Win32, которая не использует чисел с плавающей запятой. По какой-то причине окно иногда мерцает при обновлении окна. Я полагаю, что это вызвано обновлением окна после того, как было удалено то, что было ранее показано в окне, и до того, как будет нарисовано следующее. Я нашел несколько веб-страниц и вопросов с ответами о том, что кажется той же самой проблемой, за исключением того, что решения не работают.
Некоторые примеры {
Не используйте CS_HREDRAW | CS_VREDRAW. (Нет заметного эффекта)
Возврат 1 для сообщения окна 'WM_ERASEBKGND'. (Мне нужно стереть то, что было нарисовано ранее. Это останавливает мерцание, предотвращая его стирание.)
Вместо стирания нарисуйте прямоугольник в случае WM_PAINT. (Это еще хуже)
}
Как на самом деле предотвратить мерцание окна?
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c
#include <windows.h>
#include <windowsx.h>
#include <tchar.h>
boolean Draw;
//Trigonometry tables in increments of 1/256 of a rotation and multiplied by 65536
const int Total=3,Sine[256]={0,1608,3216,4821,6424,8022,9616,11204,12785,14359,15924,17479,19024,20557,22078,23586,25080,26558,28020,29466,30893,32303,33692,35062,36410,37736,39040,40320,41576,42806,44011,45190,46341,47464,48559,49624,50660,51665,52639,53581,54491,55368,56212,57022,57798,58538,59244,59914,60547,61145,61705,62228,62714,63162,63572,63944,64277,64571,64827,65043,65220,65358,65457,65516,65536,65516,65457,65358,65220,65043,64827,64571,64277,63944,63572,63132,62714,62228,61705,61145,60547,59914,59244,58538,57798,57022,56212,55368,54491,53581,52639,51665,50660,49624,48559,47464,46341,45190,44011,42806,41576,40320,39040,37736,36410,35062,33692,32303,30893,29466,28020,26558,25080,23586,22078,20557,19024,17479,15924,14359,12785,11204,9616,8022,6424,4821,3216,1608,0,-1608,-3216,-4821,-6424,-8022,-9616,-11204,-12785,-14359,-15924,-17479,-19024,-20557,-22078,-23586,-25080,-26558,-28020,-29466,-30893,-32303,-33692,-35062,-36410,-37736,-39040,-40320,-41576,-42806,-44011,-45190,-46341,-47464,-48559,-49624,-50660,-51665,-52639,-53581,-54491,-55368,-56212,-57022,-57798,-58538,-59244,-59914,-60547,-61145,-61705,-62228,-62714,-63162,-63572,-63944,-64277,-64571,-64827,-65043,-65220,-65358,-65457,-65516,-65536,-65516,-65457,-65358,-65220,-65043,-64827,-64571,-64277,-63944,-63572,-63162,-62714,-62228,-61705,-61145,-60547,-59914,-59244,-58538,-57798,-57022,-56212,-55368,-54491,-53581,-52639,-51665,-50660,-49624,-48559,-47464,-46341,-45190,-44011,-42806,-41576,-40320,-39040,-37736,-36410,-35062,-33692,-32303,-30893,-29466,-28020,-26558,-25080,-23586,-22078,-20557,-19024,-17479,-15924,-14359,-12785,-11204,-9616,-8022,-6424,-4821,-3216,-1608},Cosine[256]={65536,65516,65457,65358,65220,65043,64827,64571,64277,63944,63572,63132,62714,62228,61705,61145,60547,59914,59244,58538,57798,57022,56212,55368,54491,53581,52639,51665,50660,49624,48559,47464,46341,45190,44011,42806,41576,40320,39040,37736,36410,35062,33692,32303,30893,29466,28020,26558,25080,23586,22078,20557,19024,17479,15924,14359,12785,11204,9616,8022,6424,4821,3216,1608,0,-1608,-3216,-4821,-6424,-8022,-9616,-11204,-12785,-14359,-15924,-17479,-19024,-20557,-22078,-23586,-25080,-26558,-28020,-29466,-30893,-32303,-33692,-35062,-36410,-37736,-39040,-40320,-41576,-42806,-44011,-45190,-46341,-47464,-48559,-49624,-50660,-51665,-52639,-53581,-54491,-55368,-56212,-57022,-57798,-58538,-59244,-59914,-60547,-61145,-61705,-62228,-62714,-63162,-63572,-63944,-64277,-64571,-64827,-65043,-65220,-65358,-65457,-65516,-65536,-65516,-65457,-65358,-65220,-65043,-64827,-64571,-64277,-63944,-63572,-63162,-62714,-62228,-61705,-61145,-60547,-59914,-59244,-58538,-57798,-57022,-56212,-55368,-54491,-53581,-52639,-51665,-50660,-49624,-48559,-47464,-46341,-45190,-44011,-42806,-41576,-40320,-39040,-37736,-36410,-35062,-33692,-32303,-30893,-29466,-28020,-26558,-25080,-23586,-22078,-20557,-19024,-17479,-15924,-14359,-12785,-11204,-9616,-8022,-6424,-4821,-3216,-1608,0,1608,3216,4821,6424,8022,9616,11204,12785,14359,15924,17479,19024,20557,22078,23586,25080,26558,28020,29466,30893,32303,33692,35062,36410,37736,39040,40320,41576,42806,44011,45190,46341,47464,48559,49624,50660,51665,52639,53581,54491,55368,56212,57022,57798,58538,59244,59914,60547,61145,61705,62228,62714,63162,63572,63944,64277,64571,64827,65043,65220,65358,65457,65516};
int HorizontalAxis,VerticalAxis,SemiHorizontalAxis,SemiVerticalAxis,Speed=1,Phi=64,Theta,VelX,VelY,VelZ,SinTheta,CosTheta=65536,SinPhi,CosPhi=-65536,RegX,RegY,RegZ,Quadrilaterals[3][6]={{0,1,2,3,1,0},{0,3,4,5,0,1},{6,7,8,9,1,2}};
LONG64 AxAv,X,Y,Z,XCoordinates[10]={-5,-5,5,5,5,-5,60,60,120,120},YCoordinates[10]={-5,5,5,-5,-5,-5,80,140,140,80},ZCoordinates[10]={10,10,10,10,30,30,100,100,200,200},q$,w$,e$,r$,t$,y$,u$,i$;
POINT Points[3][4]={{{0,0},{0,0},{0,0},{0,0}}};
RECT WindowRect;
const HPEN Pens[2]={CreatePen(PS_NULL,0,0),CreatePen(PS_SOLID,1,RGB(0,0,0))};
const HBRUSH Brushes[3]={CreateSolidBrush(RGB(0,0,0)),CreateSolidBrush(RGB(128,128,128)),CreateSolidBrush(RGB(255,255,255))};
HINSTANCE hInst;
HWND hWnd;
PAINTSTRUCT ps;
HDC hdc;
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam){
switch(message){
case WM_KEYDOWN:
if(GetAsyncKeyState(16)){Speed=1+3*Speed/2;}
if(GetAsyncKeyState(17)){
Speed=2*Speed/3-1;
if(Speed<1){Speed=1;}
}if(GetAsyncKeyState(82)){
X=0;Y=0;Z=0;Theta=0;Phi=0;RegX=0;RegY=0;RegZ=0;
SinTheta=0;CosTheta=65536;SinPhi=0;CosPhi=65536;
}return 0;
case WM_SIZE:
GetWindowRect(hWnd,&WindowRect);
HorizontalAxis=WindowRect.right-WindowRect.left;
SemiHorizontalAxis=HorizontalAxis/2;
VerticalAxis=WindowRect.bottom-WindowRect.top-100;
SemiVerticalAxis=VerticalAxis/2;
AxAv=(HorizontalAxis+VerticalAxis)/2;
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
if(GetAsyncKeyState(83)){
if(Phi>0){
Phi--;
SinPhi=Cosine[Phi];CosPhi=-Sine[Phi];
}
}if(GetAsyncKeyState(87)){
if(Phi<128){
Phi++;
SinPhi=Cosine[Phi];CosPhi=-Sine[Phi];
}
}if(GetAsyncKeyState(65)){
Theta--;
if(Theta<0){Theta=255;}
SinTheta=Sine[Theta];CosTheta=Cosine[Theta];
}if(GetAsyncKeyState(68)){
Theta++;
if(Theta>255){Theta=0;}
SinTheta=Sine[Theta];CosTheta=Cosine[Theta];
}if(GetAsyncKeyState(39)){VelZ=-SinTheta*Speed;VelX=-CosTheta*Speed;}
if(GetAsyncKeyState(38)){VelZ+=CosTheta*Speed;VelX-=SinTheta*Speed;}
if(GetAsyncKeyState(37)){VelZ+=SinTheta*Speed;VelX+=CosTheta*Speed;}
if(GetAsyncKeyState(40)){VelZ-=CosTheta*Speed;VelX+=SinTheta*Speed;}
if(GetAsyncKeyState(81)){VelY=65536*Speed;}
if(GetAsyncKeyState(69)){VelY=-65536*Speed;}
RegX+=VelX;RegY+=VelY;RegZ+=VelZ;
X+=RegX/65536;Y+=RegY/65536;Z+=RegZ/65536;
RegX%=65536;RegY%=65536;RegZ%=65536;
VelX=0;VelY=0;VelZ=0;
q$=0;
while(q$<Total){
Draw=false;
w$=Quadrilaterals[q$][0];
e$=65536*(XCoordinates[w$]-X);
r$=65536*(YCoordinates[w$]-Y);
t$=65536*(ZCoordinates[w$]-Z);
y$=(CosTheta*e$+SinTheta*t$)/65536;
e$=(CosTheta*t$-SinTheta*e$)/65536;
u$=(CosPhi*r$+SinPhi*e$)/65536;
i$=(CosPhi*e$-SinPhi*r$)/65536;
if(i$<0){
Draw=true;
Points[q$][0].x=SemiHorizontalAxis+AxAv*y$/i$;
Points[q$][0].y=SemiVerticalAxis+AxAv*u$/i$;
}w$=Quadrilaterals[q$][1];
e$=65536*(XCoordinates[w$]-X);
r$=65536*(YCoordinates[w$]-Y);
t$=65536*(ZCoordinates[w$]-Z);
y$=(CosTheta*e$+SinTheta*t$)/65536;
e$=(CosTheta*t$-SinTheta*e$)/65536;
u$=(CosPhi*r$+SinPhi*e$)/65536;
i$=(CosPhi*e$-SinPhi*r$)/65536;
if(i$<0){
Draw=true;
Points[q$][1].x=SemiHorizontalAxis+AxAv*y$/i$;
Points[q$][1].y=SemiVerticalAxis+AxAv*u$/i$;
}w$=Quadrilaterals[q$][2];
e$=65536*(XCoordinates[w$]-X);
r$=65536*(YCoordinates[w$]-Y);
t$=65536*(ZCoordinates[w$]-Z);
y$=(CosTheta*e$+SinTheta*t$)/65536;
e$=(CosTheta*t$-SinTheta*e$)/65536;
u$=(CosPhi*r$+SinPhi*e$)/65536;
i$=(CosPhi*e$-SinPhi*r$)/65536;
if(i$<0){
Draw=true;
Points[q$][2].x=SemiHorizontalAxis+AxAv*y$/i$;
Points[q$][2].y=SemiVerticalAxis+AxAv*u$/i$;
}w$=Quadrilaterals[q$][3];
e$=65536*(XCoordinates[w$]-X);
r$=65536*(YCoordinates[w$]-Y);
t$=65536*(ZCoordinates[w$]-Z);
y$=(CosTheta*e$+SinTheta*t$)/65536;
e$=(CosTheta*t$-SinTheta*e$)/65536;
u$=(CosPhi*r$+SinPhi*e$)/65536;
i$=(CosPhi*e$-SinPhi*r$)/65536;
if(i$<0){
Draw=true;
Points[q$][3].x=SemiHorizontalAxis+AxAv*y$/i$;
Points[q$][3].y=SemiVerticalAxis+AxAv*u$/i$;
}if(Draw){
SelectPen(hdc,Pens[Quadrilaterals[q$][4]]);
SelectBrush(hdc,Brushes[Quadrilaterals[q$][5]]);
Polygon(hdc,Points[q$],4);
}q$++;
}EndPaint(hWnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:return DefWindowProc(hWnd,message,wParam,lParam);
}
}
int CALLBACK WinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPSTR lpCmdLine,_In_ int nCmdShow){
GetWindowRect(GetDesktopWindow(),&WindowRect);
HorizontalAxis=WindowRect.right;
SemiHorizontalAxis=HorizontalAxis/2;
VerticalAxis=WindowRect.bottom-100;
SemiVerticalAxis=VerticalAxis/2;
AxAv=(HorizontalAxis+VerticalAxis)/2;
WNDCLASSEX wcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW|CS_VREDRAW;
wcex.lpfnWndProc=WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(hInstance,IDI_APPLICATION);
wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName=NULL;
wcex.lpszClassName=_T("DesktopApp");
wcex.hIconSm=LoadIcon(wcex.hInstance,IDI_APPLICATION);
if(!RegisterClassEx(&wcex)){
MessageBox(NULL,_T("RegisterClassEx failed!"),_T("Something"),NULL);
return 1;
}hInst=hInstance;
hWnd=CreateWindow(_T("DesktopApp"),_T("Something Application"),WS_OVERLAPPEDWINDOW,0,0,HorizontalAxis,VerticalAxis,NULL,NULL,hInstance,NULL);
if(!hWnd){
MessageBox(NULL,_T("CreateWindow failed!"),_T("Something"),NULL);
return 1;
}ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
Sleep(10);
InvalidateRect(hWnd,NULL,true);
}return(int)msg.wParam;
}