Показване на 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.