Uwielbiam tworzyć "animacje" w języku C++, takie jak symulator MandelBrot Set, Game of Life itp., Ustawiając piksele bezpośrednio na ekranie klatka po klatce. Polecenie SetPixel() sprawia, że jest to niezwykle proste, chociaż niestety jest ono również bardzo powolne. Oto rodzaj konfiguracji używam dla każdej klatki, jeśli chciałem malować cały ekran z zawartością tablicy R:Jak wyświetlać piksele na ekranie bezpośrednio z surowej tablicy wartości RGB szybciej niż SetPixel()?
#include <windows.h>
using namespace std;
int main()
{
int xres = 1366;
int yres = 768;
char *R = new char [xres*yres*3];
/*
R is a char array containing the RGB value of each pixel sequentially
Arithmetic operations done to each element of R here
*/
HWND window; HDC dc; window = GetActiveWindow(); dc = GetDC(window);
for (int j=0 ; j<yres ; j++)
for (int i=0 ; i<xres ; i++)
SetPixel(dc,i,j,RGB(R[j*xres+3*i],R[j*xres+3*i+1],R[j*xres+3*i+2]));
delete [] R;
return 0;
}
Na moim komputerze to trwa prawie 5 sekund, aby wykonać za oczywiste powód, dla którego SetPixel() jest wywoływany ponad milion razy. Najlepszy scenariusz, mógłbym uruchomić to 100 razy szybciej i uzyskać płynną animację 20 klatek na sekundę.
Słyszałem, że konwersja R do pliku bitmapowego w jakiś sposób, a następnie użycie BitBlt do wyświetlania klatki w jednym czystym poleceniu jest drogą do zrobienia, ale nie mam pojęcia, jak to zaimplementować dla mojej konfiguracji i byłbym bardzo wdzięczny jakaś pomoc.
Jeśli jest to istotne, używam systemu Windows 7 i używam Code :: Blocks jako mojego IDE.
Twoje przeczucie jest poprawne: interakcja pomiędzy Windows i ustawianie poszczególnych pikseli jest wąskim gardłem, a preferowanym sposobem jest stworzenie mapy bitowej w pamięci. Nie powinno być trudno znaleźć samouczek. Po jego wdrożeniu możesz być * zaskoczony * wzrostem prędkości. (Inną opcją może być zmiana na SDL, która również może być przyspieszana w ten sam sposób, ale minimalizuje część specyficzną dla systemu Windows.) – usr2564301
Użyj 'CreateDIBitmap()', aby utworzyć mapę bitową z dostarczonych danych pikseli. Powstała bitmapa będzie kompatybilna z oknem HDC, które chcesz narysować, możesz więc użyć 'CreateCompatibleDC()' i 'SelectObject()' aby przygotować bitmapę do rysowania, a następnie 'BitBlt()' aby narysować mapa bitowa w oknie. –
Zobacz także CreateDIBSection –