XNA:n käyttäminen WPF-sovelluksissa

Sivu päivitetty :
Sivun luontipäivämäärä :

yhteenveto

Tässä artikkelissa kuvataan, miten XNA Frameworkia käytetään WPF-sovelluksissa.

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

Toimintaympäristö

Edellytykset

Tuetut XNA-versiot
  • 2.0
  • 3.0
Tuetut alustat
  • Windows (XP SP2 tai uudempi, Vista)
Windowsin vaatima Vertex Shader -versio 1.1
Windowsin vaatima Pixel Shader -versio 1.1

Toimintaympäristö

lava

aine

Jos haluat hahmontaa tietyn ohjausobjektin DirectX:n avulla, sinun on hankittava kyseisen ohjausobjektin ikkunan kahva. Toisin kuin Windows Form -ohjausobjekteissa, WPF-ohjausobjekteissa ei kuitenkaan ole ikkunakahvoja (WPF:ssä ne yksinkertaisesti "piirtävät" ohjausobjektin).

WPF sisältää kuitenkin WindowsFormsHost-nimisen ohjausobjektin, jonka avulla voit käyttää Windows Forms -ohjausobjekteja.

Tässä artikkelissa luomme näytteen monikulmion piirtämisestä, kun sitä pyöritetään yllä olevan kuvan mukaisesti, mutta jätän pois itse XNA: n yksityiskohdat, koska sen selittäminen olisi liian pitkä. Puhun vain WPF: n ja XNA: n välisestä suhteesta.

Avaa ensin WPF-ikkuna (tässä tapauksessa Window1.xaml) ja aseta WindowsFormHost-ohjausobjekti työkaluriviltä. Oikealla oleva liukusäädin on bonus.

WPF ウインドウデザイン

Minun on todella tehtävä hieman enemmän työtä XAML: n kanssa, mutta jätän sen myöhemmäksi, koska minun on ensin luotava ohjaimet XNA: n käyttämiseksi.

Lisää "Windows Forms" "Mukautettu ohjausobjekti" projektiisi. Jätä nimi GraphicsDeviceControl.

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

Älä unohda lisätä Microsoft.Xna.Framework-viittausta etukäteen. On myös "Microsoft.Xna.Framework.Game", mutta sitä käytetään vain peliprojektissa, joten sitä ei tarvitse sisällyttää.

Managed DirectX の参照

Jotta mallikoodi pysyisi lyhyenä, kaikista XNA:han liittyvistä ohjelmista on yhteenveto GraphicsDeviceControl.cs. Se ei ole kovin monipuolinen kirjoitustyyli, joten käytä sitä ja kirjoita se uudelleen.

GraphicsDeviceControl-ohjausobjektin koko koodi näkyy alla (suunnittelijaosaa lukuun ottamatta). Jos olet koskaan käyttänyt XNA:ta, tiedät, että se ei tee mitään epätavallista. Käytän ajastinkomponenttia, jotta monikulmio näyttää pyörivän koko ajan.

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

Nyt kun olet luonut ohjausobjektin, katsotaanpa XAML-koodia. Koska aiomme sijoittaa luomamme ohjausobjektin, lisäämme juuritunnisteeseen nimiavaruuden. Tässä se määritellään nimellä "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>

Laajenna seuraavaksi juuri lisäämäsi WindowsFormsHost-ohjausobjektin tunniste ja lisää GraphicsDeviceControl alla esitetyllä tavalla.

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

Sinulla ei tarvitse olla "x:Name", mutta malli käyttää sitä kärkipistetietojen käyttämiseen liukusäätimellä.

Jos teet tämän, voit suorittaa WPF:ssä kohtauksen, jossa monikulmiot piirretään pyörivällä monikulmiolla näytteen osoittamalla tavalla. Pääsy liukusäätimellä on bonus, joten lataa näytetiedot ja tarkista ne.

Ohjelma vaatii .NET Framework 3.0:n, uusimman DirectX runtimen ja Microsoft XNA Framework Redistributable 2.0:n. Lisäksi laitteistovaatimuksena tarvitaan "näytönohjain, joka tukee Pixel Shader 1.1:tä tai uudempaa".

Lisäksi projekti luotiin "Visual Studio 2008 Professional Edition" -versiossa. Valmistele ympäristö Visual Studio 2008:aa varten.