Sử dụng XNA trong các ứng dụng WPF
tóm tắt
Mô tả cách sử dụng XNA Framework trong các ứng dụng WPF.
Môi trường hoạt động
Điều kiện tiên quyết
Các phiên bản XNA được hỗ trợ |
|
Nền tảng được hỗ trợ |
|
Phiên bản Vertex Shader yêu cầu của Windows | 1.1 |
Phiên bản Pixel Shader yêu cầu của Windows | 1.1 |
Môi trường hoạt động
nền tảng |
chất
Để hiển thị trên một điều khiển cụ thể bằng DirectX, bạn cần lấy tay cầm cửa sổ cho điều khiển đó. Tuy nhiên, không giống như các điều khiển Windows Form, các điều khiển WPF không có các điều khiển cửa sổ (trong WPF, chúng chỉ đơn giản là "vẽ" điều khiển).
Tuy nhiên, WPF cung cấp một điều khiển được gọi là "WindowsFormsHost" cho phép bạn sử dụng các điều khiển Windows Forms.
Trong bài viết này, chúng ta sẽ tạo một mẫu vẽ một đa giác khi nó được xoay như hình trên, nhưng tôi sẽ bỏ qua các chi tiết của bản thân XNA vì nó sẽ quá dài để giải thích nó. Tôi sẽ chỉ nói về mối quan hệ giữa WPF và XNA.
Đầu tiên, mở một cửa sổ WPF (trong trường hợp này là Window1.xaml) và đặt một điều khiển WindowsFormHost từ thanh công cụ. Thanh trượt ở bên phải là một phần thưởng.
Tôi thực sự cần phải làm thêm một chút công việc trên XAML, nhưng tôi sẽ để nó sau này vì tôi phải tạo các điều khiển để sử dụng XNA trước.
Thêm "Windows Forms" "Custom Control" vào dự án của bạn. Để lại tên GraphicsDeviceControl.
Đừng quên thêm tham chiếu "Microsoft.Xna.Framework" trước. Ngoài ra còn có "Microsoft.Xna.Framework.Game", nhưng điều này được sử dụng trong một dự án chỉ dành cho trò chơi, vì vậy không cần phải bao gồm nó.
Để giữ cho mã mẫu ngắn gọn, tất cả các chương trình liên quan đến XNA đều được tóm tắt trong GraphicsDeviceControl.cs. Nó không phải là một phong cách viết rất linh hoạt, vì vậy hãy áp dụng nó và viết lại.
Mã đầy đủ cho GraphicsDeviceControl được hiển thị bên dưới (ngoại trừ phần thiết kế). Nếu bạn đã từng sử dụng XNA, bạn sẽ biết rằng nó không làm bất cứ điều gì khác thường. Tôi đang sử dụng một thành phần Timer để làm cho đa giác dường như xoay mọi lúc.
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();
}
}
}
Bây giờ bạn đã tạo điều khiển, hãy xem xét XAML. Vì chúng ta sẽ đặt điều khiển mà chúng ta đã tạo, chúng ta sẽ thêm một không gian tên vào thẻ gốc. Ở đây, nó được định nghĩa là "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>
Tiếp theo, mở rộng thẻ cho điều khiển WindowsFormsHost mà bạn vừa đặt và thêm GraphicsDeviceControl, như được hiển thị bên dưới.
<my:WindowsFormsHost Name="windowsFormsHostManagedDirectX" Width="300" Height="300"
HorizontalAlignment="Left" VerticalAlignment="Top">
<xw:GraphicsDeviceControl x:Name="GraphicsDeviceControl" />
</my:WindowsFormsHost>
Bạn không cần phải có "x:Name", nhưng mẫu sử dụng nó để truy cập dữ liệu đỉnh bằng thanh trượt.
Nếu bạn làm điều này, bạn có thể chạy một cảnh trên WPF trong đó các đa giác được vẽ với một đa giác xoay, như được hiển thị trong mẫu. Truy cập bằng thanh trượt là một phần thưởng, vì vậy vui lòng tải xuống dữ liệu mẫu và kiểm tra nó.
Chương trình yêu cầu .NET Framework 3.0, thời gian chạy DirectX mới nhất và Microsoft XNA Framework Redistributable 2.0. Ngoài ra, như một yêu cầu phần cứng, "card đồ họa hỗ trợ Pixel Shader 1.1 trở lên" là bắt buộc.
Ngoài ra, dự án được tạo ra trong "Visual Studio 2008 Professional Edition". Chuẩn bị môi trường cho Visual Studio 2008.