Bagikan melalui


Memperluas permainan sampel

Catatan

Topik ini adalah bagian dari membuat permainan Platform Windows Universal sederhana (UWP) dengan seri tutorial DirectX. Topik di tautan tersebut mengatur konteks untuk seri.

Untuk mengunduh versi game ini yang menggunakan XAML untuk overlay, lihat Sampel game DirectX dan XAML. Pastikan untuk membaca file readme di sana untuk detail tentang membuat sampel.

Pada titik ini kita telah membahas komponen utama dari game DirectX 3D dasar Platform Windows Universal (UWP). Anda dapat mengatur kerangka kerja untuk game, termasuk penyedia tampilan dan alur penyajian, dan menerapkan perulangan game dasar. Anda juga dapat membuat overlay antarmuka pengguna dasar, menggabungkan suara, dan mengimplementasikan kontrol. Anda sedang dalam perjalanan untuk membuat permainan Anda sendiri, tetapi jika Anda membutuhkan lebih banyak bantuan dan info, lihat sumber daya ini.

Menggunakan XAML untuk overlay

Salah satu alternatif yang tidak kami bahas secara mendalam adalah penggunaan XAML alih-alih Direct2D untuk overlay. XAML memiliki banyak manfaat daripada Direct2D untuk menggambar elemen antarmuka pengguna. Manfaat yang paling penting adalah membuat menggabungkan tampilan dan nuansa Windows 10 ke dalam game DirectX Anda lebih nyaman. Banyak elemen, gaya, dan perilaku umum yang menentukan aplikasi UWP terintegrasi erat ke dalam model XAML, membuatnya jauh lebih sedikit pekerjaan bagi pengembang game untuk diterapkan. Jika desain game Anda sendiri memiliki antarmuka pengguna yang rumit, pertimbangkan untuk menggunakan XAML alih-alih Direct2D.

Dengan XAML, kita dapat membuat antarmuka game yang terlihat mirip dengan Direct2D yang dibuat sebelumnya.

XAML

Overlay XAML

Direct2D

Overlay D2D

Meskipun mereka memiliki hasil akhir yang sama, ada sejumlah perbedaan antara menerapkan antarmuka Direct2D dan XAML.

Fitur XAML Direct2D
Menentukan overlay Ditentukan dalam file XAML, \*.xaml. Setelah memahami XAML, membuat dan mengonfigurasi overlay yang lebih rumit dibuat lebih sederhana jika dibandingkan dengan Direct2D. Didefinisikan sebagai kumpulan primitif Direct2D dan string DirectWrite yang ditempatkan dan ditulis secara manual ke buffer target Direct2D.
Elemen antarmuka pengguna Elemen antarmuka pengguna XAML berasal dari elemen standar yang merupakan bagian dari WINDOWS Runtime XAML API, termasuk Windows::UI::Xaml dan Windows::UI::Xaml::Controls. Kode yang menangani perilaku elemen antarmuka pengguna XAML didefinisikan dalam file codebehind, Main.xaml.cpp. Bentuk sederhana dapat digambar seperti persegi panjang dan elipsis.
Mengubah ukuran jendela Secara alami menangani perubahan ukuran dan melihat peristiwa perubahan status, mengubah overlay yang sesuai Perlu menentukan cara mengurai ulang komponen overlay secara manual.

Perbedaan besar lainnya melibatkan rantai pertukaran. Anda tidak perlu melampirkan rantai pertukaran ke objek Windows::UI::Core::CoreWindow. Sebagai gantinya, aplikasi DirectX yang menggabungkan XAML mengaitkan rantai pertukaran saat objek SwapChainPanel baru dibangun.

Cuplikan berikut menunjukkan cara mendeklarasikan XAML untuk SwapChainPanel dalam file DirectXPage.xaml .

<Page
    x:Class="Simple3DGameXaml.DirectXPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Simple3DGameXaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <SwapChainPanel x:Name="DXSwapChainPanel">

    <!-- ... XAML user controls and elements -->

    </SwapChainPanel>
</Page>

Objek SwapChainPanel diatur sebagai properti Konten dari objek jendela saat ini yang dibuat saat diluncurkan oleh singleton aplikasi.

void App::OnLaunched(_In_ LaunchActivatedEventArgs^ /* args */)
{
    m_mainPage = ref new DirectXPage();

    Window::Current->Content = m_mainPage;
    // Bring the application to the foreground so that it's visible
    Window::Current->Activate();
}

Untuk melampirkan rantai pertukaran yang dikonfigurasi ke instans SwapChainPanel yang ditentukan oleh XAML Anda, Anda harus mendapatkan penunjuk ke implementasi antarmuka ISwapChainPanelNative asli yang mendasar dan memanggil ISwapChainPanelNative::SetSwapChain di atasnya, meneruskannya rantai pertukaran yang dikonfigurasi.

Cuplikan berikut dari DX::D eviceResources::CreateWindowSizeDependentResources merinci ini untuk interop DirectX/XAML:

        ComPtr<IDXGIDevice3> dxgiDevice;
        DX::ThrowIfFailed(
            m_d3dDevice.As(&dxgiDevice)
            );

        ComPtr<IDXGIAdapter> dxgiAdapter;
        DX::ThrowIfFailed(
            dxgiDevice->GetAdapter(&dxgiAdapter)
            );

        ComPtr<IDXGIFactory2> dxgiFactory;
        DX::ThrowIfFailed(
            dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory))
            );

        // When using XAML interop, the swap chain must be created for composition.
        DX::ThrowIfFailed(
            dxgiFactory->CreateSwapChainForComposition(
                m_d3dDevice.Get(),
                &swapChainDesc,
                nullptr,
                &m_swapChain
                )
            );

        // Associate swap chain with SwapChainPanel
        // UI changes will need to be dispatched back to the UI thread
        m_swapChainPanel->Dispatcher->RunAsync(CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
        {
            // Get backing native interface for SwapChainPanel
            ComPtr<ISwapChainPanelNative> panelNative;
            DX::ThrowIfFailed(
                reinterpret_cast<IUnknown*>(m_swapChainPanel)->QueryInterface(IID_PPV_ARGS(&panelNative))
                );
            DX::ThrowIfFailed(
                panelNative->SetSwapChain(m_swapChain.Get())
                );
        }, CallbackContext::Any));

        // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
        // ensures that the application will only render after each VSync, minimizing power consumption.
        DX::ThrowIfFailed(
            dxgiDevice->SetMaximumFrameLatency(1)
            );
    }

Untuk informasi selengkapnya tentang proses ini, lihat Interop DirectX dan XAML.

Sampel

Untuk mengunduh versi game ini yang menggunakan XAML untuk overlay, lihat Sampel game DirectX dan XAML. Pastikan untuk membaca file readme di sana untuk detail tentang membuat sampel.

Tidak seperti versi permainan sampel yang dibahas di topik-topik lainnya, versi XAML mendefinisikan kerangka kerjanya dalam file App.xaml.cpp dan DirectXPage.xaml.cpp , bukan App.cpp dan GameInfoOverlay.cpp.