mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-25 10:05:49 +08:00
dwm加锁并返回mat
This commit is contained in:
@@ -13,6 +13,7 @@ namespace Fischless.GameCapture.DwmSharedSurface
|
||||
public class SharedSurfaceCapture : IGameCapture
|
||||
{
|
||||
private nint _hWnd;
|
||||
private static readonly object LockObject = new object();
|
||||
private Device? _d3dDevice;
|
||||
|
||||
public void Dispose() => Stop();
|
||||
@@ -73,27 +74,38 @@ namespace Fischless.GameCapture.DwmSharedSurface
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
NativeMethods.DwmGetDxSharedSurface(_hWnd, out var phSurface, out _, out _, out _, out _);
|
||||
if (phSurface == nint.Zero)
|
||||
lock (LockObject)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
NativeMethods.DwmGetDxSharedSurface(_hWnd, out var phSurface, out _, out _, out _, out _);
|
||||
if (phSurface == nint.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ToBitmap(phSurface)?.ToMat();
|
||||
|
||||
if (_d3dDevice == null)
|
||||
{
|
||||
Debug.WriteLine("D3Device is null.");
|
||||
return null;
|
||||
}
|
||||
|
||||
using var surfaceTexture = _d3dDevice.OpenSharedResource<Texture2D>(phSurface);
|
||||
using var stagingTexture = CreateStagingTexture(surfaceTexture, _d3dDevice);
|
||||
var mat = stagingTexture.CreateMat(_d3dDevice, surfaceTexture, _region);
|
||||
if (mat == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var bgrMat = new Mat();
|
||||
Cv2.CvtColor(mat, bgrMat, ColorConversionCodes.BGRA2BGR);
|
||||
return bgrMat;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Bitmap? ToBitmap(nint phSurface)
|
||||
private Texture2D CreateStagingTexture(Texture2D surfaceTexture, Device device)
|
||||
{
|
||||
if (_d3dDevice == null)
|
||||
{
|
||||
Debug.WriteLine("D3Device is null.");
|
||||
return null;
|
||||
}
|
||||
|
||||
using var surfaceTexture = _d3dDevice.OpenSharedResource<Texture2D>(phSurface);
|
||||
|
||||
var staging = new Texture2D(_d3dDevice, new Texture2DDescription
|
||||
return new Texture2D(device, new Texture2DDescription
|
||||
{
|
||||
Width = _region == null ? surfaceTexture.Description.Width : _region.Value.Right - _region.Value.Left,
|
||||
Height = _region == null ? surfaceTexture.Description.Height : _region.Value.Bottom - _region.Value.Top,
|
||||
@@ -106,9 +118,6 @@ namespace Fischless.GameCapture.DwmSharedSurface
|
||||
CpuAccessFlags = CpuAccessFlags.Read,
|
||||
OptionFlags = ResourceOptionFlags.None
|
||||
});
|
||||
|
||||
|
||||
return staging.CreateBitmap(_d3dDevice, surfaceTexture, _region);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
|
||||
@@ -238,6 +238,7 @@ public class GraphicsCapture : IGameCapture
|
||||
_captureSession = null!;
|
||||
_captureFramePool = null!;
|
||||
_captureItem = null!;
|
||||
_stagingTexture?.Dispose();
|
||||
_d3dDevice?.Dispose();
|
||||
|
||||
_hWnd = IntPtr.Zero;
|
||||
|
||||
@@ -4,6 +4,7 @@ using SharpDX.DXGI;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.Imaging;
|
||||
using Windows.Graphics.Capture;
|
||||
using OpenCvSharp;
|
||||
|
||||
namespace Fischless.GameCapture.Graphics.Helpers;
|
||||
|
||||
@@ -67,4 +68,40 @@ public static class Texture2DExtensions
|
||||
staging.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static Mat? CreateMat(this Texture2D staging, SharpDX.Direct3D11.Device d3dDevice, Texture2D surfaceTexture, ResourceRegion? region = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Copy data
|
||||
if (region != null)
|
||||
{
|
||||
d3dDevice.ImmediateContext.CopySubresourceRegion(surfaceTexture, 0, region, staging, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
d3dDevice.ImmediateContext.CopyResource(surfaceTexture, staging);
|
||||
}
|
||||
|
||||
// 映射纹理以便CPU读取
|
||||
var dataBox = d3dDevice.ImmediateContext.MapSubresource(
|
||||
staging,
|
||||
0,
|
||||
MapMode.Read,
|
||||
SharpDX.Direct3D11.MapFlags.None);
|
||||
|
||||
var mat = new Mat(staging.Description.Height, staging.Description.Width, MatType.CV_8UC4, dataBox.DataPointer);
|
||||
return mat;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine("Failed to copy texture to mat.");
|
||||
Debug.WriteLine(e.StackTrace);
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
staging.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user