如何在透明窗口中绘制透明的DirectX内容?

时间:2008-09-29 11:05:53

标签: c# windows directx transparent direct3d

我想绘制DirectX内容,使其看起来漂浮在桌面顶部和正在运行的任何其他应用程序上。我还需要能够使directx内容半透明,以便其他内容显示出来。有没有办法做到这一点?

我正在使用带有C#的Managed DX。

4 个答案:

答案 0 :(得分:5)

我找到了一个适用于Vista的解决方案,从OregonGhost提供的链接开始。这是C#语法的基本过程。此代码位于继承自Form的类中。如果在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();
}

最后,具有默认设置的表单将具有玻璃般的部分透明背景。将FormBorderStyle设置为“none”,它将是100%透明的,只有您的内容浮动在所有内容之上。

答案 1 :(得分:4)

您可以使用DirectComposition,LayeredWindows,DesktopWindowManager或WPF。所有方法都有其优点和缺点:

-DirectComposition是最有效的,但需要Windows 8,并且限制为60Hz。

-LayeredWindows使用DXGI通过Direct2D-interop与D3D合作很棘手。

-WPF相对易于使用D3DImage,但也限于60Hz和DX9,没有MSAA。可以通过DXGI与更高版本的DX版本互操作,当MSAA-Rendertarget解析为原生非MSAA表面时,也可以使用MSAA。

-DesktopWindowManager非常适合自Windows Vista以来的高性能,但DirectX-Versions似乎受到DWM使用的版本(Vista上仍为DX9)的限制。应该可以通过可用的DXGI获得更高DX版本的变通方法

如果您不需要每像素aplha,您还可以使用半透明表单的不透明度值。我已经能够使用所有描述的技术与C#和SharpDX,但在DirectComposition和LayeredWindows的情况下,需要一点C ++ - Wrappercode。对于初学者,我建议通过WPF。

答案 2 :(得分:2)

我想如果你不想使用桌面窗口管理器,那就很难了,即如果你想支持Windows XP。使用DWM,它似乎是rather easy

如果速度不是问题,您可以放弃渲染到曲面,然后将渲染图像复制到分层窗口。不要指望那么快。

答案 3 :(得分:1)

WPF也是另一种选择。

  

由Microsoft开发,Windows Presentation Foundation(或WPF)是一个计算机软件图形子系统,用于在基于Windows的应用程序中呈现用户界面。