Я использовал Directx11 в С#, чтобы сделать снимок экрана, но в итоге я получил только 0 в диапазоне, не знаю почему, в середине нет ошибки, и выполнение возвращает 0, код использует Silk.net.direct3d11 библиотека
Я также попробовал это, создав промежуточную текстуру Text2D, затем скопировав мою DesktopTexture в эту промежуточную текстуру Text2D, а затем скопировав из промежуточной текстуры Text2D в stagingResource.
//....
ID3D11Device* device=null;
ID3D11DeviceContext* context=null;
D3DFeatureLevel featureLevel=D3DFeatureLevel.Level101;
D3DFeatureLevel[] featureLevels =
[
D3DFeatureLevel.Level111, D3DFeatureLevel.Level110, D3DFeatureLevel.Level101,D3DFeatureLevel.Level100
];
fixed (D3DFeatureLevel* pFeatureLevels = &featureLevels[0])
{
D3D11 d3D11 = new D3D11(new DefaultNativeContext("d3d11"));
if (d3D11.CreateDevice((IDXGIAdapter*)adapter1, D3DDriverType.Unknown, IntPtr.Zero,
(uint)CreateDeviceFlag.None,pFeatureLevels,(uint)featureLevels.Length, D3D11.SdkVersion, ref device,
&featureLevel, ref context)!=0){/*..*/}
}
ID3D11DeviceContext* immediateContext = null;
device->GetImmediateContext(ref immediateContext);
IDXGIOutputDuplication *outputDuplication = null;
if (output5.DuplicateOutput((IUnknown*)device, ref outputDuplication)!=0){/*..*/}
OutduplFrameInfo outduplFrameInfo = new OutduplFrameInfo();
IDXGIResource* desktopResource = null;
if (outputDuplication->AcquireNextFrame(1000, &outduplFrameInfo, &desktopResource)!=0{/*..*/}
if (desktopResource->QueryInterface<ID3D11Resource>(out var desktopTexture)!=0){/*..*/}
Texture2DDesc stagingTextureDesc = new()
{
CPUAccessFlags = (uint)CpuAccessFlag.Read,
BindFlags = (uint)(BindFlag.None),
Format = Format.FormatB8G8R8A8Unorm,
Width = (uint)desc.DesktopCoordinates.Size.X,
Height = (uint)desc.DesktopCoordinates.Size.Y,
MiscFlags = (uint)ResourceMiscFlag.None,
MipLevels = 1,
ArraySize = 1,
SampleDesc = { Count = 1, Quality = 0 },
Usage = Usage.Staging
};
ID3D11Texture2D* stagingTexture = null;
if (device->CreateTexture2D(&stagingTextureDesc,null,ref stagingTexture )!=0){/*..*/}
stagingTexture->QueryInterface<ID3D11Resource>(out var stagingResource);
immediateContext->CopyResource(stagingResource, desktopTexture);
MappedSubresource mappedSubresource=new MappedSubresource();
if (immediateContext->Map(stagingResource, 0, Map.Read, 0, &mappedSubresource)!=0){/*..*/}
var span = new ReadOnlySpan<byte>(mappedSubresource.PData,
(int)mappedSubresource.DepthPitch);
Что я делаю не так?
@SimonMourier gist.github.com/MakesYT/6de981d0432a1ab9ded9eae64989f969
Это не воспроизводящий код, а просто фрагменты некомпилируемого кода.





AcquireNextFrame не обещает сразу предоставить вам скриншот. Возможно, вам придется вызвать его несколько раз, прежде чем текстура будет готова.
Подробнее см. в этом ответе: AcquireNextFrame не работает (API дублирования рабочего стола и D3D11).
Странное явление заключается в том, что если я поставлю точку останова в AcquireNextFrame, а затем вручную возобновлю выполнение, все будет работать нормально, но если точки останова нет, попытки будут выполняться бесконечно. cs while (true) { OutduplFrameInfo outduplFrameInfo = new OutduplFrameInfo(); desktopResource = null; if (outputDuplication->AcquireNextFrame(5000, &outduplFrameInfo, &desktopResource)==0&&outduplFrameInfo.LastPresentTime!=0) { break; } Console.WriteLine("recall"); }
Или Thread.Sleep(2); Тоже подойдет
Итак, вы нашли ответ, на который я дал ссылку, а также комментарий там, не так ли?
Да, но есть еще некоторые проблемы
У вас есть полный код воспроизведения? Мы не можем использовать ту часть, которую ты засунул.