了解DXGI DirectX 11桌面复制以获取缓冲区或阵列的问题 [英] Problems to understand DXGI DirectX 11 Desktop Duplication to get a Buffer or Array

查看:1046
本文介绍了了解DXGI DirectX 11桌面复制以获取缓冲区或阵列的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆