質問編集履歴

1 リサイズの名目を追加。

退会済みユーザー

退会済みユーザー

2015/03/09 20:19  投稿

DirectX11におけるテクスチャーからテクスチャーへの描画
DirectX11におけるテクスチャーからテクスチャーへのリサイズ描画
Windows 8で実装されたIDXGIOutputDuplicationを使ってのC++によるデスクトップイメージの取得を試しています。CopySubresourceRegionでID3D11Texture2D形式のデータが取得されるまでは成功したのですが、このデータをIDXGISurface::Mapでピクセルデータを取得してからのリサイズだとCPUの負担になるため、できることならDirectX内で完結させたいと考えています。
現在、テクスチャーからテクスチャーへの縮小コピーすることで解決できないかを検討しています。DirectX9世代の情報だと比較的容易に見つかるのですが、最新バージョンのDirect3Dの情報はそれらに埋もれているようでなかなか検索に当たりません。DirectX11世代におけるテクスチャー間のリサイズコピーの手法、もしくはIDXGIOutputDuplicationで取得したデータのリサイズの方法をご存じでしたらお教えください。
```lang-c++
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++;
}
}
```
  • C++

    4883 questions

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

  • DirectX

    82 questions

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

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る