C# DirectX - 捕获屏幕有时会翻转
C# DirectX - capture screen sometimes flipped
我尝试使用钩子函数做 DirectX 9 应用截图 EndScene
这很好用,但有时我会得到倒置的图像。
我不明白我做错了什么
任何其他函数(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;
}
}
}
一些附加功能:
//-----------------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);
}
解决方法:检查device.VertexFormat
中的值
我尝试使用钩子函数做 DirectX 9 应用截图 EndScene
这很好用,但有时我会得到倒置的图像。
我不明白我做错了什么
任何其他函数(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;
}
}
}
一些附加功能:
//-----------------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);
}
解决方法:检查device.VertexFormat