2016-04-22 12 views
1

Ich bin neu in Direct X, aber ich war erfolgreich in der Lage, die Windows Desktop-Duplizierungs-API zur Videoaufnahme zu verwenden. Die API ermöglicht Ihnen auch, Mauszeigerinformationen einschließlich der Position, Höhe, Breite und der Rohpixeldaten (im Systemspeicher) des Cursorbildes abzurufen. Der Mauszeiger wird standardmäßig nicht auf dem erfassten Bildschirmbild gezeichnet, sondern muss manuell bearbeitet werden.Kopieren von ID3D11Texture2D mit richtigem Alpha

Ich versuche, diese Mauszeigerdaten auf das Hauptbildschirm-Capture-Bild zu "kopieren", um ein einzelnes Bild mit einem sichtbaren Mauscursor zu erstellen. Bisher war es mir möglich, den Cursor anzuzeigen, indem ich aus den Cursor-Pixeldaten einen ID3D11Texture2D erstellte und dann einen ID3D11DeviceContext::CopySubresourceRegion vorformte, um den Cursor auf das Hauptbildschirmbild zu kopieren, das ebenfalls als ID3D11Texture2D gespeichert wurde. Die Bildtextur des Hauptbildschirms befindet sich immer im Format und die Roh-Cursor-Pixeldaten seems to be in the same format, mindestens für die DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR Form.

Mein aktuelles Problem scheint mit der Alpha-Handhabung dieser Kopie zu tun zu haben. Der Cursor wird angezeigt, aber wenn das Rechteck kopiert wird, wird das Alpha, das den Cursor umgibt, stattdessen schwarz ausgefüllt. Hier ist ein Beispiel wie es aussieht: Black border around mouse

Es ist mir auch wichtig, dass dies im Videospeicher passiert, da die endgültige Textur direkt vom Videospeicher in einen Videoencoder übergeht.

Ich bin bereit, meine Methode zu ändern, wenn CopySubresourceRegion nicht das richtige Werkzeug für den Job ist. Irgendwelche Ideen, wie ich diesen Cursor auf den Hauptbildschirm Bildtextur mit richtigem Alpha bekommen kann?

Antwort

3

Die einzige Möglichkeit, auf die Alpha-Blending-Funktionen Ihres Grafikprozessors zuzugreifen, sind Draw-Befehle. Kopieren Sie Anrufe nur ersetzen, wie Sie sehen.

Sie haben bereits den Mauszeiger in einem ‚ID3D11Texture2D‘, was Sie jetzt brauchen, ist ein ‚ID3D11ShaderResourceView‘ es als eine Textur zu verwenden, ein ‚ID3DVertexShader‘ und ‚ID3DPixelShader‘ Paar in einer Oberfläche zu machen. Ein 'ID3D11RenderTargetView' von Ihrer Zieloberfläche.

Eine Reihe von 'ID3D11RasterizerState', 'ID3D11DepthStencilState' und 'ID3D11BlendState' zum Konfigurieren des GPU-Status ohne Tiefentest, Alpha-Blend und andere vollständige Einstellung, die meisten von ihnen auf Standard für Sie sollten in Ordnung sein.

Dann müssen Sie ein Quad mit all dem zeichnen, um Ihren Cursor anzuzeigen. Je nachdem, wie Sie den Shader schreiben, benötigen Sie entweder einen konstanten Puffer, einen Vertex-Puffer und ein Eingabe-Layout oder beides.

Für diese Art von Quad-Blit bevorzuge ich normalerweise nur mit einem einzigen konstanten Puffer umzugehen und die Vertex-Position von SV_VertexID innerhalb des Vertex-Shaders neu aufzubauen, aber es liegt an Ihnen.

Dies ist, wie Sie die blit Shader ohne Eckpunktpufferspeicher, eine einzige Draw (4,0) mit einem Streifen primitive Topologie zu verwalten schreiben kann, ist genug:

struct IA { 
    uint vid : SV_VertexID; 
};  
struct VSPS { 
    float4 pos : SV_Position; 
    float2 uv : COLOR; 
};  
struct Root { 
    float left; 
    float top; 
    float right; 
    float bottom; 
}; 

ConstantBuffer<Root> root_ : register(b0); 
Texture2D<float4> texture_ : register(t0); 
SamplerState sampler_ : register(s0); 

void mainvs(in IA input, out VSPS output) { 
    float x = input.vid < 2 ? 0.f : 1.f; 
    float y = (input.vid & 1) ? 1.f : 0.f; 

    output.uv = float2(x, y); 

    float px = input.vid < 2 ? root_.left : root_.right; 
    float py = (input.vid & 1) ? root_.bottom : root_.top;; 

    output.pos = float4(px,py,0.f,1.f); 

    output.pos.y = 1 - output.pos.y; 
    output.pos.xy *= 2; 
    output.pos.xy -= 1; 
} 

float4 mainps(in VSPS input) : SV_TARGET { 
    return texture_.Sample(sampler_, input.uv); 
} 
+1

Es wird von der Antwort impliziert ist, aber es lohnt die besagt, explizit, dass 'CopySubresourceRegion' Alpha-Blending nicht ausführt. Stattdessen erstellt es eine einfache rechteckige Kopie und überschreibt alle Kanäle im Ziel (einschließlich Alpha). Der Grund dafür, dass Sie schwarz sehen, liegt darin, dass die Ursprungstextur {0,0,0,0} außerhalb des Cursorbereichs oder transparent schwarz ist. Bei der Anzeige wird der Alphakanal für die Anzeige ignoriert, was zu opakem Schwarz führt. – MooseBoys

+0

Danke Leute, ich komme dazu, nach einer erfolgreichen Implementierung werde ich für die Annahme zurückkommen. – chrisd1100