XNA nézet megjelenítése közvetlenül WPF ablakban

Oldal frissítve :
Oldal létrehozásának dátuma :

összefoglalás

Ismerteti, hogyan lehet közvetlenül megjeleníteni egy WPF ablakban az XNA segítségével.

WPF ウインドウ上に直接 XNA のビューを表示する

Működési környezet

Előfeltételek

Támogatott XNA verziók
  • 2.0
  • 3.0
Támogatott platformok
  • Windows (XP SP2 vagy újabb, Vista)
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

Az XNA használata WPF alkalmazásokban című részben a WindowsFormsHost vezérlőt használtam a nézet megjelenítéséhez, de most csak a WPF ablakot szeretném használni a sokszög megjelenítéséhez. Az "XNA használata WPF alkalmazásokban" egy kicsit reprezentáció, ezért elmagyarázom a különbségeket.

Névtéraliasok

// 名前空間エイリアス
using Xna = Microsoft.Xna.Framework;
using XnaGraphics = Microsoft.Xna.Framework.Graphics;

Mivel a szín- és mátrixstruktúrákat az XNA-keretrendszer és a WPF-névterek fedik le, a használathoz meg kell adnia a struktúra nevét a névtérből. Úgy tűnik azonban, hogy minden alkalommal hosszú, ezért létrehozok egy névtér-aliast. A "Microsoft.Xna.Framework.Rectangle" például mostantól "Xna.Rectangle" néven is megadható.

időzítő

NET-keretrendszer 3.0-s verziója óta elérhető a "System.Windows.Threading.DispatcherTimer" nevű időzítőosztály, amely minden képkocka megjelenítésére szolgál. A WPF egy DispatcherTimer használatával teszi lehetővé a feldolgozást ugyanazon a szálon, mint a felhasználói felület.

/// <summary>
/// タイマー
/// </summary>
private DispatcherTimer timer = null;

mezőt, amely egy DispatcherTimer deklarálására szolgál.

/// <summary>
/// タイマーイベント
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
    this.Draw();
}

Meghatároz egy metódust, amelyet a DispatcherTimer rendszeres időközönként meghív.

// タイマー
this.timer = new DispatcherTimer();
this.timer.Tick += new EventHandler(dispatcherTimer_Tick);
this.timer.Interval = new TimeSpan(0, 0, 0, 0, 16);
this.timer.Start();

Ez az időzítő beállításának folyamata. Miután létrehozta a DispatcherTimer egy példányát, és beállította a metódust a hívásra és az időintervallumra, a DispatcherTimer.Start metódus elindítja az időzítőt.

Ablakfogantyú beszerzése

Direct3D-eszköz létrehozásához szükség van egy ablakfogópontra. A WPF azonban nem rendelkezik az ablakfogantyú fogalmával, így nincs mód arra, hogy közvetlenül a Window osztályból szerezze be.

Mivel azonban vannak olyan esetek, amikor szükség van egy ablakfogóra, mint ebben az esetben, az ablakfogantyú a "System.Windows.Interop.WindowInteropHelper" osztályon keresztül érhető el a Win32 kód együttműködéseként. (ez a Window osztály)

// ウィンドウハンドルを取得する
IntPtr handle = new WindowInteropHelper(this).Handle;

Ezt a leírót használja Direct3D-eszköz létrehozásakor. Ha azonban megpróbálja lekérni az ablakleírót az OnInitialized metódusban, akkor 0 értéket ad vissza, valószínűleg azért, mert az ablak még nincs létrehozva. Ebben a példában az eszköz az OnSourceInitialized metódusban jön létre.

Renderelés a megadott területre

A célterületet megadhatja a GraphicsDevice.Present második argumentumaként. A mintában megpróbálom eltolásként a pozícióba (50, 50) rajzolni. A méret megegyezik a backbuffer méretével (300, 300). Az első argumentum az a terület, ahonnan rajzolni kell, és ha null értéket ad meg, akkor a program az eredeti puffert használja.

// 描画先を指定する
Xna.Rectangle rect = new Xna.Rectangle(
    50, 50,
    (int)this.viewSize.Width, (int)this.viewSize.Height);

this.device.Present(null, rect, this.windowHandle);

Egy eszköz megsemmisítése

Megsemmisíti a készüléket, amikor bezárja az ablakot. Eredetileg a Dispose metódussal szerettem volna kezelni, de mivel a WPF Window osztály alapértelmezés szerint nem örökli az IDisposable-t, inkább ide írtam.

/// <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);
}

kivégzés

Ha futtatja a mintaprogramot, futtathatja a cikk elején láthatóhoz hasonló képernyőképpel.

Első pillantásra jól jelenik meg, de amikor az egérrel húzva átméretezem az ablakot, a nézet villog vagy eltűnik az átméretezés során. Úgy tűnik, hogy ütközik a WPF rendereléssel, és sok mindent kipróbáltam, de nem tudtam megoldani.

Ha XNA-t használ, biztonságosabbnak tűnik a WindowsFormsHost vezérlő használata.

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.