استخدام XNA في تطبيقات WPF

تحديث الصفحة :
تاريخ إنشاء الصفحة :

ملخص

يصف كيفية استخدام XNA Framework في تطبيقات WPF.

WPF アプリケーションで XNA を使用する

بيئة التشغيل

المتطلبات المسبقه

إصدارات XNA المدعومة
  • 2.0
  • 3.0
المنصات المدعومة
  • Windows (XP SP2 أو أحدث، Vista)
Windows المطلوب إصدار Vertex Shader 1.1
Windows المطلوب إصدار Pixel Shader 1.1

بيئة التشغيل

رصيف

مادة

للعرض على عنصر تحكم معين باستخدام DirectX ، تحتاج إلى الحصول على مقبض النافذة لعنصر التحكم هذا. ومع ذلك ، على عكس عناصر تحكم Windows Form ، لا تحتوي عناصر تحكم WPF على مقابض نوافذ (في WPF ، فإنها ببساطة "ترسم" عنصر التحكم).

ومع ذلك، يوفر WPF عنصر تحكم يسمى "WindowsFormsHost" يسمح لك باستخدام عناصر تحكم Windows Forms.

في هذه المقالة ، سنقوم بإنشاء عينة من رسم مضلع أثناء تدويره كما هو موضح أعلاه ، لكنني سأحذف تفاصيل XNA نفسها لأنها ستكون طويلة جدا لشرحها. سأتحدث فقط عن العلاقة بين WPF و XNA.

أولا ، افتح نافذة WPF (في هذه الحالة ، Window1.xaml) وضع عنصر تحكم WindowsFormHost من شريط الأدوات. شريط التمرير الموجود على اليمين هو مكافأة.

WPF ウインドウデザイン

أحتاج حقا إلى القيام بمزيد من العمل على XAML ، لكنني سأتركه لوقت لاحق لأنه يجب علي إنشاء عناصر التحكم لاستخدام XNA أولا.

أضف "نماذج Windows" "التحكم المخصص" إلى مشروعك. اترك الاسم GraphicsDeviceControl.

Windows Forms のカスタムコントロールを追加

لا تنس إضافة مرجع "Microsoft.Xna.Framework" مسبقا. يوجد أيضا "Microsoft.Xna.Framework.Game" ، ولكن يتم استخدامه في مشروع للعبة فقط ، لذلك ليست هناك حاجة لتضمينه.

Managed DirectX の参照

للحفاظ على نموذج التعليمات البرمجية قصيرا، يتم تلخيص جميع البرامج المتعلقة ب XNA في GraphicsDeviceControl.cs. إنه ليس أسلوب كتابة متعدد الاستخدامات ، لذا يرجى تطبيقه وإعادة كتابته.

يتم عرض التعليمات البرمجية الكاملة ل GraphicsDeviceControl أدناه (باستثناء جزء المصمم). إذا سبق لك استخدام XNA ، فستعرف أنه لا يفعل أي شيء خارج عن المألوف. أنا أستخدم مكون مؤقت لجعل المضلع يبدو وكأنه يدور طوال الوقت.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XNAOnWPF
{
    /// <summary>
    /// グラフィックデバイスコントロール
    /// </summary>
    public partial class GraphicsDeviceControl : Control
    {
        /// <summary>
        /// グラフィックデバイス
        /// </summary>
        private GraphicsDevice device = null;

        /// <summary>
        /// エフェクト
        /// </summary>
        private BasicEffect effect = null;

        /// <summary>
        /// 頂点データ
        /// </summary>
        private VertexPositionColor[] vertices = new VertexPositionColor[3];
        /// <summary>
        /// 頂点データ
        /// </summary>
        public VertexPositionColor[] Vertices
        {
            get { return this.vertices; }
        }


        /// <summary>
        /// コンストラクタ
        /// </summary>
        public GraphicsDeviceControl()
        {
            InitializeComponent();
        }

        /// <summary>
        /// コントロールが作成されるとき
        /// </summary>
        protected override void OnCreateControl()
        {
            if (this.DesignMode == false)
            {
                try
                {
                    // デバイス作成
                    PresentationParameters pp = new PresentationParameters();
                    pp.SwapEffect = SwapEffect.Discard;
                    pp.BackBufferWidth = 300;
                    pp.BackBufferHeight = 300;
                    pp.EnableAutoDepthStencil = true;
                    pp.AutoDepthStencilFormat = DepthFormat.Depth16;
                    this.device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter,
                        DeviceType.Hardware, this.Handle, pp);

                    // 頂点データの設定
                    this.vertices[0] = new VertexPositionColor(
                        new Vector3(0.0f, -2.0f + (float)Math.Sqrt(3) * 3.0f, 0.0f),
                        new Microsoft.Xna.Framework.Graphics.Color(255, 0, 0));
                    this.vertices[1] = new VertexPositionColor(
                        new Vector3(3.0f, -2.0f, 0.0f),
                        new Microsoft.Xna.Framework.Graphics.Color(0, 255, 0));
                    this.vertices[2] = new VertexPositionColor(
                        new Vector3(-3.0f, -2.0f, 0.0f),
                        new Microsoft.Xna.Framework.Graphics.Color(0, 0, 255));

                    // 頂点定義
                    this.device.VertexDeclaration =
                        new VertexDeclaration(this.device, VertexPositionColor.VertexElements);

                    // エフェクト
                    this.effect = new BasicEffect(this.device, null);
                    this.effect.VertexColorEnabled = true;

                    // ビュー変換行列を設定
                    this.effect.View = Matrix.CreateLookAt(
                        new Vector3(0.0f, 0.0f, -10.0f),
                        new Vector3(0.0f, 0.0f, 0.0f),
                        Vector3.Up);

                    // 射影変換を設定
                    this.effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                        MathHelper.ToRadians(45.0f), 1.0f, 1.0f, 100.0f);

                    // レンダリングステート設定
                    this.device.RenderState.CullMode = CullMode.None;
                    this.device.RenderState.AlphaBlendEnable = true;
                    this.device.RenderState.SourceBlend = Blend.SourceAlpha;
                    this.device.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(ex.ToString());
                }
            }

            base.OnCreateControl();
        }

        /// <summary>
        /// 使用中のリソースをすべてクリーンアップします。
        /// </summary>
        /// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }

            if (disposing)
            {
                if (this.device != null)
                {
                    this.device.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        /// <summary>
        /// 描画イベント
        /// </summary>
        /// <param name="pe"></param>
        protected override void OnPaint(PaintEventArgs pe)
        {
            this.Draw();

            base.OnPaint(pe);
        }

        /// <summary>
        /// 描画
        /// </summary>
        private void Draw()
        {
            if (this.device == null)
            {
                return;
            }

            this.device.Clear(Microsoft.Xna.Framework.Graphics.Color.DarkBlue);

            // ポリゴンを描画する
            this.effect.Begin();
            this.effect.Techniques[0].Passes[0].Begin();

            this.effect.World = Matrix.CreateRotationY((float)Environment.TickCount / 1000.0f);
            this.device.DrawUserPrimitives<VertexPositionColor>(
                PrimitiveType.TriangleList, vertices, 0, 1);

            this.effect.Techniques[0].Passes[0].End();
            this.effect.End();

            this.device.Present();
        }

        /// <summary>
        /// タイマーイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer_Tick(object sender, EventArgs e)
        {
            this.Draw();
        }
    }
}

الآن بعد أن قمت بإنشاء عنصر التحكم ، دعنا نلقي نظرة على XAML. نظرا لأننا سنضع عنصر التحكم الذي أنشأناه ، فسنضيف مساحة اسم إلى علامة الجذر. هنا ، يتم تعريفه على أنه "xw".

<Window&nbsp;x:Class="ManagedDirectXOnWPF.Window1"
&nbsp;&nbsp;&nbsp;&nbsp;xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
&nbsp;&nbsp;&nbsp;&nbsp;xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
&nbsp;&nbsp;&nbsp;&nbsp;Title="WPFウインドウ上でManaged DirectXを使用してポリゴン描画"
&nbsp;&nbsp;&nbsp;&nbsp;Height="338"&nbsp;Width="422"
&nbsp;&nbsp;&nbsp;&nbsp;xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xw="clr-namespace:ManagedDirectXOnWPF">
    <!-- 省略 -->
</Window>

بعد ذلك، قم بتوسيع العلامة الخاصة بعنصر تحكم WindowsFormsHost الذي قمت بوضعه للتو، وأضف GraphicsDeviceControl، كما هو موضح أدناه.

<my:WindowsFormsHost&nbsp;Name="windowsFormsHostManagedDirectX"&nbsp;Width="300"&nbsp;Height="300"
                    HorizontalAlignment="Left"&nbsp;VerticalAlignment="Top">
  <xw:GraphicsDeviceControl&nbsp;x:Name="GraphicsDeviceControl"&nbsp;/>
</my:WindowsFormsHost>

ليس عليك أن يكون لديك "x:Name"، ولكن النموذج يستخدمه للوصول إلى بيانات الرأس باستخدام شريط تمرير.

إذا قمت بذلك، يمكنك تشغيل مشهد على WPF حيث يتم رسم المضلعات باستخدام مضلع دوار، كما هو موضح في العينة. الوصول عن طريق شريط التمرير هو مكافأة ، لذا يرجى تنزيل بيانات العينة والتحقق منها.

يتطلب البرنامج .NET Framework 3.0 وأحدث وقت تشغيل DirectX و Microsoft XNA Framework Redistributable 2.0. بالإضافة إلى ذلك ، كمتطلبات للأجهزة ، يلزم وجود "بطاقة رسومات تدعم Pixel Shader 1.1 أو أعلى".

بالإضافة إلى ذلك ، تم إنشاء المشروع في "Visual Studio 2008 Professional Edition". إعداد بيئة ل Visual Studio 2008.