Hiển thị chế độ xem XNA trực tiếp trên cửa sổ WPF
tóm tắt
Mô tả cách hiển thị trực tiếp trong cửa sổ WPF với XNA.
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
Trong Sử dụng XNA trong các ứng dụng WPF, tôi đã sử dụng điều khiển WindowsFormsHost để hiển thị chế độ xem, nhưng bây giờ tôi chỉ muốn sử dụng cửa sổ WPF để hiển thị đa giác. "Sử dụng XNA trong các ứng dụng WPF" là một chút đại diện, vì vậy tôi sẽ giải thích sự khác biệt.
Bí danh không gian tên
// 名前空間エイリアス
using Xna = Microsoft.Xna.Framework;
using XnaGraphics = Microsoft.Xna.Framework.Graphics;
Vì cấu trúc Color và Matrix được bao phủ bởi không gian tên XNA Framework và WPF, bạn phải chỉ định tên của cấu trúc từ không gian tên để sử dụng nó. Tuy nhiên, có vẻ như nó luôn dài, vì vậy tôi đang tạo một bí danh không gian tên. Ví dụ: "Microsoft.Xna.Framework.Rectangle" hiện có thể được chỉ định là "Xna.Rectangle".
Timer
Kể từ .NET Framework 3.0, một lớp hẹn giờ có tên là "System.Windows.Threading.DispatcherTimer" đã có sẵn và lớp hẹn giờ này được sử dụng để hiển thị mọi khung hình. WPF sử dụng DispatcherTimer để cho phép xử lý trên cùng một luồng với giao diện người dùng.
<summary>
タイマー
</summary>
private DispatcherTimer timer = null;
, khai báo DispatcherTimer.
<summary>
タイマーイベント
</summary>
<param name="sender"></param>
<param name="e"></param>
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
this.Draw();
}
Xác định một phương thức mà DispatcherTimer gọi đều đặn.
// タイマー
this.timer = new DispatcherTimer();
this.timer.Tick += new EventHandler(dispatcherTimer_Tick);
this.timer.Interval = new TimeSpan(0, 0, 0, 0, 16);
this.timer.Start();
Đây là quá trình cài đặt hẹn giờ. Sau khi tạo một thực thể của DispatcherTimer và đặt phương thức để gọi và khoảng thời gian, phương thức DispatcherTimer.Start bắt đầu bộ hẹn giờ.
Lấy một tay cầm cửa sổ
Để tạo thiết bị Direct3D, bạn cần có một tay cầm cửa sổ. Tuy nhiên, WPF không có khái niệm về một tay cầm cửa sổ, vì vậy không có cách nào để lấy nó trực tiếp từ lớp Window.
Tuy nhiên, vì có những lúc cần có một tay cầm cửa sổ, như trong trường hợp này, có thể lấy bộ điều khiển cửa sổ thông qua lớp "System.Windows.Interop.WindowInteropHelper" như một interop cho mã Win32. (đây là lớp Window)
// ウィンドウハンドルを取得する
IntPtr handle = new WindowInteropHelper(this).Handle;
Sử dụng tay cầm này khi tạo thiết bị Direct3D. Tuy nhiên, nếu bạn cố gắng lấy tay cầm cửa sổ trong phương thức OnInitialized, nó sẽ trả về 0, có thể là do cửa sổ chưa được tạo. Trong mẫu này, thiết bị được tạo theo phương thức OnSourceInitialized.
Kết xuất đến khu vực được chỉ định
Bạn có thể chỉ định khu vực đích làm đối số thứ hai của GraphicsDevice.Present. Trong mẫu, tôi cố gắng vẽ nó ở vị trí (50, 50) như một độ lệch. Kích thước giống với kích thước của bộ đệm ngược (300, 300). Đối số đầu tiên là khu vực cần vẽ, và nếu null được chỉ định, bộ đệm ban đầu được sử dụng.
// 描画先を指定する
Xna.Rectangle rect = new Xna.Rectangle(
50, 50,
(int)this.viewSize.Width, (int)this.viewSize.Height);
this.device.Present(null, rect, this.windowHandle);
Phá hủy thiết bị
Bạn đang phá hủy thiết bị của mình khi đóng cửa sổ. Ban đầu, tôi muốn xử lý nó bằng phương thức Dispose, nhưng vì lớp WPF Window không kế thừa IDisposable theo mặc định, tôi đã viết nó ở đây thay thế.
<summary>
ウインドウが閉じたとき
</summary>
<param name="e"></param>
protected override void OnClosed(EventArgs e)
{
if (this.device != null)
{
this.device.Dispose();
this.device = null;
}
base.OnClosed(e);
}
Thực hiện
Nếu bạn chạy chương trình mẫu, bạn có thể chạy nó với hình ảnh màn hình như ở đầu bài viết.
Thoạt nhìn, nó hiển thị tốt, nhưng khi tôi thay đổi kích thước cửa sổ bằng cách kéo nó bằng chuột, chế độ xem nhấp nháy hoặc biến mất trong quá trình thay đổi kích thước. Nó có vẻ mâu thuẫn với kết xuất WPF, và tôi đã thử rất nhiều thứ nhưng không thể giải quyết được.
Nếu bạn đang sử dụng XNA, có vẻ an toàn hơn khi sử dụng điều khiển WindowsFormsHost.
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.