我知道这个问题的术语一定是错的,但请耐心等待,并且从我的外行人的角度来看待事情(我没有计算机技术的形成,我是一个自学成才的爱好者。从编程语言的正规教育中获得我的学校的机器人俱乐部)。有没有办法在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
事件处理中呈现。同样的结果:没有窗口。
任何人都可以指向正确的方向吗?
我有一个非常强大的GPU,并且据说DirectX 12从图形库中获得了最好的性能,我想看看它有多好。非常感谢您的链接,看起来很有希望。 – FinnTheHuman
DirectX 12具有*潜力*以获得更好的CPU性能,但需要大量工程努力才能实现。如果您需要Direct3D硬件功能级别11.0或更高版本(DX12没有用于FL 9.x或10.x设备的任何驱动程序),则DX11和DX12的GPU功能相同。一般来说,除非你有一大批需要DX12 API提供的额外控制的图形工程师,否则在将DX11转移到DX12之前,你应该已经将DX11推向了突破点。对于独立或小型团队来说,保持DX 12快乐是一大笔工作。 –
我想为DX12提供模拟功能的唯一方法就是我想学习它,而不是像现在想要用它来玩游戏。所以,对DX12也有这样的控制是很好的。 – Yola