2008-09-29 194 views
5

我想繪製DirectX內容,以便它看起來是懸浮在桌面和任何其他正在運行的應用程序的頂部。我也需要能夠使directx內容變得半透明,所以其他的東西都會顯示出來。有沒有辦法做到這一點?如何在透明窗口中繪製透明的DirectX內容?

我使用託管DX用C#。

+0

是不是分層窗口的選項? – 2008-11-06 05:00:36

+0

http://msdn.microsoft.com/en-us/library/ms997507.aspx – 2008-11-06 05:01:11

回答

5

我發現它工作在Vista上,從OregonGhost所提供的鏈接開始的解決方案。這是C#語法中的基本過程。此代碼位於從Form繼承的類中。它似乎並不如在用戶控件的工作:

//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設置爲「無」,並且它將100%透明,只有您的內容高於一切。

2

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

如果速度不是問題,您可能會脫離渲染到表面,然後將渲染圖像複製到分層窗口。不要指望這會很快。

+0

由於Vista中的DWM是dx9,所以只能在dx9下使用。 Windows 7將使用dx10,這樣會很好。 – 2009-02-20 13:04:41

1

WPF也是另一種選擇。

由微軟爲Windows Presentation Foundation(WPF或)開發是基於Windows的應用程序渲染用戶界面的計算機軟件的圖形子系統。

3

您可以使用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版本似乎受限於DWM使用的版本(仍然是Vista上的DX9)。更高DX版本的解決方法應該可以通過DXGI在可用的情況下使用

如果您不需要每像素aplha,也可以使用半透明窗體的opacity-value。我已經能夠在C#和SharpDX中使用所有描述的技術,但是在DirectComposition和LayeredWindows的情況下需要一些C++ - Wrappercode。對於初學者,我會建議通過WPF。