Wyświetlanie widoku XNA bezpośrednio w oknie WPF
streszczenie
Opisuje sposób renderowania bezpośrednio w oknie WPF za pomocą XNA.
Środowisko pracy
Warunki wstępne
Obsługiwane wersje XNA |
|
Obsługiwane platformy |
|
Wymagana wersja cieniowania wierzchołków systemu Windows | 1.1 |
Wymagana wersja Pixel Shader w systemie Windows | 1.1 |
Środowisko pracy
podest |
substancja
W temacie Korzystanie z XNA w aplikacjach WPF użyłem kontrolki WindowsFormsHost do wyświetlenia widoku, ale teraz chcę użyć tylko okna WPF do wyświetlenia wielokąta. "Używanie XNA w aplikacjach WPF" to trochę reprezentacja, więc wyjaśnię różnice.
Aliasy przestrzeni nazw
// 名前空間エイリアス
using Xna = Microsoft.Xna.Framework;
using XnaGraphics = Microsoft.Xna.Framework.Graphics;
Ponieważ struktury Color i Matrix są objęte przestrzeniami nazw XNA Framework i WPF, należy określić nazwę struktury z przestrzeni nazw, aby można było z niej korzystać. Jednak za każdym razem wydaje się, że jest długi, więc tworzę alias przestrzeni nazw. Na przykład "Microsoft.Xna.Framework.Rectangle" można teraz określić jako "Xna.Rectangle".
minutnik
Od czasu .NET Framework 3.0 dostępna jest klasa czasomierza o nazwie "System.Windows.Threading.DispatcherTimer", która jest używana do renderowania każdej klatki. WPF używa DispatcherTimer, aby umożliwić przetwarzanie w tym samym wątku co interfejs użytkownika.
<summary>
タイマー
</summary>
private DispatcherTimer timer = null;
, deklarując DispatcherTimer.
<summary>
タイマーイベント
</summary>
<param name="sender"></param>
<param name="e"></param>
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
this.Draw();
}
Definiuje metodę, którą DispatcherTimer wywołuje w regularnych odstępach czasu.
// タイマー
this.timer = new DispatcherTimer();
this.timer.Tick += new EventHandler(dispatcherTimer_Tick);
this.timer.Interval = new TimeSpan(0, 0, 0, 0, 16);
this.timer.Start();
To jest proces ustawiania timera. Po utworzeniu instancji klasy DispatcherTimer i ustawieniu metody do wywołania oraz interwału czasu metoda DispatcherTimer.Start uruchamia czasomierz.
Uzyskanie klamki okiennej
Aby utworzyć urządzenie Direct3D, potrzebny jest uchwyt okna. Jednak WPF nie ma koncepcji uchwytu okna, więc nie ma sposobu, aby pobrać go bezpośrednio z klasy Window.
Jednak ze względu na to, że istnieją sytuacje, w których wymagany jest uchwyt okna, tak jak w tym przypadku, uchwyt okna można uzyskać za pośrednictwem klasy "System.Windows.Interop.WindowInteropHelper" jako międzyoperacyjność dla kodu Win32. (jest to klasa Window)
// ウィンドウハンドルを取得する
IntPtr handle = new WindowInteropHelper(this).Handle;
Użyj tego uchwytu podczas tworzenia urządzenia Direct3D. Jeśli jednak spróbujesz uzyskać uchwyt okna w metodzie OnInitialized, zwróci wartość 0, prawdopodobnie dlatego, że okno nie zostało jeszcze utworzone. W tym przykładzie urządzenie jest tworzone w metodzie OnSourceInitialized.
Renderowanie do określonego obszaru
Obszar docelowy można określić jako drugi argument klasy GraphicsDevice.Present. W próbce staram się narysować go w pozycji (50, 50) jako przesunięcie. Rozmiar jest taki sam jak rozmiar bufora wstecznego (300, 300). Pierwszym argumentem jest obszar, z którego ma być rysowany, a jeśli określono wartość null, używany jest oryginalny bufor.
// 描画先を指定する
Xna.Rectangle rect = new Xna.Rectangle(
50, 50,
(int)this.viewSize.Width, (int)this.viewSize.Height);
this.device.Present(null, rect, this.windowHandle);
Niszczenie urządzenia
Zamykając okno, niszczysz swoje urządzenie. Pierwotnie chciałem sobie z tym poradzić za pomocą metody Dispose, ale ponieważ klasa WPF Window domyślnie nie dziedziczy IDisposable, napisałem to tutaj.
<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);
}
egzekucja
Jeśli uruchomisz przykładowy program, możesz uruchomić go z obrazem ekranu, takim jak ten na początku artykułu.
Na pierwszy rzut oka renderuje się dobrze, ale kiedy zmieniam rozmiar okna, przeciągając je myszą, widok migocze lub znika podczas zmiany rozmiaru. Wygląda na to, że jest w konflikcie z renderowaniem WPF i próbowałem wielu rzeczy, ale nie mogłem tego rozwiązać.
Jeśli używasz XNA, bezpieczniej jest użyć kontrolki WindowsFormsHost.
Program wymaga .NET Framework 3.0, najnowszego środowiska uruchomieniowego DirectX oraz pakietu redystrybucyjnego Microsoft XNA Framework 2.0. Ponadto jako wymóg sprzętowy wymagana jest "karta graficzna obsługująca Pixel Shader 1.1 lub nowszy".
Dodatkowo projekt powstał w programie "Visual Studio 2008 Professional Edition". Przygotowanie środowiska dla programu Visual Studio 2008.