2016-06-06 59 views
0

我知道这个问题的术语一定是错的,但请耐心等待,并且从我的外行人的角度来看待事情(我没有计算机技术的形成,我是一个自学成才的爱好者。从编程语言的正规教育中获得我的学校的机器人俱乐部)。有没有办法在WPF窗口中托管DirectX12应用程序?

我想要的是能够使用托管DirectX 12作为我的应用程序的“背景”,带有游戏循环和全部。并且,如果可能的话,可以在实际的directX游戏周围使用WPF控件,例如功能区或工具箱或菜单。我一直在寻找互联网,我发现所有的东西都是Windows和DirectX 9.0的老东西;我希望这些日子有新的东西。

我tryed Windows窗体的方法,基本上是这样的:

using System; 
using System.Windows; 
using System.Windows.Interop; 
using Microsoft.DirectX.Direct3D; 
using DColor = System.Drawing.Color; 

public partial class MainWindow : Window 
{ 
    Device device; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     initDevice(); 
    } 

    private void initDevice() 
    { 
     try 
     { 
      PresentParameters parameters = new PresentParameters(); 
      parameters.Windowed = true; 
      parameters.SwapEffect = SwapEffect.Discard; 
      IntPtr windowHandle = new WindowInteropHelper(this).Handle; 

      device = new Device(0, DeviceType.Hardware, windowHandle, CreateFlags.HardwareVertexProcessing, parameters); 
     } 
     catch(Exception e) 
     { 
      MessageBox.Show("initDevice threw an Exception\n" + e.Message, "ERROR", MessageBoxButton.OK, MessageBoxImage.Error); 
     } 
    } 

    private void render() 
    { 
     device.Clear(ClearFlags.Target, DColor.LightGreen, 0f, 1); 
     device.Present(); 
    } 
} 

没有抛出异常,窗口永远不会呈现在所有。应用程序运行,但窗口不显示。我不认为这会起作用,因为没有游戏循环,并且render不会从任何地方被调用,但我没有想到窗口甚至没有被显示。如果我注释掉调用initDevice()的那一行,WPF的空白窗口通常会显示为

然后我发现CompositionTarget.Rendering事件每帧调用一次(或tick?),所以此事件的处理程序必须用作游戏循环。

,所以我尝试这样做:

using System; 
using System.Drawing; 
using System.IO; 
using System.Windows; 
using System.Windows.Media; 
using System.Windows.Forms.Integration; 
using Microsoft.DirectX.Direct3D; 
using DColor = System.Drawing.Color; 
using System.Windows.Forms; 

public partial class MainWindow : Window 
{ 
    Device device = null; 
    MemoryStream stream; 
    PictureBox display; 
    WindowsFormsHost host; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     initDevice(); 
     CompositionTarget.Rendering += CompositionTarget_Rendering; 
    } 

    private void CompositionTarget_Rendering(object sender, EventArgs e) 
    { 
     render(); 
    } 

    private void initDevice() 
    { 
     try 
     { 
      PresentParameters parameters = new PresentParameters(); 
      parameters.Windowed = true; 
      parameters.SwapEffect = SwapEffect.Discard; 

      device = new Device(0, DeviceType.Hardware, display, CreateFlags.HardwareVertexProcessing, parameters); 
      stream = new MemoryStream(); 
      device.SetRenderTarget(0, new Surface(device, stream, Pool.Managed)); 
     } 
     catch(Exception e) 
     { 
      System.Windows.MessageBox.Show("initDevice threw an Exception\n" + e.Message, "ERROR", MessageBoxButton.OK, MessageBoxImage.Error); 
     } 
    } 

    private void render() 
    { 
     device.Clear(ClearFlags.Target, DColor.LightGreen, 0f, 1); 
     device.Present(); 
     display.Image = Image.FromStream(stream); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     host = new WindowsFormsHost(); 
     display = new PictureBox(); 
     host.Child = display; 
     mainGrid.Children.Add(host); 
    } 
} 

仍然没有显示窗口,即使应用程序正在运行,而不是崩溃。

最后我想同样的事情,但没有处理CompositionTarget.Rendering,但使用DispatcherTimer代替,并呼吁其Tick事件处理中呈现。同样的结果:没有窗口。

任何人都可以指向正确的方向吗?

回答

1

project应该有所帮助。它目前仅支持Direct3D 11,但其原理与DirectX 12相同。

那么,为什么您需要DirectX 12而不是仅仅使用DirectX 11?答案应该是比“12比11大”更具技术性的东西。

+0

我有一个非常强大的GPU,并且据说DirectX 12从图形库中获得了最好的性能,我想看看它有多好。非常感谢您的链接,看起来很有希望。 – FinnTheHuman

+3

DirectX 12具有*潜力*以获得更好的CPU性能,但需要大量工程努力才能实现。如果您需要Direct3D硬件功能级别11.0或更高版本(DX12没有用于FL 9.x或10.x设备的任何驱动程序),则DX11和DX12的GPU功能相同。一般来说,除非你有一大批需要DX12 API提供的额外控制的图形工程师,否则在将DX11转移到DX12之前,你应该已经将DX11推向了突破点。对于独立或小型团队来说,保持DX 12快乐是一大笔工作。 –

+0

我想为DX12提供模拟功能的唯一方法就是我想学习它,而不是像现在想要用它来玩游戏。所以,对DX12也有这样的控制是很好的。 – Yola

相关问题