0

DXGI デスクトップ複製について知りたいです。私は多くのことを読みましたが、これは Microsoft Web サイトの DesktopDuplication サンプルの一部からコピーしたコードです。私の計画は、他のプログラム用に新しいテクスチャを作成したいので、DesktopImage から Buffer または Array を取得することです。誰かがそれを得るために何ができるかを説明してくれることを願っています.

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;
}
4

2 に答える 2

2

私の理解が正しければ、現在のデスクトップ イメージを取得し、それをプライベート テクスチャに複製し、そのプライベート テクスチャをウィンドウにレンダリングする必要があります。DXGI から取得したテクスチャ オブジェクトで何かを行うには D3D が必要になるため、Direct3D 11 を読み、シーンをレンダリングする方法を学習することから始めます。これこれ、およびこれで、D3D11 を開始できます。また、コードをコピーしたサンプルのソースを読むのに時間を費やします。これを行う方法が完全に説明されているからです。そのサンプルの完全なソース コードへのリンクを次に示します

実際にテクスチャ データを取得してレンダリングするには、次の手順を実行する必要があります。

1)。D3D11 デバイス オブジェクトとデバイス コンテキストを作成します。

2)。グラフィックス カード用の Vertex シェーダーと Pixel シェーダーを作成してコンパイルし、アプリケーションにロードします。

3)。入力レイアウト オブジェクトを作成し、デバイスに設定します。

4)。デバイスに必要な Blend、Depth-Stencil、および Rasterizer の状態を初期化します。

5)。Texture オブジェクトと Shader Resource View オブジェクトを作成します。

6)。上記のコードを使用して Desktop Duplication テクスチャを取得します。

7)。CopyResourceデータをテクスチャにコピーするために使用します。

8)。そのテクスチャを画面にレンダリングします。

これにより、デスクトップの 1 つに表示されているすべてのデータがテクスチャにキャプチャされます。デスクトップのダーティ rect に対しては処理を行いません。移動した領域に対する処理は行いません。これは、「デスクトップをキャプチャして別の場所に表示する」コードです。

さらに詳しく知りたい場合は、リンクされたリソースを読み、サンプル コードを調べてください。サンプルは基本的に、求めていることを実行します。

于 2014-12-02T16:11:37.133 に答える