2008-09-29 18 views
5

Quiero dibujar contenido de DirectX para que parezca estar flotando sobre la parte superior del escritorio y cualquier otra aplicación que se esté ejecutando. También necesito poder hacer que el contenido de Directx sea semitransparente, para que se muestren otras cosas. ¿Hay alguna forma de hacer esto?¿Cómo se dibuja el contenido transparente de DirectX en una ventana transparente?

Estoy usando Managed DX con C#.

+0

¿No son ventanas en capas una opción? –

+0

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

Respuesta

5

Encontré una solución que funciona en Vista, a partir del enlace proporcionado por OregonGhost. Este es el proceso básico, en sintaxis C#. Este código pertenece a una clase que hereda de Form. No parece funcionar si en un control de usuario:

//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(); 
} 

Por último, un formulario con ajuste por defecto tendrá un fondo de mirada vidriosa parcialmente transparente. Establezca FormBorderStyle en "none" y será 100% transparente, con solo su contenido flotando por encima de todo.

2

Supongo que será difícil sin utilizar Desktop Window Manager, es decir, si desea admitir Windows XP. Con el DWM, parece ser rather easy sin embargo.

Si la velocidad no es un problema, puede salirse con la renderización a una superficie y luego copiar la imagen renderizada en una ventana en capas. Sin embargo, no esperes que sea rápido.

+0

Un problema que solo funciona con dx9, ya que DWM en Vista es dx9. Windows 7 usará dx10, así que será agradable. –

1

WPF es también otra opción.

Desarrollado por Microsoft, Windows Presentation Foundation (o WPF) es un subsistema gráfico de software para la representación de interfaces de usuario en aplicaciones basadas en Windows.

+1

Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. – fglez

+0

Observe cómo esto fue respondido hace casi 4 años, durante la versión beta? Las preguntas y respuestas en ese momento fueron experimentales. Esto ciertamente no es una respuesta brillante, pero es una respuesta y una respuesta viable. El enlace es válido como es el contenido. –

3

Puede usar DirectComposition, LayeredWindows, DesktopWindowManager o WPF. Todos los métodos vienen con sus ventajas y desventajas:

-DirectComposition es el más eficiente, pero necesita Windows 8 y está limitado a 60Hz.

-LayeredWindows son difíciles de trabajar con D3D a través de Direct2D-interop usando DXGI.

-WPF es relativamente fácil de usar a través de D3DImage, pero también está limitado a 60Hz y DX9 y no a MSAA. Es posible interoperar con versiones DX más altas a través de DXGI, también se puede usar MSAA cuando el MSAA-Rendertarget se resuelve en la superficie no MSAA nativa.

-DesktopWindowManager es ideal para el alto rendimiento disponible desde Windows Vista, pero las versiones de DirectX parecen estar limitadas por la versión que utiliza DWM (todavía DX9 en Vista). Las soluciones provisionales para versiones DX más altas deberían ser posibles a través de DXGI donde esté disponible

Si no necesita una aplha por píxel, también puede usar el valor de opacidad de una forma semitransparente. He podido utilizar todas las técnicas descritas con C# y SharpDX, pero en el caso de DirectComposition y LayeredWindows se necesitaba un pequeño C++ - Wrappercode. Para empezar, sugeriría ir a través de WPF.

Cuestiones relacionadas