2016-02-11 10 views
1

Я стараюсь делать DirectX 9 скриншот приложения с использованием функции hook EndScene Это хорошо работает, но иногда я получаю перевернутое изображение. Я не могу понять, что я делаю неправильноC# DirectX - экран захвата иногда переворачивается

Любая другая функция (Present) не используется

Это часть моего кода

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

Некоторые additionl функции:

//-----------------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); 
} 
+0

Обратите внимание, что блокировка 'if (_renderTargetCopyLocked) (...)' не является потокобезопасной. Вы можете использовать только блокировку с двойным проверкой, когда есть только одно возможное изменение состояния - поскольку вы снова и снова включаете '_renderTargetCopyLocked', это небезопасно. – Luaan

+0

Спасибо. Это старая конструкция, когда я использовал 'SharpDX.Direct3D9.Query' – Artyom

ответ

1

Solution : проверьте значения в device.VertexFormat