XNA:n käyttäminen WPF-sovelluksissa
yhteenveto
Tässä artikkelissa kuvataan, miten XNA Frameworkia käytetään WPF-sovelluksissa.
Toimintaympäristö
Edellytykset
Tuetut XNA-versiot |
|
Tuetut alustat |
|
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.
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.
Ä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ää.
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 x:Class="ManagedDirectXOnWPF.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPFウインドウ上でManaged DirectXを使用してポリゴン描画"
Height="338" Width="422"
xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:xw="clr-namespace:ManagedDirectXOnWPF">
<!-- 省略 -->
</Window>
Laajenna seuraavaksi juuri lisäämäsi WindowsFormsHost-ohjausobjektin tunniste ja lisää GraphicsDeviceControl alla esitetyllä tavalla.
<my:WindowsFormsHost Name="windowsFormsHostManagedDirectX" Width="300" Height="300"
HorizontalAlignment="Left" VerticalAlignment="Top">
<xw:GraphicsDeviceControl x:Name="GraphicsDeviceControl" />
</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.