2008-09-29 8 views
5

Desidero disegnare il contenuto DirectX in modo che appaia sopra il desktop e qualsiasi altra applicazione in esecuzione. Devo anche essere in grado di rendere semi-trasparente il contenuto di directx, quindi le altre cose vengono mostrate. C'è un modo per farlo?Come si disegna un contenuto DirectX trasparente in una finestra trasparente?

Sto utilizzando Managed DX con C#.

+0

Non sono disponibili finestre a più livelli? –

+0

http://msdn.microsoft.com/en-us/library/ms997507.aspx –

risposta

5

Ho trovato una soluzione che funziona su Vista, a partire dal collegamento fornito da OregonGhost. Questo è il processo di base, nella sintassi C#. Questo codice si trova in una classe che eredita da Form. Non sembra funzionare se in un UserControl:

//this will allow you to import the necessary functions from the .dll 
using System.Runtime.InteropServices; 

//this imports the function used to extend the transparent window border. 
[DllImport("dwmapi.dll")] 
static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMargins); 

//this is used to specify the boundaries of the transparent area 
internal struct Margins { 
    public int Left, Right, Top, Bottom; 
} 
private Margins marg; 

//Do this every time the form is resized. It causes the window to be made transparent. 
marg.Left = 0; 
marg.Top = 0; 
marg.Right = this.Width; 
marg.Bottom = this.Height; 
DwmExtendFrameIntoClientArea(this.Handle, ref marg); 

//This initializes the DirectX device. It needs to be done once. 
//The alpha channel in the backbuffer is critical. 
PresentParameters presentParameters = new PresentParameters(); 
presentParameters.Windowed = true; 
presentParameters.SwapEffect = SwapEffect.Discard; 
presentParameters.BackBufferFormat = Format.A8R8G8B8; 

Device device = new Device(0, DeviceType.Hardware, this.Handle, 
CreateFlags.HardwareVertexProcessing, presentParameters); 

//the OnPaint functions maked the background transparent by drawing black on it. 
//For whatever reason this results in transparency. 
protected override void OnPaint(PaintEventArgs e) { 
    Graphics g = e.Graphics; 

    // black brush for Alpha transparency 
    SolidBrush blackBrush = new SolidBrush(Color.Black); 
    g.FillRectangle(blackBrush, 0, 0, Width, Height); 
    blackBrush.Dispose(); 

    //call your DirectX rendering function here 
} 

//this is the dx rendering function. The Argb clearing function is important, 
//as it makes the directx background transparent. 
protected void dxrendering() { 
    device.Clear(ClearFlags.Target, Color.FromArgb(0, 0, 0, 0), 1.0f, 0); 

    device.BeginScene(); 
    //draw stuff here. 
    device.EndScene(); 
    device.Present(); 
} 

Infine, un modulo con l'impostazione di default avrà una vetroso cercando di sfondo parzialmente trasparente. Imposta FormBorderStyle su "none" e sarà trasparente al 100% con il solo contenuto che fluttua sopra tutto.

2

Immagino che sarà difficile senza utilizzare Desktop Window Manager, ad esempio se si desidera supportare Windows XP. Con il DWM, sembra essere rather easy.

Se la velocità non è un problema, è possibile ottenere il rendering su una superficie e quindi copiare l'immagine renderizzata in una finestra a più livelli. Non aspettarti che per essere veloce però.

+0

Un dolore che funziona solo con dx9, poiché DWM in Vista è dx9. Windows 7 userà dx10, quindi sarà bello. –

1

WPF è anche un'altra opzione.

Sviluppato da Microsoft, il Windows Presentation Foundation (WPF o) è un sottosistema grafico del computer-software per il rendering interfacce utente nelle applicazioni basate su Windows.

+1

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. – fglez

+0

Nota come è stata data risposta a quasi 4 anni fa, durante la beta? Domande e risposte allora erano sperimentali. Questa non è certamente una risposta brillante, ma è una risposta e una valida a questo. Il link è valido così come il contenuto. –

3

È possibile utilizzare DirectComposition, LayeredWindows, DesktopWindowManager o WPF. Tutti i metodi presentano vantaggi e svantaggi:

-DirectComposition è il più efficiente, ma richiede Windows 8 ed è limitato a 60Hz.

-LayeredWindows sono difficili da utilizzare con D3D tramite Direct2D-interop che utilizza DXGI.

-WPF è relativamente facile da usare tramite D3DImage, ma è anche limitato a 60 Hz e DX9 e non a MSAA. È possibile utilizzare le versioni DX da Interop a DX-DX, inoltre è possibile utilizzare MSAA quando il MSAA-Rendertarget viene risolto sulla superficie nativa nonMSAA.

-DesktopWindowManager è ottimo per le prestazioni elevate disponibili da Windows Vista, ma le versioni DirectX sembrano essere limitate dalla versione utilizzata dal DWM (ancora DX9 su Vista). Soluzioni alternative per versioni DX più elevate dovrebbero essere possibili tramite DXGI ove disponibile

Se non è necessario per pixel aplha, è anche possibile utilizzare il valore di opacità di un modulo semitrasparente. Sono stato in grado di utilizzare tutte le tecniche descritte con C# e SharpDX, ma nel caso di DirectComposition e LayeredWindows era necessario un piccolo C++ - Wrappercode. Per i principianti suggerirei di andare via WPF.