Question

Je souhaite dessiner le contenu DirectX de sorte qu'il semble flotter au-dessus du bureau et de toutes les autres applications en cours d'exécution. Je dois également pouvoir rendre le contenu directx semi-transparent, pour que d'autres choses se manifestent. Y a-t-il un moyen de le faire?

J'utilise Managed DX avec C #.

Était-ce utile?

La solution

J'ai trouvé une solution qui fonctionne sous Vista, à partir du lien fourni par OregonGhost. C'est le processus de base, en syntaxe C #. Ce code est dans une classe héritant de Form. Cela ne semble pas fonctionner dans 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();
}

Enfin, un formulaire avec les paramètres par défaut aura un arrière-plan partiellement transparent qui donnera un aspect vitreux. Définissez FormBorderStyle sur " none " et ce sera 100% transparent avec seulement votre contenu flottant au-dessus de tout.

Autres conseils

Vous pouvez utiliser DirectComposition, LayeredWindows, DesktopWindowManager ou WPF. Toutes les méthodes ont leurs avantages et leurs inconvénients:

-DirectComposition est la solution la plus efficace, mais nécessite Windows 8 et est limitée à 60 Hz.

-LayeredWindows sont difficiles à utiliser avec D3D via Direct2D-interop à l'aide de DXGI.

-WPF est relativement facile à utiliser via D3DImage, mais est également limité à 60Hz et DX9 sans MSAA. Il est possible d’interconnecter vers des versions DX supérieures via DXGI. MSAA peut également être utilisé lorsque MSAA-Rendertarget est résolu en surface native nonMSAA.

-DesktopWindowManager est idéal pour les hautes performances disponibles depuis Windows Vista, mais les versions DirectX semblent être limitées par la version utilisée par DWM (toujours DX9 sur Vista). Les solutions de contournement pour les versions DX supérieures devraient être possibles via DXGI, le cas échéant.

Si vous n'avez pas besoin d'aplha par pixel, vous pouvez également utiliser la valeur d'opacité d'un formulaire semi-transparent.

Ou utilisez la méthode Win32 native pour l'alpha global de Windows (rappelez-vous qu'un alpha de 0 n'acceptera pas l'entrée de la souris):

SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
COLORREF color = 0;
BYTE alpha = 128;
SetLayeredWindowAttributes(hWnd, color, alpha, LWA_ALPHA);

J'ai pu utiliser toutes les techniques décrites avec C # et SharpDX, mais dans le cas de DirectComposition, LayeredWindows et Win32 natif, un peu de C ++ - Wrappercode était nécessaire. Pour commencer, je suggérerais de passer par WPF.

Je suppose que ce sera difficile sans utiliser le gestionnaire de fenêtres du bureau, c’est-à-dire si vous souhaitez prendre en charge Windows XP. Avec le DWM, il semble plutôt facile .

Si la vitesse ne pose pas de problème, vous pouvez vous échapper en effectuant un rendu sur une surface, puis en copiant l'image rendue dans une fenêtre en couches. Ne vous attendez pas à ce que cela soit rapide cependant.

WPF est également une autre option.

  

Développé par Microsoft, Windows Presentation Foundation (ou WPF) est un sous-système graphique de logiciels permettant de restituer les interfaces utilisateur dans les applications Windows.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top