2017-10-19 13 views
0

Ich führe eine Erfassung von Direct3D-Back-Buffer. Wenn ich die Pixel herunterlade, wird der Bildrahmen um seine vertikale Achse gedreht. Ist es möglich, D3D mitzuteilen, dass der Rahmen beim Kopieren der Ressource oder beim Erstellen des Ziels ID3D11Texture2D gedreht werden soll?Direct3D11: Spiegeln ID3D11Texture2D

Hier ist, wie ich es tun:

Die Textur, in die ich den Frame-Buffer kopieren wie folgt erstellt:

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); 

Dann auf jeden Frame ich tun:

 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: Ich habe keine Kontrolle über die Rendering-Pipeline. Ich hänge eine externe App mit diesem Code an. Ich möchte auch nicht mit dem Pixel-Puffer auf der CPU, wie Reverse-Kopie in einer Schleife, etc .. Die niedrige Latenz der Kopie hat hohe Priorität.

UPDATE:

ich dies auch versucht:

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); 

, die den Rahmen verursacht von seinem Inhalt leer zu sein.

+0

Vergessen Sie nicht, die '' HRESULT'' Werte für diejenigen Funktionen zu überprüfen, die nicht ''void'' zurückgeben. Sie gehen derzeit davon aus, dass es immer funktioniert. Verwenden Sie '' SUCCEEDED'', '' FAILED'' oder etwas wie [ThrowIfFailed] (https://github.com/Microsoft/DirectXTK/wiki/ThrowIfFailed). –

+0

@ChuckWalbourn Eigentlich macht es den ganzen Weg..Entschieden hier wegen der Einfachheit. –

+0

Ein Beispiel basierend auf Multi-Hooks ein altes Projekt: https://github.com/headmax/Cplus/blob/master/Projet4/Main.cpp dunno wenn Sie wirklich helfen ... –

Antwort

0

Alle Direct3D abgebildet Ressourcen sollten Scanline-by Abtastlinien verarbeitet werden, so dass nur die Kopie umkehren:

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

Für viele Beispiele mit Direct3D Ressourcen arbeiten, sehen DirectXTex.

+0

Keine Option. Ich brauche die Kopie, um extrem schnell zu sein. Ich suche einen Weg, um den Schlag auf Fahrer- oder GPU-Seite zu machen. Ich werde es in meiner Frage betonen. –

+0

Sie können einfach ein Quad in eine Textur mit der Vs umgedreht rendern ... –

0

Erstellen Sie eine Textur mit D3D11_USAGE_DEAFULT, mit CPUAccessFlags = 0 und BindFlags = D3D11_BIND_SHADER_RESOURCE. CopyResource den Backbuffer der Swapchain zu ihm. Erstellen Sie eine andere Textur mit D3D11_BIND_RENDER_TARGET. Setze es als Renderziel, setze einen Pixelshader und zeichne einen umgedrehten Quad mit der ersten Textur. Jetzt sollten Sie in der Lage sein, die zweite Textur auf die Staging-Textur, die Sie jetzt verwenden, zu kopieren. Dies sollte schneller sein als das Kopieren von gespiegelten Bilddaten mit der CPU. Diese Lösung würde jedoch mehr Ressourcen auf der GPU benötigen und möglicherweise in einem Hook schwer einzurichten sein.