【发布时间】:2016-10-06 15:43:12
【问题描述】:
我知道这个问题的术语肯定是全错的,但是请大家多多包涵,试着站在我门外汉的角度看问题(我没有计算机技术的形成,我是一个自学成才的爱好者。最接近的我接受过正规的编程语言教育是我学校的机器人俱乐部)。
我想要的是能够将托管 DirectX 12 用作我的应用程序的“背景”,并带有游戏循环等等。并且,如果可能的话,能够拥有 WPF 控件,如功能区或工具箱或实际 directX 游戏周围的菜单。我一直在寻找整个互联网,我发现的只是 Windows 和 DirectX 9.0 的非常旧的东西;我希望这些天有新的东西。
我尝试了Windows Form的方法,基本上是这样的:
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 事件每帧(或滴答声?)被调用一次,所以这个事件的处理程序必须用作游戏循环。
所以我尝试了这个:
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 事件处理程序内部调用了 render。结果相同:没有窗口。
谁能指出我正确的方向?
【问题讨论】:
标签: c# wpf interop directx-12