نمایش نمای XNA مستقیما روی پنجره WPF
خلاصه
نحوه رندر مستقیم در پنجره WPF با XNA را توضیح می دهد.
محیط عملیاتی
پیش نیازها
نسخه های XNA پشتیبانی شده |
|
پلتفرم های پشتیبانی شده |
|
نسخه Vertex Shader مورد نیاز ویندوز | 1.1 |
ویندوز نسخه Pixel Shader مورد نیاز است | 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" به عنوان interop برای کد 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" ایجاد شده است. یک محیط برای ویژوال استودیو 2008 آماده کنید.