2017-10-19 105 views
0

我執行Direct3D後臺緩衝區的捕獲。當我下載像素時,圖像幀沿着其垂直軸翻轉。當複製資源時,或者在創建目標時,可以「告訴」D3D翻轉該幀。Direct3D11:翻轉ID3D11Texture2D

這是我如何做到這一點:

到我複製幀緩存紋理創建這樣的:

D3D11_TEXTURE2D_DESC description = 
    { 
     desc.BufferDesc.Width, desc.BufferDesc.Height, 1, 1, 
     DXGI_FORMAT_R8G8B8A8_UNORM, 
     { 1, 0 }, // DXGI_SAMPLE_DESC 
     D3D11_USAGE_STAGING,//transder from GPU to CPU 
     0, D3D11_CPU_ACCESS_READ, 0 
    }; 
    D3D11_SUBRESOURCE_DATA data = { buffer, desc.BufferDesc.Width * PIXEL_SIZE, 0 }; 
    device->CreateTexture2D(&description, &data, &pNewTexture); 

然後每幀我做的:

 pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast< void** >(&pSurface)); 
    pContext->CopyResource(pNewTexture, pSurface); 
    D3D11_MAPPED_SUBRESOURCE resource; 
    pContext->Map(pNewTexture, 0, D3D11_MAP_READ , 0, &resource); 
    //reading from resource.pData 
    //... 

PS:我沒有渲染管道的控制權。我用這段代碼掛鉤了一個外部應用程序。 此外,我不想弄亂CPU上的像素緩衝區,就像循環中的反向複製等。副本的低延遲是高優先級。

UPDATE:

我也試過這樣:

D3D11_BOX box; 
    box.left = 0; 
    box.right = desc.BufferDesc.Width; 
    box.top = desc.BufferDesc.Height; 
    box.bottom = 0; 
    box.front = 0; 
    box.back = 1; 
    pContext->CopySubresourceRegion(pNewTexture, 0, 0, 0, 0, pSurface, 0, &box); 

這將導致框架是從它的內容爲空。

+0

不要忘記檢查那些返回非''void''的函數的''HRESULT''值。您目前假設它始終有效。使用''SUCCEEDED'',''FAILED''或類似[ThrowIfFiled](https://github.com/Microsoft/DirectXTK/wiki/ThrowIfFailed)。 –

+0

@ChuckWalbourn實際上一直這樣做..爲簡單起見,在這裏刪除。 –

+0

基於多鉤子一箇舊項目的例子:https://github.com/headmax/Cplus/blob/master/Projet4/Main.cpp不知道如果真的幫助你... – 2017-10-19 07:20:54

回答

0

所有的Direct3D映射的資源應該被處理的掃描線逐個掃描線,所以才扭轉副本:

auto ptr = reinterpret_cast<const uint8_t>(resource.pData) 
      + (desc.BufferDesc.Height - 1) * resource.RowPitch; 

for(unsigned int y = 0; y < desc.BufferDesc.Height; ++y) 
{ 
    // do something with the data in ptr 
    // which is desc.BufferDesc.Width * BytesPerPixel(desc.Format) bytes 
    // i.e. DXGI_FORMAT_R8G8B8A8_UNORM would be desc.BufferDesc.Width * 4 
    ptr -= resource.RowPitch; 
} 

對於大量使用的Direct3D資源工作的例子,見DirectXTex

+0

沒有選項。我需要的副本速度非常快。我試圖在驅動程序或GPU方面做翻轉的方式。我會在我的問題中強調這一點。 –

+0

只需將Vs翻轉即可將四邊形渲染到紋理... –

0

用D3D11_USAGE_DEAFULT創建一個紋理,CPUAccessFlags = 0,BindFlags = D3D11_BIND_SHADER_RESOURCE。將資源交換鏈的後臺緩衝區複製到它。用D3D11_BIND_RENDER_TARGET創建另一個紋理。將其設置爲渲染目標,設置像素着色器並使用第一個紋理繪製翻轉的四邊形。現在,您應該可以將第二個紋理的CopyResource更改爲您現在使用的臨時紋理。這應該比使用CPU複製翻轉的圖像數據更快。但是,這種解決方案會佔用GPU上的更多資源,並且可能很難在鉤子中進行設置。