Paparkan pandangan XNA terus pada tetingkap WPF
Ringkasan
Menerangkan cara untuk memaparkan terus dalam tetingkap WPF dengan XNA.
Persekitaran operasi
Prasyarat
Versi XNA yang Disokong |
|
Platform yang Disokong |
|
Versi Vertex Shader yang Diperlukan Windows | 1.1 |
Windows Versi Pixel Shader Diperlukan | 1.1 |
Persekitaran operasi
Platform |
Bahan
Dalam Menggunakan XNA dalam Aplikasi WPF, saya menggunakan kawalan WindowsFormsHost untuk memaparkan pandangan, tetapi sekarang saya mahu menggunakan hanya tetingkap WPF untuk memaparkan poligon. "Menggunakan XNA dalam Aplikasi WPF" adalah sedikit perwakilan, jadi saya akan menerangkan perbezaannya.
Alias ruang nama
// 名前空間エイリアス
using Xna = Microsoft.Xna.Framework;
using XnaGraphics = Microsoft.Xna.Framework.Graphics;
Oleh kerana struktur Warna dan Matriks diliputi oleh Rangka Kerja XNA dan ruang nama WPF, anda mesti menentukan nama struktur daripada ruang nama untuk menggunakannya. Walau bagaimanapun, nampaknya panjang setiap kali, jadi saya mencipta alias ruang nama. Sebagai contoh, "Microsoft.Xna.Framework.Rectangle" kini boleh ditentukan sebagai "Xna.Rectangle".
Pemasa
Sejak .NET Framework 3.0, kelas pemasa yang dipanggil "System.Windows.Threading.DispatcherTimer" telah tersedia, dan kelas pemasa ini digunakan untuk memaparkan setiap bingkai. WPF menggunakan DispatcherTimer untuk membenarkan pemprosesan pada jaluran yang sama seperti UI.
<summary>
タイマー
</summary>
private DispatcherTimer timer = null;
, mengisytiharkan DispatcherTimer.
<summary>
タイマーイベント
</summary>
<param name="sender"></param>
<param name="e"></param>
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
this.Draw();
}
Mentakrifkan kaedah yang dipanggil oleh DispatcherTimer pada selang masa yang tetap.
// タイマー
this.timer = new DispatcherTimer();
this.timer.Tick += new EventHandler(dispatcherTimer_Tick);
this.timer.Interval = new TimeSpan(0, 0, 0, 0, 16);
this.timer.Start();
Ini ialah proses menetapkan pemasa. Selepas mencipta contoh DispatcherTimer dan menetapkan kaedah untuk memanggil dan selang masa, kaedah DispatcherTimer.Start memulakan pemasa.
Mendapatkan Pemegang Tingkap
Untuk mencipta peranti Direct3D, anda memerlukan pemegang tetingkap. Walau bagaimanapun, WPF tidak mempunyai konsep pemegang tetingkap, jadi tiada cara untuk mendapatkannya terus daripada kelas Window.
Walau bagaimanapun, memandangkan terdapat kalanya pemegang tetingkap diperlukan, seperti dalam kes ini, pemegang tetingkap boleh diperolehi melalui kelas "System.Windows.Interop.WindowInteropHelper" sebagai interop untuk kod Win32. (ini ialah kelas Window)
// ウィンドウハンドルを取得する
IntPtr handle = new WindowInteropHelper(this).Handle;
Gunakan pemegang ini semasa mencipta peranti Direct3D. Walau bagaimanapun, jika anda cuba mendapatkan pemegang tetingkap dalam kaedah OnInitialized, ia akan mengembalikan 0, mungkin kerana tetingkap belum dicipta lagi. Dalam sampel ini, peranti dicipta dalam kaedah OnSourceInitialized.
Render ke Kawasan Tertentu
Anda boleh menentukan kawasan destinasi sebagai hujah kedua GraphicsDevice.Present. Dalam sampel, saya cuba melukisnya pada kedudukan (50, 50) sebagai offset. Saiznya sama dengan saiz penampan belakang (300, 300). Hujah pertama ialah kawasan dari mana hendak dilukis, dan jika nol ditentukan, penimbal asal digunakan.
// 描画先を指定する
Xna.Rectangle rect = new Xna.Rectangle(
50, 50,
(int)this.viewSize.Width, (int)this.viewSize.Height);
this.device.Present(null, rect, this.windowHandle);
Memusnahkan peranti
Anda memusnahkan peranti anda apabila anda menutup tetingkap. Pada asalnya, saya mahu mengendalikannya dengan kaedah Dispose, tetapi kerana kelas Tetingkap WPF tidak mewarisi IDisposable secara lalai, saya menulisnya di sini.
<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);
}
Pelaksanaan
Jika anda menjalankan program sampel, anda boleh menjalankannya dengan imej skrin seperti yang ada di permulaan artikel.
Pada pandangan pertama, ia dipaparkan dengan baik, tetapi apabila saya mengubah saiz tetingkap dengan menyeretnya dengan tetikus, paparan berkelip atau hilang semasa mengubah saiz. Nampaknya ia bercanggah dengan pemaparan WPF, dan saya mencuba banyak perkara tetapi tidak dapat menyelesaikannya.
Jika anda menggunakan XNA, nampaknya lebih selamat untuk menggunakan kawalan WindowsFormsHost.
Program ini memerlukan .NET Framework 3.0, masa jalan DirectX terkini dan Microsoft XNA Framework Redistributable 2.0. Di samping itu, sebagai keperluan perkakasan, "kad grafik yang menyokong Pixel Shader 1.1 atau lebih tinggi" diperlukan.
Di samping itu, projek itu dicipta dalam "Visual Studio 2008 Professional Edition". Sediakan persekitaran untuk Visual Studio 2008.