Відображення вигляду XNA безпосередньо на вікні WPF
зведення
Описує, як рендерити безпосередньо у вікні WPF за допомогою XNA.
Робоче середовище
Передумови
Підтримувані версії XNA |
|
Підтримувані платформи |
|
Потрібна версія Vertex Shader для 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. Крім того, як вимога до апаратного забезпечення, потрібна «відеокарта, яка підтримує Pixel Shader 1.1 або вище».
Крім того, проект був створений в "Visual Studio 2008 Professional Edition". Підготуйте середовище для Visual Studio 2008.