Directx 9 screen capture c#

Trying to get an image via a hook from DirectX 9. For the hook, I use the EndScene function. Next, using SharpDX, I try to execute something like this code:

var format = Format.A8R8G8B8;

using (var pSurface = Surface.CreateOffscreenPlain(device, width, height,
                            format, Pool.Scratch))
{
   device.GetFrontBufferData(0, pSurface);
   SharpDX.Rectangle rect = new SharpDX.Rectangle(0, 0, width,
                            height);
   SharpDX.DataRectangle lockedRect = pSurface.LockRectangle(rect,
           LockFlags.ReadOnly | LockFlags.NoSystemLock | LockFlags.NoDirtyUpdate);
   ProcessCapture(rect.Width, rect.Height, lockedRect.Pitch, lockedRect.DataPointer, pSurface.Description.Format.ToPixelFormat());
   pSurface.UnlockRectangle();
}

As a result, GetFrontBufferData crashes with an error:

HRESULT: [0x8876086C], Module: [SharpDX.Direct3D9], ApiCode: [D3DERR_INVALIDCALL/InvalidCall], Message: Unknown

Part 2: There is more complex code that works, but there is a problem-the screen screen is sometimes flipped. I don't know how to fix it. not strong in DirectX.

Tell me what I'm doing wrong.

Author: Vladimir Glinskikh, 2016-02-10

1 answers

The solution from part 2 worked. the problem with flipping images was solved by checking the parameters in device.VertexFormat

Code from Part 2

using (Surface renderTarget = device.GetRenderTarget(0))
{
  var width = renderTarget.Description.Width;
  var height = renderTarget.Description.Height;
  var format = renderTarget.Description.Format;

  // If existing _renderTargetCopy, ensure that it is the correct size and format
  if (_renderTargetCopy != null && (_renderTargetCopy.Description.Width != width || _renderTargetCopy.Description.Height != height || _renderTargetCopy.Description.Format != format))
  {
    // Cleanup resources
    Cleanup();
  }

  // Ensure that we have something to put the render target data into
  if (!_resourcesInitialised || _renderTargetCopy == null)
  {
    CreateResources(device, width, height, format);
  }

  // Resize from render target Surface to resolvedSurface (also deals with resolving multi-sampling)
  device.StretchRectangle(renderTarget, _resolvedTarget, TextureFilter.None);
}

// Copy data from resolved target to our render target copy
device.GetRenderTargetData(_resolvedTarget, _renderTargetCopy);

// Lock the render target
SharpDX.Rectangle rect;
SharpDX.DataRectangle lockedRect = LockRenderTarget(_renderTargetCopy, out rect);
_renderTargetCopyLocked = true;

lock (_lockRenderTarget)
{
  ProcessCapture(rect.Width, rect.Height, lockedRect.Pitch, lockedRect.DataPointer, _renderTargetCopy.Description.Format.ToPixelFormat());
}

// If the render target is locked from a previous request unlock it
if (_renderTargetCopyLocked)
{
  // Wait for the the ProcessCapture thread to finish with it
  lock (_lockRenderTarget)
  {
    if (_renderTargetCopyLocked)
    {
      _renderTargetCopy.UnlockRectangle();
      _renderTargetCopyLocked = false;
    }
  }
}
 1
Author: Artyom, 2016-02-18 12:51:15