2013-10-25 4 views
0

Я работаю над доступом к пиксельным цветам игры, с небольшим успехом. Я исследовал и пытался использовать несколько методов, включая BitBlt, библиотеку SharpDX, Desktop Duplication (не мог использовать из-за ограничений Windows 8) и GetPixel() (это сработало, но слишком медленно, чтобы быть полезным).Read DirectX Game Overlay

Ни одна из этих (кроме GetPixel()) не работает из-за Overlay игры (возможно, я просто не обнаружил соответствующую функцию SharpDX/D3D).

Я изучил драйверы зеркал, но я не мог найти достаточную документацию для их использования или знать, будут ли они работать.

Есть ли способ получить доступ к пикселям наложения DirectX?

+0

Оверлей - это особый вид поверхности в DirectX, Microsoft не предоставляет никакого открытого интерфейса для получения данных с поверхности Overlay, нет никакого способа, кроме как подключиться! – zdd

ответ

1

Поскольку игры с прямым x обычно дублируются в два раза, существует вероятность 50% того, что GetPixel или Bitblt будут работать вообще. Если вам действительно нужны пиксели в реальном времени из игры, вы можете подключить их с помощью dll/объединять и подавать пиксели в любое приложение, которое вы хотите с помощью sharedmemory или в какой-то форме межпроцессного общения.

В качестве примечания, так как вы говорите, что GetPixel работает для вас, вы всегда можете попробовать следующее для захвата скриншот указанного окна и сохранение его .. Вам нужно связать с gdi32 и gdiplus

#include <windows.h> 
#include <iostream> 
#include <fstream> 

typedef struct 
{ 
    HBITMAP hBmp; 
    int Width, Height; 
    unsigned int* Pixels; 
    unsigned short BitsPerPixel; 
} BmpData; 

bool ScreenShot(BmpData &Data, HDC DC) 
{ 
    bool Result = false; 
    memset(&Data, 0, sizeof(Data)); 
    HDC hdcMem = CreateCompatibleDC(DC); 
    Data.Width = GetDeviceCaps(DC, HORZRES); 
    Data.Height = GetDeviceCaps(DC, VERTRES); 

    unsigned char* Pixels = NULL; 
    unsigned short BitsPerPixel = 32; 
    BITMAPINFO Info = {{sizeof(BITMAPINFOHEADER), Data.Width, -Data.Height, 1, BitsPerPixel, BI_RGB, 0, 0, 0, 0, 0}}; 

    Data.hBmp = CreateDIBSection(DC, &Info, DIB_RGB_COLORS, reinterpret_cast<void**>(&Pixels), NULL, 0); 
    if(Data.hBmp) 
    { 
     HBITMAP hOld = reinterpret_cast<HBITMAP>(SelectObject(hdcMem, Data.hBmp)); 
     BitBlt(hdcMem, 0, 0, Data.Width, Data.Height, DC, 0, 0, SRCCOPY); 
     SelectObject(hdcMem, hOld); 
     Data.Height *= -1; 
     Data.BitsPerPixel = BitsPerPixel; 
     Data.Pixels = reinterpret_cast<unsigned int*>(Pixels); 
     Result = true; 
    } 

    DeleteDC(hdcMem); 
    return Result; 
} 

/*Portable way to save a bitmap =)*/ 
void SaveBitmap(const char* FilePath, const BmpData &Data) 
{ 
    std::fstream hFile(FilePath, std::ios::out | std::ios::binary); 
    if (!hFile.is_open()) 
    { 
     printf("%s", "Error. Cannot Create Bitmap."); 
     return; 
    } 

    unsigned int Trash = 0; 
    unsigned short Planes = 1; 
    unsigned int biSize = 40; 
    unsigned short Type = 0x4D42; 
    unsigned int compression = 0; 
    unsigned int PixelsOffsetBits = 54; 
    int Width = Data.Width; 
    int Height = -Data.Height; 
    unsigned short BitsPerPixel = Data.BitsPerPixel; 
    unsigned int size = ((Width * BitsPerPixel + 31)/32) * 4 * Height; 
    unsigned int bfSize = 54 + size; 
    Height *= -1; 

    hFile.write(reinterpret_cast<char*>(&Type), sizeof(Type)); 
    hFile.write(reinterpret_cast<char*>(&bfSize), sizeof(bfSize)); 
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(unsigned int)); 
    hFile.write(reinterpret_cast<char*>(&PixelsOffsetBits), sizeof(PixelsOffsetBits)); 
    hFile.write(reinterpret_cast<char*>(&biSize), sizeof(biSize)); 
    hFile.write(reinterpret_cast<char*>(&Width), sizeof(Width)); 
    hFile.write(reinterpret_cast<char*>(&Height), sizeof(Height)); 
    hFile.write(reinterpret_cast<char*>(&Planes), sizeof(Planes)); 
    hFile.write(reinterpret_cast<char*>(&BitsPerPixel), sizeof(BitsPerPixel)); 
    hFile.write(reinterpret_cast<char*>(&compression), sizeof(compression)); 
    hFile.write(reinterpret_cast<char*>(&size), sizeof(size)); 
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(unsigned int)); 
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(unsigned int)); 
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(unsigned int)); 
    hFile.write(reinterpret_cast<char*>(&Trash), sizeof(unsigned int)); 
    hFile.write(reinterpret_cast<char*>(Data.Pixels), size); 
    hFile.close(); 
} 

int main() 
{ 
    HWND MyWindow = nullptr; //Handle to the window that you want to screenshot.. 

    BmpData data; 
    HDC Screen = GetDC(MyWindow); //Get a DC.. 
    ScreenShot(data, Screen); 
    SaveBitmap("C:/Users/Brandon/desktop/Foo.bmp", data); 
    DeleteDC(Screen); 
    DeleteObject(data.hBmp); 
} 
+0

К сожалению, скриншот не работает: /. Он по-прежнему занимает черный скриншот (не захватывая Overlay). Я начну изучать метод dll/detour, спасибо за совет. – asqapro