Používanie XNA v aplikáciách WPF
súhrn
Popisuje, ako používať XNA Framework v aplikáciách WPF.
Prevádzkové prostredie
Predpoklady
Podporované verzie XNA |
|
Podporované platformy |
|
Windows vyžaduje verziu tieňovača vrcholov | 1.1 |
Windows vyžaduje verziu Pixel Shader | 1.1 |
Prevádzkové prostredie
nástupište |
látka
Ak chcete prekresliť na konkrétnom ovládacom prvku pomocou rozhrania DirectX, musíte získať rukoväť okna pre tento ovládací prvok. Na rozdiel od ovládacích prvkov Windows Form však ovládacie prvky WPF nemajú úchyty okien (vo WPF jednoducho "nakreslia" ovládací prvok).
WPF však poskytuje ovládací prvok s názvom "WindowsFormsHost", ktorý umožňuje používať ovládacie prvky Windows Forms.
V tomto článku vytvoríme ukážku kreslenia mnohouholníka pri jeho otáčaní, ako je znázornené vyššie, ale vynechám detaily samotného XNA, pretože by to bolo príliš dlhé na jeho vysvetlenie. Budem hovoriť len o vzťahu medzi WPF a XNA.
Najprv otvorte okno WPF (v tomto prípade Window1.xaml) a umiestnite ovládací prvok WindowsFormHost z panela s nástrojmi. Posúvač vpravo je bonus.
Naozaj potrebujem urobiť trochu viac práce na XAML, ale nechám to na neskôr, pretože najprv musím vytvoriť ovládacie prvky, aby som mohol používať XNA.
Pridajte do projektu "Windows Forms" "Custom Control". Ponechajte názov GraphicsDeviceControl.
Nezabudnite vopred pridať odkaz "Microsoft.Xna.Framework". K dispozícii je aj "Microsoft.Xna.Framework.Game", ale ten sa používa iba v hernom projekte, takže ho nie je potrebné zahrnúť.
Aby bol vzorový kód krátky, všetky programy súvisiace s XNA sú zhrnuté v GraphicsDeviceControl.cs. Nie je to veľmi všestranný štýl písania, preto ho použite a prepíšte.
Úplný kód pre GraphicsDeviceControl je uvedený nižšie (okrem dizajnérskej časti). Ak ste niekedy používali XNA, budete vedieť, že nerobí nič nezvyčajné. Používam komponent Timer, aby sa mnohouholník neustále otáčal.
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();
}
}
}
Teraz, keď ste vytvorili ovládací prvok, pozrime sa na kód XAML. Keďže sa chystáme umiestniť ovládací prvok, ktorý sme vytvorili, pridáme do koreňovej značky menný priestor. Tu je definovaný ako "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>
Potom rozbaľte značku ovládacieho prvku WindowsFormsHost, ktorý ste práve umiestnili, a pridajte GraphicsDeviceControl, ako je znázornené nižšie.
<my:WindowsFormsHost Name="windowsFormsHostManagedDirectX" Width="300" Height="300"
HorizontalAlignment="Left" VerticalAlignment="Top">
<xw:GraphicsDeviceControl x:Name="GraphicsDeviceControl" />
</my:WindowsFormsHost>
Nemusíte mať "x:Name", ale ukážka ho používa na prístup k údajom vrcholov pomocou jazdca.
Ak to urobíte, môžete spustiť scénu na WPF, kde sú mnohouholníky nakreslené rotujúcim mnohouholníkom, ako je znázornené v ukážke. Prístup pomocou posúvača je bonus, preto si stiahnite vzorové údaje a skontrolujte ich.
Program vyžaduje rozhranie .NET Framework 3.0, najnovší modul runtime DirectX a Microsoft XNA Framework Redistributable 2.0. Okrem toho sa ako hardvérová požiadavka vyžaduje "grafická karta, ktorá podporuje Pixel Shader 1.1 alebo vyšší".
Okrem toho bol projekt vytvorený v "Visual Studio 2008 Professional Edition". Príprava prostredia pre Visual Studio 2008.