Ok, zatem zakładam, że zrzucam ekran i następnie będę próbował analizować to, co po zrzuceniu ekranu dostanę. Okazuje się, że ze zrzucaniem ekranu nie ma żadnego problemu. Renderowanie w Fortnite jest tak zrobione, że najprostszy kod używający GDI spokojnie radzi sobie ze zrzucaniem ekranu. Konkretnie:
Kod:
static uchar* getScreenshot(int w, int h, int x1, int y1, int ww, int hh) {
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
if (w!=nScreenWidth || h!=nScreenHeight)
throw err("getScreenshot - Bad screen size ["+AnsiString(nScreenWidth)+","+nScreenHeight+"] vs ["+w+","+h+"]");
HWND hDesktopWnd = GetDesktopWindow();
HDC hDesktopDC = GetDC(hDesktopWnd);
HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDesktopDC, ww, hh);
SelectObject(hCaptureDC,hCaptureBitmap);
BitBlt(hCaptureDC,0,0,ww,hh, hDesktopDC,x1,y1,SRCCOPY|CAPTUREBLT);
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = ww;
bi.biHeight = hh;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ww * 4 * hh;
HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
char *lpbitmap = (char *)GlobalLock(hDIB);
GetDIBits(hDesktopDC, hCaptureBitmap, 0, (UINT)hh, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
uchar* ret = (uchar*) malloc(dwBmpSize);
memcpy(ret, lpbitmap, dwBmpSize);
GlobalUnlock(hDIB);
GlobalFree(hDIB);
ReleaseDC(hDesktopWnd,hDesktopDC);
DeleteDC(hCaptureDC);
DeleteObject(hCaptureBitmap);
return ret;
}
Oczywiście zasadnicza część kodu pochodzi z jakiegoś źródła zewnętrznego (pewnie MSDN). Dodatkowo kod potrafi zrzucać jakiś określony fragment zamiast całego ekranu. Oczywiście wydajność tego jest zależna od wydajności kompa. Nie mniej jednak z moich obserwacji wydajność jest całkowicie ok. Zrzucanie fragmentu ekranu o wielkości 500x500px spokojnie może działać 60fps. Zrzucanie całego ekranu u mnie działa 15-20fps co też nie jest aż taką złą wartością.
Przy okazji warto zwrócić uwagę, że przy wielordzeniowym procesorze zdecydowanie trzeba przetwarzać dane w oddzielnych wątkach. Oczywiście trzeba dodać synchronizację.