عرض طريقة عرض XNA مباشرة على نافذة WPF
ملخص
يصف كيفية العرض مباشرة في نافذة WPF باستخدام XNA.
بيئة التشغيل
المتطلبات المسبقه
إصدارات XNA المدعومة |
|
المنصات المدعومة |
|
Windows المطلوب إصدار Vertex Shader | 1.1 |
Windows المطلوب إصدار Pixel Shader | 1.1 |
بيئة التشغيل
رصيف |
مادة
في استخدام XNA في تطبيقات WPF ، استخدمت عنصر تحكم WindowsFormsHost لعرض طريقة العرض ، لكنني الآن أريد استخدام نافذة WPF فقط لعرض المضلع. "استخدام XNA في تطبيقات WPF" هو تمثيل إلى حد ما ، لذلك سأشرح الاختلافات.
الأسماء المستعارة لمساحة الاسم
// 名前空間エイリアス
using Xna = Microsoft.Xna.Framework;
using XnaGraphics = Microsoft.Xna.Framework.Graphics;
نظرا لأن بنيتي اللون والمصفوفة مشمولتان بمساحات أسماء 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;
، معلنا عن جهاز ضبط الوقت.
<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. (هذه هي فئة النافذة)
// ウィンドウハンドルを取得する
IntPtr handle = new WindowInteropHelper(this).Handle;
استخدم هذا المقبض عند إنشاء جهاز Direct3D. ومع ذلك ، إذا حاولت الحصول على مقبض النافذة في الأسلوب OnInitialized ، فسيعود 0 ، ربما لأن النافذة لم يتم إنشاؤها بعد. في هذا النموذج، يتم إنشاء الجهاز في الأسلوب OnSourceInitialized.
العرض إلى منطقة محددة
يمكنك تحديد منطقة الوجهة كوسيطة ثانية ل GraphicsDevice.Present. في العينة ، أحاول رسمها في الموضع (50 ، 50) كتعويض. الحجم هو نفس حجم backbuffer (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);
تدمير جهاز
أنت تدمر جهازك عند إغلاق النافذة. في الأصل ، كنت أرغب في التعامل معها باستخدام طريقة التخلص ، ولكن نظرا لأن فئة 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.