Uporaba XNA v aplikacijah WPF

Stran posodobljena :
Datum ustvarjanja strani :

Povzetek

Opisuje, kako uporabljati ogrodje XNA v aplikacijah WPF.

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

Delovno okolje

Predpogoji

Podprte različice XNA
  • 2.0
  • 3.0
Podprte platforme
  • Windows (XP s servisnim paketom SP2 ali novejši, Vista)
Zahtevana različica brilnika točk v sistemu Windows 1.1
Windows je zahteval različico Pixel Shader 1.1

Delovno okolje

peron

snov

Če želite upodobiti določen kontrolnik z DirectX, morate pridobiti ročico okna za ta kontrolnik. Vendar pa za razliko od kontrolnikov Windows Form kontrolniki WPF nimajo okenskih ročic (v WPF preprosto »narišejo« kontrolnik).

Vendar pa WPF ponuja kontrolnik, imenovan »WindowsFormsHost«, ki vam omogoča uporabo kontrolnikov Windows Forms.

V tem članku bomo ustvarili vzorec risbe poligona, ko se vrti, kot je prikazano zgoraj, vendar bom izpustil podrobnosti o samem XNA, ker bi bilo predolgo, da bi ga razložili. Govoril bom samo o odnosu med WPF in XNA.

Najprej odprite okno WPF (v tem primeru Window1.xaml) in v orodni vrstici postavite kontrolnik WindowsFormHost. Drsnik na desni je bonus.

WPF ウインドウデザイン

Res moram narediti malo več dela na XAML-u, vendar ga bom pustil za pozneje, ker moram najprej ustvariti kontrolnike za uporabo XNA.

V projekt dodajte »Windows Forms« »Custom Control«. Pustite ime GraphicsDeviceControl.

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

Ne pozabite vnaprej dodati sklica »Microsoft.Xna.Framework«. Obstaja tudi »Microsoft.Xna.Framework.Game«, vendar se to uporablja v projektu samo za igro, zato ga ni treba vključiti.

Managed DirectX の参照

Da bi bila vzorčna koda kratka, so vsi programi, povezani z XNA, povzeti v GraphicsDeviceControl.cs. To ni zelo vsestranski slog pisanja, zato ga uporabite in ponovno napišite.

Celotna koda za GraphicsDeviceControl je prikazana spodaj (razen oblikovalskega dela). Če ste kdaj uporabljali XNA, boste vedeli, da ne naredi nič nenavadnega. Uporabljam komponento časovnika, da se zdi, da se mnogokotnik ves čas vrti.

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();
        }
    }
}

Zdaj, ko ste ustvarili kontrolnik, si poglejmo XAML. Ker bomo postavili kontrolnik, ki smo ga ustvarili, bomo korenski oznaki dodali imenski prostor. Tukaj je opredeljen kot "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>

Nato razširite oznako za kontrolnik WindowsFormsHost, ki ste ga pravkar postavili, in dodajte GraphicsDeviceControl, kot je prikazano spodaj.

<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>

Ni vam treba imeti »x:Name«, vendar ga vzorec uporablja za dostop do podatkov o točkah z drsnikom.

Če to storite, lahko zaženete prizor na WPF, kjer so mnogokotniki narisani z vrtljivim mnogokotnikom, kot je prikazano v vzorcu. Dostop z drsnikom je bonus, zato prosimo, da prenesete vzorčne podatke in jih preverite.

Program zahteva ogrodje .NET Framework 3.0, najnovejši izvajalnik DirectX in Microsoft XNA Framework Redistributable 2.0. Poleg tega je kot strojna zahteva potrebna »grafična kartica, ki podpira Pixel Shader 1.1 ali novejšo različico«.

Poleg tega je bil projekt ustvarjen v "Visual Studio 2008 Professional Edition". Pripravite okolje za Visual Studio 2008.