Отображение представления XNA непосредственно в окне WPF
сводка
Описывает, как выполнять отрисовку непосредственно в окне WPF с помощью XNA.
Операционная среда
Необходимые условия
Поддерживаемые версии XNA |
|
Поддерживаемые платформы |
|
Windows Требуемая версия вершинного шейдера | 1.1 |
Требуемая версия пиксельного шейдера Windows | 1.1 |
Операционная среда
платформа |
вещество
В разделе Использование XNA в приложениях WPF я использовал элемент управления WindowsFormsHost для отображения представления, но теперь я хочу использовать только окно WPF для отображения многоугольника. "Использование XNA в приложениях WPF" - это своего рода представление, поэтому я объясню различия.
Псевдонимы пространств имен
// 名前空間エイリアス
using Xna = Microsoft.Xna.Framework;
using XnaGraphics = Microsoft.Xna.Framework.Graphics;
Поскольку структуры Color и Matrix охватываются пространствами имен XNA Framework и WPF, для ее использования необходимо указать имя структуры из пространства имен. Однако каждый раз кажется, что он длинный, поэтому я создаю псевдоним пространства имен. Например, "Microsoft.Xna.Framework.Rectangle" теперь можно указать как "Xna.Rectangle".
таймер
Начиная с .NET Framework 3.0, доступен класс таймера под названием "System.Windows.Threading.DispatcherTimer", и этот класс таймера используется для рендеринга каждого кадра. WPF использует DispatcherTimer для обеспечения обработки в том же потоке, что и пользовательский интерфейс.
<summary>
タイマー
</summary>
private DispatcherTimer timer = null;
, объявляя DispatcherTimer.
<summary>
タイマーイベント
</summary>
<param name="sender"></param>
<param name="e"></param>
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
this.Draw();
}
Определяет метод, который DispatcherTimer вызывает через равные промежутки времени.
// タイマー
this.timer = new DispatcherTimer();
this.timer.Tick += new EventHandler(dispatcherTimer_Tick);
this.timer.Interval = new TimeSpan(0, 0, 0, 0, 16);
this.timer.Start();
Это и есть процесс установки таймера. После создания экземпляра DispatcherTimer и установки метода для вызова и интервала времени метод DispatcherTimer.Start запускает таймер.
Получение оконной ручки
Чтобы создать устройство Direct3D, вам понадобится маркер окна. Однако в WPF нет понятия дескриптора окна, поэтому нет способа получить его непосредственно из класса Window.
Однако, поскольку в некоторых случаях требуется дескриптор окна, как в данном случае, дескриптор окна можно получить с помощью класса "System.Windows.Interop.WindowInteropHelper" в качестве взаимодействия для кода Win32. (это класс Window)
// ウィンドウハンドルを取得する
IntPtr handle = new WindowInteropHelper(this).Handle;
Используйте этот дескриптор при создании устройства Direct3D. Однако, если вы попытаетесь получить дескриптор окна в методе OnInitialized, он вернет 0, вероятно, потому, что окно еще не было создано. В этом примере устройство создается в методе OnSourceInitialized.
Рендеринг в указанную область
Область назначения можно указать в качестве второго аргумента GraphicsDevice.Present. В образце я пытаюсь нарисовать его в положении (50, 50) в качестве смещения. Размер такой же, как и размер заднего буфера (300, 300). Первый аргумент — это область, из которой нужно рисовать, и если указано значение null, используется исходный буфер.
// 描画先を指定する
Xna.Rectangle rect = new Xna.Rectangle(
50, 50,
(int)this.viewSize.Width, (int)this.viewSize.Height);
this.device.Present(null, rect, this.windowHandle);
Уничтожение устройства
Вы уничтожаете свое устройство, когда закрываете окно. Первоначально я хотел обрабатывать его с помощью метода Dispose, но поскольку класс WPF Window не наследует IDisposable по умолчанию, я написал его здесь.
<summary>
ウインドウが閉じたとき
</summary>
<param name="e"></param>
protected override void OnClosed(EventArgs e)
{
if (this.device != null)
{
this.device.Dispose();
this.device = null;
}
base.OnClosed(e);
}
исполнение
Если вы запустите пример программы, вы можете запустить ее с изображением экрана, как в начале статьи.
На первый взгляд, он хорошо рендерится, но когда я изменяю размер окна, перетаскивая его мышкой, вид мерцает или исчезает во время изменения размера. Кажется, это конфликтует с рендерингом WPF, и я перепробовал много вещей, но не смог решить эту проблему.
Если вы используете XNA, кажется более безопасным использовать элемент управления WindowsFormsHost.
Для работы программы требуется .NET Framework 3.0, новейшая среда выполнения DirectX и распространяемый компонент Microsoft XNA Framework Redistributable 2.0. Кроме того, в качестве требования к оборудованию требуется «видеокарта, поддерживающая пиксельные шейдеры 1.1 или выше».
Кроме того, проект был создан в "Visual Studio 2008 Professional Edition". Подготовка среды для Visual Studio 2008.