了解DXGI DirectX 11桌面复制以获取缓冲区或阵列的问题 [英] Problems to understand DXGI DirectX 11 Desktop Duplication to get a Buffer or Array
问题描述
我想了解DXGI桌面复制.我已经读了很多书,这是我从Microsoft网站上的DesktopDuplication示例的一部分复制的代码.我的计划是从DesktopImage获取缓冲区或数组,因为我想为其他程序创建新的Texture.我希望有人可以向我解释我该怎么做.
I want to understand DXGI Desktop Duplication. I have read a lot and this is the code I copied from parts of the DesktopDuplication sample on the Microsoft Website. My plan is to get the Buffer or Array from the DesktopImage because I want to make a new Texture for an other program. I hope somebody can explain me what I can do to get it.
void DesktopDublication::GetFrame(_Out_ FRAME_DATA* Data, _Out_ bool* Timeout)
{
IDXGIResource* DesktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
// Get new frame
HRESULT hr = m_DeskDupl->AcquireNextFrame(500, &FrameInfo, &DesktopResource);
if (hr == DXGI_ERROR_WAIT_TIMEOUT)
{
*Timeout = true;
}
*Timeout = false;
if (FAILED(hr))
{
}
// If still holding old frame, destroy it
if (m_AcquiredDesktopImage)
{
m_AcquiredDesktopImage->Release();
m_AcquiredDesktopImage = nullptr;
}
// QI for IDXGIResource
hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&m_AcquiredDesktopImage));
DesktopResource->Release();
DesktopResource = nullptr;
if (FAILED(hr))
{
}
// Get metadata
if (FrameInfo.TotalMetadataBufferSize)
{
// Old buffer too small
if (FrameInfo.TotalMetadataBufferSize > m_MetaDataSize)
{
if (m_MetaDataBuffer)
{
delete[] m_MetaDataBuffer;
m_MetaDataBuffer = nullptr;
}
m_MetaDataBuffer = new (std::nothrow) BYTE[FrameInfo.TotalMetadataBufferSize];
if (!m_MetaDataBuffer)
{
m_MetaDataSize = 0;
Data->MoveCount = 0;
Data->DirtyCount = 0;
}
m_MetaDataSize = FrameInfo.TotalMetadataBufferSize;
}
UINT BufSize = FrameInfo.TotalMetadataBufferSize;
// Get move rectangles
hr = m_DeskDupl->GetFrameMoveRects(BufSize, reinterpret_cast<DXGI_OUTDUPL_MOVE_RECT*>(m_MetaDataBuffer), &BufSize);
if (FAILED(hr))
{
Data->MoveCount = 0;
Data->DirtyCount = 0;
}
Data->MoveCount = BufSize / sizeof(DXGI_OUTDUPL_MOVE_RECT);
BYTE* DirtyRects = m_MetaDataBuffer + BufSize;
BufSize = FrameInfo.TotalMetadataBufferSize - BufSize;
// Get dirty rectangles
hr = m_DeskDupl->GetFrameDirtyRects(BufSize, reinterpret_cast<RECT*>(DirtyRects), &BufSize);
if (FAILED(hr))
{
Data->MoveCount = 0;
Data->DirtyCount = 0;
}
Data->DirtyCount = BufSize / sizeof(RECT);
Data->MetaData = m_MetaDataBuffer;
}
Data->Frame = m_AcquiredDesktopImage;
Data->FrameInfo = FrameInfo;
}
推荐答案
由于在我的最后一个答案上写错了感觉,所以我决定再创建一个.
Since tacking this onto my last answer didn't feel quite right, I decided to create a second.
如果要将桌面数据读取到文件中,则需要D3D11设备对象,设置了D3D11_USAGE_STAGING
标志的纹理对象以及将桌面纹理的RGBA像素数据转换为任意值的方法你要.基本过程是我原始答案中的简化过程:
If you want to read the desktop data to a file, you need a D3D11 Device object, a texture object with the D3D11_USAGE_STAGING
flag set, and a method of converting the RGBA pixel data of the desktop texture to whatever it is you want. The basic procedure is a simplified version of the one in my original answer:
1).创建一个D3D11设备对象和一个设备上下文.
1). Create a D3D11 Device object and a Device Context.
2).创建具有与桌面纹理相同格式的暂存纹理.
2). Create a Staging Texture with the same format as the Desktop Texture.
3).使用CopyResource
将桌面纹理复制到暂存纹理中.
3). Use CopyResource
to copy the Desktop Texture into your Staging Texture.
4).使用ID3D11DeviceContext::Map()
获取指向暂存纹理中包含的数据的指针.
4). Use ID3D11DeviceContext::Map()
to get a pointer to the data contained in the Staging Texture.
确保您知道Map
的工作方式,并确保可以从单个二进制流中写出图像文件.图像缓冲区中也可能有填充,因此请注意,您可能还需要将其过滤掉.另外,请确保您Unmap
缓冲区而不是调用free
,因为几乎可以肯定的是,给您的缓冲区不属于CRT.
Make sure you know how Map
works and make sure you can write out image files from a single binary stream. There may also be padding in the image buffer, so be aware you may also need to filter that out. Additionally, make sure you Unmap
the buffer instead of calling free
, as the buffer given to you almost certainly does not belong to the CRT.
这篇关于了解DXGI DirectX 11桌面复制以获取缓冲区或阵列的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!