質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • C++

    3338questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • DirectX

    67questions

    DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

DirectX11におけるテクスチャーからテクスチャーへのリサイズ描画

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,381
退会済みユーザー

退会済みユーザー

Windows 8で実装されたIDXGIOutputDuplicationを使ってのC++によるデスクトップイメージの取得を試しています。CopySubresourceRegionでID3D11Texture2D形式のデータが取得されるまでは成功したのですが、このデータをIDXGISurface::Mapでピクセルデータを取得してからのリサイズだとCPUの負担になるため、できることならDirectX内で完結させたいと考えています。

現在、テクスチャーからテクスチャーへの縮小コピーすることで解決できないかを検討しています。DirectX9世代の情報だと比較的容易に見つかるのですが、最新バージョンのDirect3Dの情報はそれらに埋もれているようでなかなか検索に当たりません。DirectX11世代におけるテクスチャー間のリサイズコピーの手法、もしくはIDXGIOutputDuplicationで取得したデータのリサイズの方法をご存じでしたらお教えください。

int DeskCapture::UpdateFrame()
{
    HRESULT hr;

    ReleasePixelData();
    RELEASE(deskimage);

    IDXGIResource* res = NULL;
    hr = dupli->AcquireNextFrame(500, &frameinfo, &res);
    if (hr == DXGI_ERROR_WAIT_TIMEOUT) return 1;
    if (FAILED(hr)){
        if (hr == DXGI_ERROR_ACCESS_LOST){
            RELEASE(dupli);
            if(CreateDuplication() >= 0) return 1;
            return -1;
        }else{
            dupli->ReleaseFrame();
            return -2;
        }
    }

    hr = res->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&deskimage);
    RELEASE(res);

    if (FAILED(hr)) return -3;

    frameinfo.AccumulatedFrames;
    if (frameinfo.AccumulatedFrames == 0){
        hr = dupli->ReleaseFrame();
        if (FAILED(hr)) return -4;
    }

    SetPixelData();

    return 0;
}

void DeskCapture::SetPixelData()
{
    if (frameinfo.AccumulatedFrames == 0 || !frameinfo.TotalMetadataBufferSize) return;

    if (frameinfo.TotalMetadataBufferSize > databuflen){
        if (databuf) delete[]databuf;

        databuflen = frameinfo.TotalMetadataBufferSize;
        databuf = new BYTE[databuflen];
    }

    HRESULT hr;
    UINT size = frameinfo.TotalMetadataBufferSize;
    hr = dupli->GetFrameMoveRects(size, (DXGI_OUTDUPL_MOVE_RECT*)databuf, &size);
    if (FAILED(hr)) return;

    BYTE* dirtyrects = databuf + size;
    size = frameinfo.TotalMetadataBufferSize - size;

    hr = dupli->GetFrameDirtyRects(size, (RECT*)dirtyrects, &size);
    if (FAILED(hr)) return;

    D3D11_TEXTURE2D_DESC desc;
    desc.MipLevels = 1;
    desc.ArraySize = 1;
    desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    desc.Usage = D3D11_USAGE_STAGING;
    desc.BindFlags = 0;
    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    desc.MiscFlags = 0;

    D3D11_BOX box;
    box.front = 0;
    box.back = 1;

    DXGI_MAPPED_RECT mrc;

    UINT dirty = size / sizeof(RECT);
    RECT *pr = (RECT*)dirtyrects;
    for (UINT i = 0; i < dirty; i++){
        ID3D11Texture2D *stage;
        desc.Width = (pr->right - pr->left);
        desc.Height = (pr->bottom - pr->top);
        hr = device->CreateTexture2D(&desc, NULL, &stage);
        if (FAILED(hr)) continue;

        IDXGISurface *surf = NULL;
        box.top = pr->top;
        box.left = pr->left;
        box.right = pr->right;
        box.bottom = pr->bottom;
        context->CopySubresourceRegion((ID3D11Resource*)stage, 0, 0, 0, 0, (ID3D11Resource*)deskimage, 0, &box);
        
        hr = stage->QueryInterface(__uuidof(IDXGISurface), (void**)&surf);
        if (SUCCEEDED(hr)){
            hr = surf->Map(&mrc, DXGI_MAP_READ);

            BYTE *p = mrc.pBits;
            BYTE *pp = pixelbuf + ((height - pr->top - 1) * width + pr->left) * 4;
            for (UINT y = 0; y < desc.Height; y++){
                memcpy(pp, p, desc.Width * 4);
                pp -= width * 4;
                p += mrc.Pitch;
            }

            surf->Unmap();
        }

        //ExportBitmap();

        RELEASE(stage);
        RELEASE(surf);

        pr++;
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C++

    3338questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • DirectX

    67questions

    DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。