Usando o XAML com o DirectX

Blog do desenvolvedor de aplicativos do Windows 8

Ideias sobre a criação de aplicativos com o estilo Metro para o Windows 8, da equipe de engenharia do Windows 8

Usando o XAML com o DirectX

  • Comments 0

Desde o início do desenvolvimento do Windows 8, pensamos sobre maneiras de combinar a interface do usuário, como o conjunto sofisticado de controles e a interatividade proporcionados pelo XAML, com os elementos gráficos, como a renderização de baixo nível e alto desempenho, do DirectX.

Os comentários que recebemos sobre o Developer Preview nos fóruns do Centro de Desenvolvimento e outros canais nos ajudaram a enfocar o conjunto de cenários relacionados que os desenvolvedores realmente desejavam para criar. Observamos alguns temas comuns: muitos de vocês desejavam adicionar elementos gráficos do DirectX ao que poderíamos chamar de aplicativo XAML ou adicionar a IU estilo Metro a um aplicativo DirectX facilmente.

Ótimas notícias! Com o lançamento do Consumer Preview, não precisamos mais estabelecer uma distinção clara entre um aplicativo XAML e um aplicativo DirectX. Agora você pode explorar a força do XAML, como uma plataforma de interface do usuário avançada e do DirectX, como uma solução de renderização de alto desempenho, no mesmo aplicativo, usando um modelo XAML familiar.

Agora que é possível combinar os dois, você realmente terá o melhor dos dois mundos. Isso abre uma enorme gama de possibilidades – alguns dos principais cenários descritos por vocês incluíam solicitações como:

  • Aplicativos de design, criatividade e processamento de imagens que combinam a interface do usuário com elementos gráficos
  • Mapa em grande escala e visualizadores de documentos, que combinam enormes elementos gráficos do DirectX com elementos de interface do usuário
  • Jogos e simulações com elementos gráficos do DirectX de alto desempenho e tela inteira, e elementos de interface do usuário mínimos sobrepostos

em que a combinação do XAML com o DirectX pode tornar os desenvolvedores mais produtivos e os aplicativos mais rápidos e sofisticados.

IU do Windows 8 estilo Metro

XAML – equivalente ao HTML/JavaScript – é um kit de ferramentas de interface do usuário para todos os tipos de aplicativos do Windows 8. Oferece construtos para interatividade, animações e controles estilo Metro, além de funcionalidades avançadas, como suporte à acessibilidade, vinculação de dados, mídia e hospedagem HTML. Você também se beneficia do suporte no tempo de design no Visual Studio e no Expression Blend, tudo isso usando a linguagem de programação que preferir.

Uma área em que a equipe de engenharia investe continuamente e que abrange todas essas áreas, tanto no XAML quanto no HTML/JavaScript, é o desempenho: empregamos muitos esforços nesse aspecto do Windows 8, tornando mais fácil do que nunca a criação de aplicativos estilo Metro rápidos e fluidos. Quanto aos elementos gráficos em particular, continuamos aperfeiçoando o desempenho da composição e renderização, trabalhamos para usar o hardware GPU sempre que possível e tornamos possível executar tipos de animações comuns separadamente do segmento da interface do usuário para garantir que elas funcionem sem problemas independentemente do trabalho que o seu aplicativo estiver fazendo na CPU. Trabalhamos para garantir que tudo o que as estruturas da interface do usuário fizerem seja bem feito: rápido, fluido e com baixo consumo de energia. Ao usar uma estrutura da interface do usuário, você já está se beneficiando do DirectX; em muitos casos, isso proporciona tudo o que é necessário para um ótimo desempenho dos elementos gráficos.

DirectX no Windows 8

Certamente, ainda há situações em que você precisa do desempenho de renderização do modo imediato bruto e de acesso direto aos dispositivos gráficos que o DirectX oferece. A partir do Windows 8, os componentes do DirectX SDK são incluídos como parte do Windows SDK primário e o DirectX contém vários recursos novos, como uma API 3D unificada, elementos gráficos 2D aperfeiçoados e desempenho de texto com Direct2D, um pipeline de processamento de imagens avançado e suporte à impressão aperfeiçoado.

Tudo no Windows 8 é otimizado para o DirectX e criado em torno dele, incluindo as plataformas de desenvolvedor, o sistema operacional e o design do hardware. Dessa forma, você pode usar o DirectX para atingir uma renderização com o mais alto desempenho no Windows 8. A maior vantagem é que soluções do DirectX puras podem ser muito complexas de se criar e manter, e (a menos que você use um wrapper de terceiros) elas devem ser implementadas em C++.

É aí que entra a interoperabilidade do DirectX com o XAML: agora você pode criar a sua interface do usuário XAML usando C#, Visual Basic ou C++ e incluir componentes do DirectX e C++. Você também deve estar se perguntando sobre o HTML/JavaScript e o DirectX. Como mencionei antes, trabalhamos muito para levar o poder do DirectX para as plataformas de interface do usuário, mas para combinar a interface do usuário com os elementos gráficos nativos do DirectX, focamos o XAML para Windows 8.

Metas de design

Com tudo isso em mente, desenvolvemos algumas metas principais que desejávamos atingir com a combinação do DirectX com o XAML:

1. Desempenho

  • Dar suporte à entrada de baixa latência e interatividade
  • Permitir um redesenho incremental dos conteúdos do XAML e DirectX
  • Minimizar a sobrecarga do uso do XAML

Sobretudo, desejávamos evitar impor uma “taxa do XAML”: se o seu aplicativo for originalmente DirectX, o uso do XAML deve ser uma escolha fácil, caso precise da IU estilo Metro. Sabemos que isso não é importante apenas para você: desejamos garantir que os seus clientes observassem no seu aplicativo um ótimo desempenho e uma longa vida útil da bateria.

2. Flexibilidade

  • Habilitar toda a funcionalidade do XAML e do DirectX 11

O resultado é que você pode criar e desenvolver uma interface do XAML no Blend e no Visual Studio, e combiná-la com qualquer conteúdo do DirectX. Desejávamos ter certeza de que não limitaríamos a força do XAML ou do DirectX, queríamos apenas permitir que você combinasse os dois.

3. Integração

  • Garantir uma integração perfeita entre o XAML e o DirectX

Você pode combinar elementos gráficos do DirectX com a interface do usuário XAML no mesmo aplicativo usando os conceitos familiares do XAML.

Depois de analisar o conjunto de cenários listados anteriormente, notamos que eles se encaixam em três grandes categorias:

  1. Combinação de pequenas ilhas do DirectX em uma interface do usuário originalmente XAML
  2. Combinação de superfícies do DirectX grandes e escalonáveis com uma interface do usuário XAML
  3. Sobreposição da interface do usuário XAML estilo Metro sobre um aplicativo originalmente DirectX

No final, descobrimos que uma única abordagem não funcionaria bem para todas essas categorias. Portanto, adicionamos três tipos de XAML, cada um voltado para um desses principais tipos de cenário. Acreditamos que, dessa forma, você tem um alto nível de flexibilidade para escolher a(s) opção(ões) que melhor atendam às necessidades do seu aplicativo. Essas opções não são exclusivas, você pode até mesmo usar todas as três abordagens para componentes diferentes no mesmo aplicativo.

Cenário #1 – SurfaceImageSource: ilhas do DirectX em uma interface do usuário XAML

Como a primeira opção para a combinação do DirectX com o XAML, você pode usar o novo tipo de XAML SurfaceImageSource para adicionar áreas de conteúdo do DirectX a um aplicativo XAML estilo Metro. Um exemplo desse tipo fornece uma superfície compartilhada do DirectX, que você pode desenhar usando toda a funcionalidade do DirectX, e depois compõe a superfície no resto da interface do seu aplicativo XAML.

Essa opção é especialmente útil quando se deseja usar o DirectX para desenhar componentes específicos que fazem parte de uma interface do usuário XAML maior. Por exemplo, você pode desejar usar o SurfaceImageSource quando aplicar efeitos de imagem complexos a uma foto ou quando criar visualizações de dados 3D de alto desempenho.

Se você já tiver usado um ImageSource XAML, o uso lhe será familiar: você pode definir um SurfaceImageSource como a fonte de um ImageBrush e usá-lo para pintar praticamente qualquer elemento XAML (ou elementos — os pincéis são reutilizáveis!). Por exemplo, você pode usar um SurfaceImageSource para preencher um Retângulo XAML:

SurfaceImageSource^ surfaceImageSource =  
ref new SurfaceImageSource(rectangle1->Width, rectangle1->Height, true);
ImageBrush^ brush = ref new ImageBrush();
brush->ImageSource = surfaceImageSource;
rectangle1->Fill = brush;

Depois, você pode usar o DirectX para desenhar o conteúdo do Retângulo e atualizá-lo sempre que precisar. O melhor é que essa superfície se integra perfeitamente ao modelo de composição XAML: as propriedades aplicadas ao Retângulo também afetam o conteúdo desenhado com o DirectX. Você pode sobrepor elementos facilmente e aplicar transformações de renderização, projeções, índice z ou opacidade, sem nenhum dos problemas de espaço aéreo que sempre ocorrem quando se combinam tecnologias de renderização:

Um diagrama mostrando um aplicativo XAML que combina uma superfície do DirectX com conteúdo XAML. A superfície do DirectX é girada e composta com outro conteúdo XAML que é sobreposto na superfície.

Superfície do DirectX retangular composta por conteúdo XAML

Você observou que o conceito é semelhante ao tipo D3DImage no WPF? Está certo! Entretanto, ouvimos os seus comentários sobre o D3DImage e trabalhamos para tornar o SurfaceImageSource mais avançado e fácil de usar. SurfaceImageSource em detalhes: dá suporte ao DirectX 11, incluindo o Direct2D; remove muitas das limitações do D3DImage (por exemplo, o SurfaceImageSource funciona em conexão de área de trabalho remota); aumenta o desempenho e gerencia as superfícies para você — não é mais preciso ficar bloqueando e desbloqueando, nem criar e gerenciar buffers manualmente! Um SurfaceImageSource pode até mesmo dar suporte a superfícies maiores do que o tamanho máximo da textura do seu dispositivo Direct3D.

A primeira coisa que talvez você observe ao criar um SurfaceImageSource é que, de imediato, parece que não há nenhum método novo. A implementação é de fato exposta por meio de uma interface nativa subjacente; isso ocorre porque ela precisa referenciar APIs do DirectX diretamente, que somente estão disponíveis em C++. Isso significa que você precisa usar o C++ ao chamar APIs do DirectX, seja diretamente em um aplicativo C++ XAML ou em um componente C++ WinRT que você poderá incluir em qualquer aplicativo do Visual Basic ou C#. Assim que você incluir o arquivo de cabeçalho necessário:

#include "windows.ui.xaml.media.dxinterop.h"

Você poderá consultar a interface do ISurfaceImageSourceNative que dá acesso aos três métodos necessários para começar:

interface ISurfaceImageSourceNative: IUnknown
{
SetDevice(IDXGIDevice *pDevice);
BeginDraw(
RECT updateRect,
IDXGISurface** pSurface,
POINT* offset
);

EndDraw();
};

O BeginDraw() pega um parâmetro updateRect que permite que você restrinja a área que deseja atualizar; isso permite aumentar o desempenho, fazendo somente pequenas atualizações incrementais na superfície. O método também retorna uma superfície e um ponto especificando um deslocamento no qual você deverá começar a desenhar: mesmo que você esteja atualizando toda a superfície, lembre-se de verificar esse deslocamento, pois a sua superfície pode fazer parte de uma superfície maior mantida pela estrutura internamente como uma otimização. Daqui, você pode criar e definir um Dispositivo DXGI e, então, começar a desenhar com o DirectX! O tópico do Centro de Desenvolvimento DirectX and XAML interop (Interoperabilidade do DirectX com o XAML) oferece uma boa visão geral dos detalhes.

Cenário #2 – VirtualSurfaceImageSource: Conteúdo do DirectX em grande escala + interface do usuário XAML

O VirtualSurfaceImageSource estende o SurfaceImageSource para dar um melhor suporte a superfícies muito grandes. Ele se baseia no conceito de virtualização, isto é, desenhar áreas de uma superfície somente quando elas se tornam visíveis na tela.

Criamos esse tipo para ser usado para exibir conteúdo complexo, maior do que a tela, especialmente quando se pode aplicar movimentos panorâmicos e zoom. Os cenários em que ele pode ser aplicado incluem desde um visualizador de documentos até um aplicativo de geração de imagens médicas, aplicativos com conteúdo que pode ser muito maior do que a resolução máxima de um monitor comum. Um controle de mapa é outro bom exemplo: usando um VirtualSurfaceImageSource, você pode implementar um mapa grande baseado em vetor com o DirectX e deixar que o sistema faça o trabalho de controlar a área que está na tela a qualquer momento. Você também pode sobrepor no mapa elementos XAML, como pinos, e manter suas posições em sincronia com o conteúdo do DirectX.

O VirtualSurfaceImageSource implementa essa virtualização usando itens lado a lado e um modelo de retorno de chamada. Depois de criar o seu VirtualSurfaceImageSource no tamanho máximo, o seu conteúdo DirectX se divide em uma série de áreas retangulares em plano de fundo; a estrutura acompanha os retângulos visíveis em qualquer ponto (além de alguns extras fora da exibição, para manter a movimentação panorâmica uniforme); e invoca um retorno de chamada que o seu aplicativo implementa para oferecer o conteúdo para novas regiões visíveis quando necessário. Isso funciona bem especialmente quando o conteúdo do VirtualSurfaceImageSource é colocado em um ScrollViewer para permitir uma movimentação panorâmica uniforme com o toque ou o mouse.

Uma superfície do DirectX com área visível enquadrada por uma tela. As regiões pretas fora da tela representam as partes da superfície que ainda não foram desenhadas porque ainda não estão visíveis na tela.

Superfície grande dividida em mosaicos retangulares

Essa abordagem não é apenas mais fácil de implementar do que controlar as coordenadas sozinho: ela pode proporcionar um grande aumento no desempenho do seu aplicativo. Como o sistema armazena o seu conteúdo em cache internamente, depois que você desenha o conteúdo de uma região, ele é guardado na memória e reutilizado automaticamente depois pelo GPU, mesmo durante e após um movimento panorâmico. Não é necessário desenhar de novo! Se você desejar atualizar qualquer região que já tiver desenhado, poderá simplesmente chamar o BeginDraw(), assim como faria com o SurfaceImageSource. Como uma maior otimização do desempenho, o sistema automaticamente recicla a memória usada para regiões antigas que estão fora da exibição após um determinado ponto, ajudando a vincular o uso da memória e garantir que o seu aplicativo tenha um bom desempenho em uma série de fatores forma e perfis de hardware mesmo com superfícies muito grandes. Esse aumento no desempenho é especialmente visível em dispositivos portáteis, como os tablets.

De forma semelhante ao uso do SurfaceImageSource, você pode consultar a interface nativa subjacente, nesse caso o IVirtualSurfaceImageSourceNative, para acessar os métodos necessários. Confira o artigo do Centro de Desenvolvimento DirectX and XAML interop ou o exemplo de aplicativo Direct2D da revista para obter mais detalhes.

Cenário #3 – SwapChainBackgroundPanel: DirectX com sobreposição do XAML

A terceira e última opção para combinar o conteúdo do DirectX com o XAML, SwapChainBackgroundPanel é um elemento XAML para desenvolver aplicativos em tela inteira originalmente voltados para o DirectX. Diferente do SurfaceImageSource e do VirtualSurfaceImageSource, o SwapChainBackgroundPanel é um elemento XAML e não um ImageSource; ele herda do painel de layout da Grade XAML e permite que os aplicativos criem e controlem totalmente uma cadeia de permuta do DirectX em tela inteira, sobre a qual todos os outros conteúdos XAML são sobrepostos:

Ilustração do modelo de composição do SwapChainBackgroundPanel, em que o conteúdo do DirectX sempre fica atrás de uma sobreposição do XAML

SwapChainBackgroundPanel atrás do conteúdo XAML sobreposto

Achamos que essa é definitivamente a melhor opção para jogos e outros aplicativos em que a maior parte dos elementos gráficos são DirectX; você obtém um ótimo desempenho e um modelo atualizado próximo a um aplicativo puramente DirectX e pode usar o XAML ao mesmo tempo para criar facilmente uma interface de exibição de alertas e vincular seus dados ao seu modelo de jogo, adicionar controles interativos e incluir elementos estilo Metro, como AppBars.

Para conseguir isso, impusemos algumas restrições ao SwapChainBackgroundPanel: ele deve ser o elemento XAML raiz do seu aplicativo, e algumas propriedades XAML herdadas, como a Opacidade e o RenderTransform, não terão efeito sobre ele (embora você possa, é claro, aplicar operações equivalentes do DirectX ao conteúdo da cadeia de permuta para conseguir os mesmos efeitos). Com isso, você tem uma forte integração com o modelo de composição da estrutura do XAML obtido pelo SurfaceImageSource, além da interação com a latência mais baixa e um maior controle sobre o tempo de apresentação, possíveis quando se gerencia a cadeia de permuta diretamente.

A interface nativa subjacente nesse caso tem apenas um método:

interface ISwapChainBackgroundPanelNative: IUnknown
{
SetSwapChain(IDXGISwapChain *pSwapChain);
};

Você pode começar a apresentar o seu conteúdo assim que chamar o SetSwapChain() para associar a sua cadeia de permuta ao painel. Nesse ponto, o SwapChainBackgroundPanel também pode ser testado quanto aos cliques e você trata a entrada usando eventos de entrada XAML normais. Todo elemento XAML filho adicionado ao painel é exibido na parte superior da sua cadeia de permuta.

O tópico do Centro de Desenvolvimento sobre interoperabilidade tem mais informações sobre o uso do SwapChainBackgroundPanel e você pode ver a fonte da compilação de um exemplo de jogo de tiro com o DirectX usando o SwapChainBackgroundPanel que mostra a implementação completa de um jogo Direct3D com uma interface XAML:

Captura de tela de um jogo de tiro com o DirectX e o XAML em que o usuário é o atirador. A superfície do DirectX contém paredes e alvos sobrepostos por uma interface do usuário XAML que contém um menu e um controle AppBar.

Jogo criado com o DirectX e o XAML

Resumo

Estamos empolgados com as novas possibilidades que surgem quando combinamos o suporte a uma interface do usuário sofisticada e a produtividade do tempo de design do XAML com a força dos elementos gráficos de alto desempenho do DirectX. Esperamos que essas três novas opções para a criação de aplicativos estilo Metro lhe sejam úteis na criação de aplicativos incríveis para os seus clientes.

-- Jesse Bishop
    gerente de programas, Windows

  • Loading...
Leave a Comment
  • Please add 4 and 5 and type the answer here:
  • Post