WPF अनुप्रयोगों में XNA का उपयोग करना

पेज अद्यतन :
पेज निर्माण की तारीख :

सारांश

वर्णन करता है कि WPF अनुप्रयोगों में XNA Framework का उपयोग कैसे करें.

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

परिचालन का वातावरण

आवश्यकताएँ

समर्थित XNA संस्करण
  • 2.0
  • 3.0
समर्थित प्लेटफार्म
  • Windows (XP SP2 या बाद के संस्करण, Vista)
Windows आवश्यक वर्टेक्स शेडर संस्करण 1.1
Windows आवश्यक पिक्सेल शेडर संस्करण 1.1

परिचालन का वातावरण

प्लेटफार्म

सार तत्व

DirectX का उपयोग करके किसी विशेष नियंत्रण पर रेंडर करने के लिए, आपको उस नियंत्रण के लिए विंडो हैंडल प्राप्त करने की आवश्यकता है। हालांकि, विंडोज फॉर्म नियंत्रणों के विपरीत, डब्ल्यूपीएफ नियंत्रणों में विंडो हैंडल नहीं होते हैं (डब्ल्यूपीएफ में वे बस नियंत्रण को "आकर्षित" करते हैं)।

हालाँकि, WPF "WindowsFormsHost" नामक एक नियंत्रण प्रदान करता है जो आपको Windows प्रपत्र नियंत्रणों का उपयोग करने की अनुमति देता है।

इस लेख में, हम एक बहुभुज ड्राइंग का एक नमूना बनाएंगे क्योंकि इसे ऊपर दिखाए गए अनुसार घुमाया गया है, लेकिन मैं एक्सएनए के विवरण को छोड़ दूंगा क्योंकि इसे समझाने के लिए बहुत लंबा होगा। मैं सिर्फ डब्ल्यूपीएफ और एक्सएनए के बीच संबंधों के बारे में बात करूंगा।

सबसे पहले, एक WPF विंडो खोलें (इस स्थिति में, Window1.xaml) और टूलबार से WindowsFormHost नियंत्रण रखें। दाईं ओर स्लाइडर एक बोनस है।

WPF ウインドウデザイン

मुझे वास्तव में एक्सएएमएल पर थोड़ा और काम करने की ज़रूरत है, लेकिन मैं इसे बाद के लिए छोड़ दूंगा क्योंकि मुझे पहले एक्सएनए का उपयोग करने के लिए नियंत्रण बनाना होगा।

अपने प्रोजेक्ट में "विंडोज फॉर्म", "कस्टम कंट्रोल" जोड़ें। GraphicsDeviceControl नाम छोड़ दें।

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

पहले से "Microsoft.Xna.Framework" संदर्भ जोड़ने के लिए मत भूलना। "Microsoft.Xna.Framework.Game" भी है, लेकिन इसका उपयोग केवल-गेम प्रोजेक्ट में किया जाता है, इसलिए इसे शामिल करने की कोई आवश्यकता नहीं है।

Managed DirectX の参照

नमूना कोड को छोटा रखने के लिए, सभी XNA-संबंधित प्रोग्राम GraphicsDeviceControl.cs में सारांशित किए जाते हैं. यह बहुत बहुमुखी लेखन शैली नहीं है, इसलिए कृपया इसे लागू करें और इसे फिर से लिखें।

GraphicsDeviceControl के लिए पूरा कोड (डिजाइनर भाग को छोड़कर) नीचे दिखाया गया है। यदि आपने कभी एक्सएनए का उपयोग किया है, तो आपको पता चल जाएगा कि यह सामान्य से कुछ भी नहीं करता है। मैं बहुभुज को हर समय घुमाने के लिए टाइमर घटक का उपयोग कर रहा हूं।

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 फ़्रेमवर्क 3.0, नवीनतम DirectX रनटाइम और Microsoft XNA फ़्रेमवर्क पुनर्वितरण योग्य 2.0 की आवश्यकता होती है। इसके अलावा, हार्डवेयर आवश्यकता के रूप में, "एक ग्राफिक्स कार्ड जो पिक्सेल शेडर 1.1 या उच्चतर का समर्थन करता है" की आवश्यकता होती है।

इसके अलावा, परियोजना "विजुअल स्टूडियो 2008 व्यावसायिक संस्करण" में बनाई गई थी। Visual Studio 2008 के लिए एक वातावरण तैयार करें।