Uporaba XNA v aplikacijah WPF
Povzetek
Opisuje, kako uporabljati ogrodje XNA v aplikacijah WPF.
Delovno okolje
Predpogoji
Podprte različice XNA |
|
Podprte platforme |
|
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.
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.
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.
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 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>
Nato razširite oznako za kontrolnik WindowsFormsHost, ki ste ga pravkar postavili, in dodajte GraphicsDeviceControl, kot je prikazano spodaj.
<my:WindowsFormsHost Name="windowsFormsHostManagedDirectX" Width="300" Height="300"
HorizontalAlignment="Left" VerticalAlignment="Top">
<xw:GraphicsDeviceControl x:Name="GraphicsDeviceControl" />
</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.