Sign in to follow this  
DanCake

Hooking DirectX and screenshots

Recommended Posts

DanCake    122
I need to hook a DirectX based game and take a screenshot using C# in a similar way to FRAPS. I'm guessing it would look something like this: DirectX game -> C++ based dll -> C# program I have seen ways of hooking DirectX (here and here) although i'm unsure how to capture a screenshot (when requested from the C# app) and get the data back. C++ really isn't my thing so sample code would be appreciated.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by DanCake
I need to hook a DirectX based game and take a screenshot using C# in a similar way to FRAPS.

I'm guessing it would look something like this:
DirectX game -> C++ based dll -> C# program

I have seen ways of hooking DirectX (here and here) although i'm unsure how to capture a screenshot (when requested from the C# app) and get the data back.

C++ really isn't my thing so sample code would be appreciated.
I've used the proxy DLL version quite a few times.
To take a screenshot with that method, you can just call IDirect3DDevice9::GetFrontBufferData after Present(), and then send that data to your C# program through a socket or named pipe or some other method of IPC.

Share this post


Link to post
Share on other sites
DanCake    122
Thanks for that, it was very helpful and i've successfully captured the front buffer to a file and managed to get sockets working in both c++ and c#.

What is the best way to extract the color values from each pixel? The following code works although once it reaches a certain pixel, I get the following:
"Unhandled exception at 0x1004407a (d3d9.dll) in test.exe: 0xC0000005: Access violation reading location 0x00134000."


void myIDirect3DDevice9::CaptureScreenshot(void)
{
LPDIRECT3DSURFACE9 FrontBuff;
D3DSURFACE_DESC SurfaceDesc;
D3DDISPLAYMODE DisplayMode;
D3DLOCKED_RECT Rect;

myIDirect3DDevice9::GetDisplayMode(D3DADAPTER_DEFAULT, &DisplayMode);

m_pIDirect3DDevice9->CreateOffscreenPlainSurface(DisplayMode.Width, DisplayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &FrontBuff, NULL);
m_pIDirect3DDevice9->GetFrontBufferData(D3DADAPTER_DEFAULT, FrontBuff);
//D3DXSaveSurfaceToFile( "c:\\screenshot.jpg", D3DXIFF_JPG, pFrontBuff, NULL, NULL);

FrontBuff->GetDesc(&SurfaceDesc);

FrontBuff->LockRect(&Rect,0,D3DLOCK_READONLY);
DWORD *imageData = (DWORD*)&Rect.pBits;
int r,g,b;

for(int i = 0; i < DisplayMode.Height; i++) {
for(int j = 0; j < DisplayMode.Width; j++) {
D3DXCOLOR PixelColor(imageData[i * Rect.Pitch / 4 + j]); //Causes the access violation

r = PixelColor.r;
g = PixelColor.g;
b = PixelColor.b;

ProcessPixel(r, g, b, i, j);
}
}

pFrontBuff->UnlockRect();
pFrontBuff->Release();


}


Share this post


Link to post
Share on other sites
Evil Steve    2017
DWORD *imageData = (DWORD*)&Rect.pBits;
should be:
DWORD *imageData = (DWORD*)Rect.pBits;

Otherwise you're taking the address of the variable on the stack, instead of copying the pointer.

Share this post


Link to post
Share on other sites
DanCake    122
I've changed that and now i'm getting the following:
"Unhandled exception at 0x100440f7 (d3d9.dll) in test.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd."

Edit: Ignore that, the UnlockRect() and Release() lines are wrong.

Thanks for all the help!

[Edited by - DanCake on January 1, 2009 9:12:45 AM]

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by DanCake
I've changed that and now i'm getting the following:
"Unhandled exception at 0x100440f7 (d3d9.dll) in test.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd."

Edit: Ignore that, the UnlockRect() and Release() lines are wrong.

Thanks for all the help!
Even though you've solved the problem, you must check the return values for all D3D functions that return any pointer or data you rely on. If you don't, you can expect your app to give those lovely "The application has encountered an error and will be closed" messages when run on various other hardware. I can count 3 points in your code that could cause a crash.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this