Search code examples
c#screenshotdirectx-9sharpdx

C# DirectX - capture screen sometimes flipped


I try to do DirectX 9 app screenshot using the hook function EndScene This works well, but sometimes I get an inverted image. I can not understand what I doing wrong

Any other function (Present) not using

This is part of my code

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;
    }
  }
}

Some additionl function:

//-----------------Function----------------
private SharpDX.DataRectangle LockRenderTarget(Surface renderTargetCopy, out SharpDX.Rectangle rect)
{
   rect = new SharpDX.Rectangle(0, 0, renderTargetCopy.Description.Width, renderTargetCopy.Description.Height);
   return renderTargetCopy.LockRectangle(rect, LockFlags.ReadOnly);
}


protected void ProcessCapture(int width, int height, int pitch, IntPtr pBits, PixelFormat format)
{
  // Copy the image data from the buffer
  int size = height * pitch;
  var data = new byte[size];
  Marshal.Copy(pBits, data, 0, size);
  Frames.Enqueue(data);
}

Solution

  • Solution: check the values in device.VertexFormat