Início Rápido do Direct2D

Direct2D é uma API de código nativo e modo imediato para criar gráficos 2D. Este tópico ilustra como usar Direct2D em um aplicativo Win32 típico para desenhar em um HWND.

Observação

Se você quiser criar um aplicativo da Windows Store que usa Direct2D, consulte o Direct2D guia de início rápido para Windows 8 tópico.

 

Este tópico contém as seguintes seções:

Desenhando um retângulo simples

Para desenhar um retângulo usando GDI, você pode manipular a mensagem WM_PAINT , conforme mostrado no código a seguir.

switch(message)
{

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);

            // Obtain the size of the drawing area.
            RECT rc;
            GetClientRect(
                hwnd,
                &rc
            );          

            // Save the original object
            HGDIOBJ original = NULL;
            original = SelectObject(
                ps.hdc,
                GetStockObject(DC_PEN)
            );

            // Create a pen.            
            HPEN blackPen = CreatePen(PS_SOLID, 3, 0);

            // Select the pen.
            SelectObject(ps.hdc, blackPen);

            // Draw a rectangle.
            Rectangle(
                ps.hdc, 
                rc.left + 100, 
                rc.top + 100, 
                rc.right - 100, 
                rc.bottom - 100);   

            DeleteObject(blackPen);

            // Restore the original object
            SelectObject(ps.hdc, original);

            EndPaint(hwnd, &ps);
        }
        return 0;

// Code for handling other messages. 

O código para desenhar o mesmo retângulo com Direct2D é semelhante: ele cria recursos de desenho, descreve uma forma a ser desenhada, desenha a forma e libera os recursos de desenho. As seções a seguir descrevem cada uma dessas etapas em detalhes.

Etapa 1: incluir Direct2D cabeçalho

Além dos cabeçalhos necessários para um aplicativo Win32, inclua o cabeçalho d2d1.h.

Etapa 2: Criar um ID2D1Factory

Uma das primeiras coisas que qualquer exemplo Direct2D faz é criar um ID2D1Factory.

ID2D1Factory* pD2DFactory = NULL;
HRESULT hr = D2D1CreateFactory(
    D2D1_FACTORY_TYPE_SINGLE_THREADED,
    &pD2DFactory
    );

A interface ID2D1Factory é o ponto de partida para usar Direct2D; use um ID2D1Factory para criar recursos Direct2D.

Ao criar uma fábrica, você pode especificar se ela é multi-ou de thread único. (Para obter mais informações sobre fábricas multi-threaded, consulte os comentários na página de referência ID2D1Factory.) Este exemplo cria uma fábrica de thread único.

Em geral, seu aplicativo deve criar a fábrica uma vez e retê-la durante a vida útil do aplicativo.

Etapa 3: Criar um ID2D1HwndRenderTarget

Depois de criar uma fábrica, use-a para criar um destino de renderização.



// Obtain the size of the drawing area.
RECT rc;
GetClientRect(hwnd, &rc);

// Create a Direct2D render target          
ID2D1HwndRenderTarget* pRT = NULL;          
HRESULT hr = pD2DFactory->CreateHwndRenderTarget(
    D2D1::RenderTargetProperties(),
    D2D1::HwndRenderTargetProperties(
        hwnd,
        D2D1::SizeU(
            rc.right - rc.left,
            rc.bottom - rc.top)
    ),
    &pRT
);

Um destino de renderização é um dispositivo que pode executar operações de desenho e criar recursos de desenho dependentes do dispositivo, como pincéis. Diferentes tipos de destinos de renderização são renderizados em dispositivos diferentes. O exemplo anterior usa um ID2D1HwndRenderTarget, que é renderizado em uma parte da tela.

Quando possível, um destino de renderização usa a GPU para acelerar as operações de renderização e criar recursos de desenho. Caso contrário, o destino de renderização usa a CPU para processar instruções de renderização e criar recursos. (Você pode modificar esse comportamento usando os sinalizadores D2D1_RENDER_TARGET_TYPE ao criar o destino de renderização.)

O método CreateHwndRenderTarget usa três parâmetros. O primeiro parâmetro, um struct D2D1_RENDER_TARGET_PROPERTIES , especifica opções de exibição remota, se o destino de renderização deve ser renderizado para software ou hardware e o DPI. O código neste exemplo usa a função auxiliar D2D1::RenderTargetProperties para aceitar propriedades de destino de renderização padrão.

O segundo parâmetro, um struct D2D1_HWND_RENDER_TARGET_PROPERTIES , especifica o HWND para o qual o conteúdo é renderizado, o tamanho inicial do destino de renderização (em pixels) e suas opções de apresentação. Este exemplo usa a função auxiliar D2D1::HwndRenderTargetProperties para especificar um HWND e um tamanho inicial. Ele usa opções de apresentação padrão.

O terceiro parâmetro é o endereço do ponteiro que recebe a referência de destino de renderização.

Quando você cria um destino de renderização e a aceleração de hardware está disponível, você aloca recursos na GPU do computador. Ao criar um destino de renderização uma vez e mantê-lo o maior tempo possível, você obtém benefícios de desempenho. Seu aplicativo deve criar destinos de renderização uma vez e mantê-los durante a vida útil do aplicativo ou até que o erro de D2DERR_RECREATE_TARGET seja recebido. Ao receber esse erro, você precisa recriar o destino de renderização (e todos os recursos que ele criou).

Etapa 4: Criar um pincel

Como uma fábrica, um destino de renderização pode criar recursos de desenho. Neste exemplo, o destino de renderização cria um pincel.

ID2D1SolidColorBrush* pBlackBrush = NULL;
if (SUCCEEDED(hr))
{
            
    pRT->CreateSolidColorBrush(
        D2D1::ColorF(D2D1::ColorF::Black),
        &pBlackBrush
        ); 
}

Um pincel é um objeto que pinta uma área, como o traço de uma forma ou o preenchimento de uma geometria. O pincel neste exemplo pinta uma área com uma cor sólida predefinida, preto.

Direct2D também fornece outros tipos de pincéis: pincéis de gradiente para pintar gradientes lineares e radiais e um pincel de bitmap para pintura com bitmaps e padrões.

Algumas APIs de desenho fornecem canetas para contornos de desenho e pincéis para preencher formas. Direct2D é diferente: ele não fornece um objeto de caneta, mas usa um pincel para desenhar contornos e preencher formas. Ao desenhar estruturas de tópicos, use a interface ID2D1StrokeStyle com um pincel para controlar as operações de acariciamento de caminho.

Um pincel só pode ser usado com o destino de renderização que o criou e com outros destinos de renderização no mesmo domínio de recurso. Em geral, você deve criar pincéis uma vez e retê-los durante a vida útil do destino de renderização que os criou. ID2D1SolidColorBrush é a exceção solitária; porque é relativamente barato criar, você pode criar um ID2D1SolidColorBrush sempre que desenhar um quadro, sem nenhum impacto perceptível no desempenho. Você também pode usar um único ID2D1SolidColorBrush e apenas alterar sua cor sempre que usá-la.

Etapa 5: Desenhar o retângulo

Em seguida, use o destino de renderização para desenhar o retângulo.

 
pRT->BeginDraw();

pRT->DrawRectangle(
    D2D1::RectF(
        rc.left + 100.0f,
        rc.top + 100.0f,
        rc.right - 100.0f,
        rc.bottom - 100.0f),
        pBlackBrush);

HRESULT hr = pRT->EndDraw();  

O método DrawRectangle usa dois parâmetros: o retângulo a ser desenhado e o pincel a ser usado para pintar a estrutura de tópicos do retângulo. Opcionalmente, você também pode especificar as opções largura do traço, padrão de traço, junção de linha e limite final.

Você deve chamar o método BeginDraw antes de emitir comandos de desenho e deve chamar o método EndDraw depois de terminar de emitir comandos de desenho. O método EndDraw retorna um HRESULT que indica se os comandos de desenho foram bem-sucedidos.

Etapa 6: liberar recursos

Quando não houver mais quadros para desenhar ou quando você receber o erro D2DERR_RECREATE_TARGET , libere o destino de renderização e todos os dispositivos que ele criou.

 
SafeRelease(pRT);
SafeRelease(pBlackBrush);

Quando o aplicativo terminar de usar Direct2D recursos (como quando ele está prestes a sair), libere o Direct2D fábrica.

 
SafeRelease(pD2DFactory);

Criar um aplicativo de Direct2D simples

O código neste tópico mostra os elementos básicos de um aplicativo Direct2D. Para resumir, o tópico omite a estrutura do aplicativo e o código de tratamento de erros que são características de um aplicativo bem escrito. Para obter um passo a passo mais detalhado que mostra o código completo para criar um aplicativo Direct2D simples e demonstra as melhores práticas de design, consulte Criar um aplicativo de Direct2D simples.

Criar um aplicativo Direct2D simples