Hello, Im having a bit of trouble trying to get a screenshot script to work. I am not a gamedev but i thought this is a kind of game related thing. Maybe someone here can help?
Right now i am taking a hwnd, creating swap chain and device then trying to capture the back buffer to get the pixels. Im using SharpDX. Alot of this code is stuff i have found online and tweaked. I think it works right now ( im not getting any invalid arg errors ), but all the output is black.
heres the code, I dont use c# much so idk how clean it will be 😬
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using Device = SharpDX.Direct3D11.Device;
internal class DXCaptureScreenCap
{
private Device device;
private SwapChain swapChain;
public void InitializeDeviceAndSwapChain(IntPtr windowHandle)
{
SwapChainDescription swapChainDescription = new SwapChainDescription()
{
BufferCount = 2,
ModeDescription = new ModeDescription(500, 500, new Rational(60, 1), Format.B8G8R8A8_UNorm),
IsWindowed = true,
OutputHandle = windowHandle,
SampleDescription = new SampleDescription(1, 0),
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput
};
Device.CreateWithSwapChain(
SharpDX.Direct3D.DriverType.Hardware,
DeviceCreationFlags.BgraSupport,
swapChainDescription,
out device,
out swapChain
);
}
public void CaptureBackBuffer()
{
if (swapChain == null || device == null)
{
throw new Exception("Swapchain or device is null");
}
// Obtain the back buffer texture from the swap chain
using (var texture = Texture2D.FromSwapChain<Texture2D>(swapChain, 0))
{
Console.WriteLine(texture);
Texture2DDescription description = texture.Description;
Texture2DDescription texture2DDesc = new Texture2DDescription
{
Width = description.Width,
Height = description.Height,
MipLevels = 1,
ArraySize = 1,
Format = description.Format,
Usage = ResourceUsage.Staging,
BindFlags = BindFlags.None,
CpuAccessFlags = CpuAccessFlags.Read,
OptionFlags = ResourceOptionFlags.None,
SampleDescription = new SampleDescription(1, 0) // Needs to be 1,0 or we will get a invalid arg error.
};
using (var stagingTexture = new Texture2D(device, texture2DDesc))
{
var stagingDescription = stagingTexture.Description;
Console.WriteLine($"Staging: Width={stagingDescription.Width}, Height={stagingDescription.Height}, Format={stagingDescription.Format}");
device.ImmediateContext.CopyResource(texture, stagingTexture);
var dataBox = device.ImmediateContext.MapSubresource(stagingTexture, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None);
byte[] pixelData = new byte[stagingDescription.Width * stagingDescription.Height * 4];
for (int y = 0; y < stagingDescription.Height; y++)
{
IntPtr srcPtr = dataBox.DataPointer + (y * dataBox.RowPitch);
Marshal.Copy(srcPtr, pixelData, y * stagingDescription.Width * 4, stagingDescription.Width * 4);
}
device.ImmediateContext.UnmapSubresource(stagingTexture, 0);
// Check for non black pixels
bool hasColorData = false;
for (int i = 0; i < pixelData.Length; i += 4)
{
byte blue = pixelData[i];
byte green = pixelData[i + 1];
byte red = pixelData[i + 2];
if (red != 0 || green != 0 || blue != 0)
{
hasColorData = true;
break; // Exit after finding non black pixel
}
}
if(!hasColorData)
{
Console.WriteLine("The data is all black");
}
}
}
}
}
I am currently calling it from main like :
DXCaptureScreenCap screenCap = new DXCaptureScreenCap();
screenCap.InitializeDeviceAndSwapChain(memman.ProcessWindowHandle);
Console.WriteLine("Press Enter to capture the back buffer...");
Console.ReadLine(); // Wait for user input
try
{
screenCap.CaptureBackBuffer();
}
catch (Exception ex)
{
Console.WriteLine($"Error capturing back buffer: {ex.Message}");
}
Console.WriteLine("Screenshot captured and resources cleaned up.");
im currently getting this output:
window handle : 1443286
Press Enter to capture the back buffer...
SharpDX.Direct3D11.Texture2D
Staging: Width=500, Height=500, Format=B8G8R8A8_UNorm
The data is all black
Screenshot captured and resources cleaned up.
and ofc a completely black image. :(
Any help is appreciated.