Kopiowanie obrazu metodą BitBlt

0

Próbuję zmienić tak mój program żeby dopasowywał zawartość okna do ekranu użytkownika zanim jednak zamienię BitBlt na StretchBlt wprowadziłem zmiany, które by to umożliwiły. Zamieniłem


case WM_PAINT:
			
			HDC hDC;
			PAINTSTRUCT ps;
			hDC = BeginPaint(hWindow, &ps);
			
			GamePaint(hDC);
				
			EndPaint(hWindow, &ps);
		
		return 0;

na

case WM_PAINT:
		
		{	
			HDC hDC;
			PAINTSTRUCT ps;
			hDC = BeginPaint(hWindow, &ps);
			HDC hDCn = CreateCompatibleDC(hDC);
		
			GamePaint(hDCn);
			
			BitBlt(hDC, 0, 0, 1200, 675, hDCn, 0, 0, SRCCOPY);
			
			DeleteDC(hDCn);
			EndPaint(hWindow, &ps);
		}
		
		return 0;

W efekcie zamiast programu mogę oglądać piękny biały ekran. Ktoś ma pomysł co moŻe nie być ok?

1

Musisz stworzyć bitmapę i przypisać ją do kontekstu hDCn.

0

case WM_PAINT:
			
			{
			HDC hDC;
			PAINTSTRUCT ps;
			hDC = BeginPaint(hWindow, &ps);
			
			HBITMAP nBitmap;
			
			if(fS)
			{
				
				nBitmap = CreateCompatibleBitmap(hDC, m_iWidth, m_iHeight);
				fS=false;
				
			}
	
			HDC hDCn_ = CreateCompatibleDC( hDC );
			SelectObject( hDCn_, nBitmap );
			
			// Rysujemy grę
			GamePaint(hDCn_);
			
			BitBlt( hDC, (tWidth-m_iWidth)/2, (tHeight-m_iHeight)/2, m_iWidth, m_iHeight, hDCn_, 0, 0, SRCCOPY );
			
			DeleteDC(hDCn_);	
			EndPaint(hWindow, &ps);
			}
		
		return 0;

fS jest zmienną globalną równą true
Dodam, że bez linijki fS=false wszystko działa

0
GamePaint(hDC);

Co i w jaki sposób rysuje GamePaint? Może po prostu rysuj wszystko w rozmiarze i rozdzielczości odpowiednich do aktualnego rozmiaru okna, zamiast skalować już po wyrenderowaniu, co raczej będzie słabo wyglądać.

0

Grafika wygląda dobrze, chodzi tylko o redukcję lagów, które się pojawiły po dodaniu tej linijki.

1

Zamiast stworzyć bitmapę w WM_PAINT daj to w WM_SIZING lub WM_SIZE.

fS jest zmienną globalną równą true

Panicz słyszał o zmiennych statycznych? nBitmap jest lokalną zmienną, więc w następnym wywołaniu WM_PAINT stworzonej bitmapy nie będzie (tzn. będzie... zgubiona) ;)

Jeśli chodzi o tworzenie i usuwanie kontekstu, to jakoś tak to powinno wyglądać:

HDC hDCn_ = CreateCompatibleDC( hDC );
HGDIOBJ hBmpOld = SelectObject( hDCn_, nBitmap);
 
/* ... */ 

SelectObject(hDCn_, hBmpOld);
DeleteDC(hDCn_);    
0

Teraz przynajmniej działa, ale program i tak zajmuje 30% CPU. Pozwoliłbym sobie zauważyć, że większość profesjonalnych dużo bardziej skomplikowanych aplikacji ( jak chodźby chrome ) ma dużo bardziej skomplikowaną grafikę i równierz musi korzystać z winapi skoro jest na windowsa zajmuje ułamki procenta CPU. No i czemu mój program w 35 fps-ach dobija do takich wartości skoro piszę go w czystym winapi, które powinno być dużo szybsze niż jakiekolwiek opakowanie na winapi jak openGL.

0
Roman Kwaśniewski napisał(a):

No i czemu mój program w 35 fps-ach dobija do takich wartości skoro piszę go w czystym winapi, które powinno być dużo szybsze niż jakiekolwiek opakowanie na winapi jak openGL.

To że piszesz swój kod proceduralnie (bez wykorzystania obiektowości), wcale nie oznacza, że będzie on super efektywny. Najwyraźniej wąskie gardło jest nie tam, gdzie go oczekujesz.

0

Podejrzewam, że większość tego czasu zabiera GamePaint. BitBlt jest wspierana sprzętowo, wykonuje się bardzo szybko i nie chce mi się wierzyć, żeby przerzucenie zawartości jednej bitmapy do kontekstu okna powodowało duży narzut czasowy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1