Estender o exemplo de jogo
Observação
Este tópico faz parte da série de tutoriais Criar um jogo simples da Plataforma Universal do Windows (UWP) com DirectX. O tópico nesse link define o contexto da série.
Para baixar a versão deste jogo que usa XAML para a sobreposição, consulte Exemplo de jogo DirectX e XAML. Certifique-se de ler o arquivo readme para obter detalhes sobre como criar o exemplo.
Neste ponto, abordamos os principais componentes de um jogo básico em DirectX 3D da Plataforma Universal do Windows (UWP). Você pode configurar a estrutura de um jogo, incluindo o provedor de exibição e o pipeline de renderização, e implementar um loop de jogo básico. Você também pode criar uma sobreposição de interface de usuário básica, incorporar sons e implementar controles. Você está no caminho certo para criar seu próprio jogo, mas se precisar de mais ajuda e informações, confira estes recursos.
Usando XAML para a sobreposição
Uma alternativa que não discutimos em profundidade é o uso de XAML em vez de Direct2D para a sobreposição. O XAML tem muitos benefícios em relação ao Direct2D para desenhar elementos da interface do usuário. O benefício mais importante é que ele torna a incorporação da aparência do Windows 10 em seu jogo DirectX mais conveniente. Muitos dos elementos, estilos e comportamentos comuns que definem um aplicativo UWP são totalmente integrados ao modelo XAML, tornando muito menos trabalhoso para um desenvolvedor de jogos implementar. Se o design do seu próprio jogo tiver uma interface do usuário complicada, considere usar XAML em vez de Direct2D.
Com o XAML, podemos criar uma interface de jogo semelhante à do Direct2D feita anteriormente.
XAML
Direct2D
Embora tenham resultados finais semelhantes, há várias diferenças entre a implementação de interfaces Direct2D e XAML.
Recurso | XAML | Direct2D |
---|---|---|
Definindo sobreposição | Definido em um arquivo XAML, \*.xaml . Depois de entender o XAML, a criação e a configuração de sobreposições mais complicadas são simplificadas quando comparadas ao Direct2D. |
Definido como uma coleção de primitivos Direct2D e cadeias de caracteres DirectWrite colocadas manualmente e gravadas em um buffer de destino Direct2D. |
Elementos da interface do usuário | Os elementos da interface do usuário XAML vêm de elementos padronizados que fazem parte das APIs XAML do Tempo de Execução do Windows, incluindo Windows::UI::Xaml e Windows::UI::Xaml::Controls. O código que manipula o comportamento dos elementos da interface do usuário XAML é definido em um arquivo codebehind, Main.xaml.cpp. | Formas simples podem ser desenhadas como retângulos e elipses. |
Redimensionamento de janela | Lida naturalmente com eventos de alteração de estado de redimensionamento e exibição, transformando a sobreposição de acordo | É necessário especificar manualmente como redesenhar os componentes da sobreposição. |
Outra grande diferença envolve a cadeia de troca. Você não precisa anexar a cadeia de troca a um objeto Windows::UI::Core::CoreWindow . Em vez disso, um aplicativo DirectX que incorpora XAML associa uma cadeia de troca quando um novo objeto SwapChainPanel é construído.
O snippet a seguir mostra como declarar XAML para o SwapChainPanel no arquivo 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>
O objeto SwapChainPanel é definido como a propriedade Content do objeto de janela atual criado na inicialização pelo singleton do aplicativo.
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();
}
Para anexar a cadeia de troca configurada à instância SwapChainPanel definida pelo XAML, você deve obter um ponteiro para a implementação de interface ISwapChainPanelNative nativa subjacente e chamar ISwapChainPanelNative::SetSwapChain nela, passando a cadeia de troca configurada.
O seguinte trecho de DX::D eviceResources::CreateWindowSizeDependentResources detalha isso para interoperabilidade 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)
);
}
Para obter mais informações sobre esse processo, consulte Interoperabilidade entre DirectX e XAML.
Amostra
Para baixar a versão deste jogo que usa XAML para a sobreposição, consulte Exemplo de jogo DirectX e XAML. Certifique-se de ler o arquivo readme para obter detalhes sobre como criar o exemplo.
Ao contrário da versão do jogo de exemplo discutida no restante desses tópicos, a versão XAML define sua estrutura nos arquivos App.xaml.cpp e DirectXPage.xaml.cpp , em vez de App.cpp e GameInfoOverlay.cpp, respectivamente.