Az XNA használata WPF alkalmazásokban
összefoglalás
Ismerteti az XNA keretrendszer használatát WPF alkalmazásokban.
Működési környezet
Előfeltételek
Támogatott XNA verziók |
|
Támogatott platformok |
|
Windows Szükséges Vertex Shader verzió | 1.1 |
Windows Szükséges Pixel Shader verzió | 1.1 |
Működési környezet
peron |
lényeg
Ha egy adott vezérlőn a DirectX használatával szeretne renderelni, be kell szereznie a vezérlő ablakfogóját. A Windows űrlapvezérlőivel ellentétben azonban a WPF vezérlők nem rendelkeznek ablakfogókkal (a WPF-ben egyszerűen "rajzolják" a vezérlőt).
A WPF azonban tartalmaz egy "WindowsFormsHost" nevű vezérlőt, amely lehetővé teszi a Windows Forms-vezérlők használatát.
Ebben a cikkben létrehozunk egy mintát egy sokszög rajzolására, ahogy a fentiek szerint elforgatják, de kihagyom magának az XNA-nak a részleteit, mert túl hosszú lenne elmagyarázni. Csak a WPF és az XNA kapcsolatáról fogok beszélni.
Először nyisson meg egy WPF-ablakot (ebben az esetben Window1.xaml), és helyezzen el egy WindowsFormHost vezérlőt az eszköztáron. A jobb oldali csúszka bónusz.
Tényleg egy kicsit többet kell dolgoznom az XAML-en, de későbbre hagyom, mert először létre kell hoznom az XNA használatához szükséges vezérlőket.
Adjon hozzá egy "Windows Forms" "Egyéni vezérlőt" a projekthez. Hagyja meg a GraphicsDeviceControl nevet.
Ne felejtse el előzetesen hozzáadni a "Microsoft.Xna.Framework" hivatkozást. Van még "Microsoft.Xna.Framework.Game" is, de ezt csak játékprojektben használják, így nincs szükség rá.
A mintakód rövidsége érdekében az összes XNA-val kapcsolatos programot GraphicsDeviceControl.cs összegezzük. Ez nem túl sokoldalú írási stílus, ezért kérjük, alkalmazza és írja át.
A GraphicsDeviceControl teljes kódja az alábbiakban látható (kivéve a tervező részt). Ha valaha is használta az XNA-t, akkor tudni fogja, hogy nem csinál semmi rendkívülit. Időzítő komponenst használok, hogy a sokszög folyamatosan forogjon.
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();
}
}
}
Most, hogy létrehozta a vezérlőt, nézzük meg az XAML-kódot. Mivel az általunk létrehozott vezérlőt helyezzük el, hozzáadunk egy névteret a gyökércímkéhez. Itt "xw" -ként definiálják.
<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>
Ezután bontsa ki az imént elhelyezett WindowsFormsHost vezérlő címkéjét, és adjon hozzá egy GraphicsDeviceControl vezérlőt az alább látható módon.
<my:WindowsFormsHost Name="windowsFormsHostManagedDirectX" Width="300" Height="300"
HorizontalAlignment="Left" VerticalAlignment="Top">
<xw:GraphicsDeviceControl x:Name="GraphicsDeviceControl" />
</my:WindowsFormsHost>
Nem kell "x:Name" értékkel rendelkeznie, de a minta ezt használja a csúcspontadatok csúszkával való eléréséhez.
Ha ezt teszi, futtathat egy jelenetet WPF-en, ahol a sokszögek forgó sokszöggel vannak rajzolva, ahogy a mintában látható. A csúszkával való hozzáférés bónusz, ezért kérjük, töltse le a mintaadatokat és ellenőrizze azokat.
A programhoz szükség van a .NET-keretrendszer 3.0-s verziójára, a legújabb DirectX futtatókörnyezetre és a Microsoft XNA Framework Redistributable 2.0-ra. Ezenkívül hardverkövetelményként "a Pixel Shader 1.1-es vagy újabb verzióját támogató grafikus kártya" szükséges.
Ezenkívül a projektet a "Visual Studio 2008 Professional Edition" -ben hozták létre. Környezet előkészítése a Visual Studio 2008 alkalmazáshoz.