Compartilhar via


Desenhar com Direct2D

Depois de criar seus recursos gráficos, você estará pronto para desenhar.

Desenhando uma elipse

O programa Circle executa uma lógica de desenho muito simples:

  1. Preencha a tela de fundo com uma cor sólida.
  2. Desenhe um círculo preenchido.

uma captura de tela do programa circular.

Como o destino de renderização é uma janela (em vez de um bitmap ou outra superfície fora da tela), o desenho é feito em resposta a mensagens WM_PAINT . O código a seguir mostra o procedimento de janela para o programa Circle.

LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_PAINT:
            OnPaint();
            return 0;

         // Other messages not shown...
    }
    return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}

Aqui está o código que desenha o círculo.

void MainWindow::OnPaint()
{
    HRESULT hr = CreateGraphicsResources();
    if (SUCCEEDED(hr))
    {
        PAINTSTRUCT ps;
        BeginPaint(m_hwnd, &ps);
     
        pRenderTarget->BeginDraw();

        pRenderTarget->Clear( D2D1::ColorF(D2D1::ColorF::SkyBlue) );
        pRenderTarget->FillEllipse(ellipse, pBrush);

        hr = pRenderTarget->EndDraw();
        if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
        {
            DiscardGraphicsResources();
        }
        EndPaint(m_hwnd, &ps);
    }
}

A interface ID2D1RenderTarget é usada para todas as operações de desenho. O método do OnPaint programa faz o seguinte:

  1. O método ID2D1RenderTarget::BeginDraw sinaliza o início do desenho.
  2. O método ID2D1RenderTarget::Clear preenche todo o destino de renderização com uma cor sólida. A cor é fornecida como uma estrutura D2D1_COLOR_F . Você pode usar a classe D2D1::ColorF para inicializar a estrutura. Para obter mais informações, consulte Usando cor em Direct2D.
  3. O método ID2D1RenderTarget::FillEllipse desenha uma elipse preenchida, usando o pincel especificado para o preenchimento. Uma elipse é especificada por um ponto central e os raios x e y. Se os raios x e y forem os mesmos, o resultado será um círculo.
  4. O método ID2D1RenderTarget::EndDraw sinaliza a conclusão do desenho para esse quadro. Todas as operações de desenho devem ser colocadas entre chamadas para BeginDraw e EndDraw.

Todos os métodos BeginDraw, Clear e FillEllipse têm um tipo de retorno void . Se ocorrer um erro durante a execução de qualquer um desses métodos, o erro será sinalizado por meio do valor retornado do método EndDraw . O CreateGraphicsResources método é mostrado no tópico Criando recursos Direct2D. Esse método cria o destino de renderização e o pincel de cor sólida.

O dispositivo pode armazenar em buffer os comandos de desenho e adiar a execução deles até que EndDraw seja chamado. Você pode forçar o dispositivo a executar quaisquer comandos de desenho pendentes chamando ID2D1RenderTarget::Flush. No entanto, a liberação pode reduzir o desempenho.

Manipulando a perda de dispositivo

Enquanto o programa está em execução, o dispositivo gráfico que você está usando pode ficar indisponível. Por exemplo, o dispositivo poderá ser perdido se a resolução de exibição for alterada ou se o usuário remover o adaptador de exibição. Se o dispositivo for perdido, o destino de renderização também se tornará inválido, juntamente com todos os recursos dependentes do dispositivo associados ao dispositivo. Direct2D sinaliza um dispositivo perdido retornando o código de erro D2DERR_RECREATE_TARGET do método EndDraw. Se você receber esse código de erro, deverá recriar o destino de renderização e todos os recursos dependentes do dispositivo.

Para descartar um recurso, basta liberar a interface para esse recurso.

void MainWindow::DiscardGraphicsResources()
{
    SafeRelease(&pRenderTarget);
    SafeRelease(&pBrush);
}

A criação de um recurso pode ser uma operação cara, portanto, não recrie seus recursos para cada mensagem de WM_PAINT . Crie um recurso uma vez e armazene o ponteiro do recurso em cache até que o recurso se torne inválido devido à perda de dispositivo ou até que você não precise mais desse recurso.

O loop de renderização do Direct2D

Independentemente do que você desenhar, seu programa deve executar um loop semelhante ao seguinte.

  1. Criar recursos independentes do dispositivo.
  2. Renderize a cena.
    1. Verifique se existe um destino de renderização válido. Caso contrário, crie o destino de renderização e os recursos dependentes do dispositivo.
    2. Chame ID2D1RenderTarget::BeginDraw.
    3. Emita comandos de desenho.
    4. Chame ID2D1RenderTarget::EndDraw.
    5. Se EndDraw retornar D2DERR_RECREATE_TARGET, descarte o destino de renderização e os recursos dependentes do dispositivo.
  3. Repita a etapa 2 sempre que precisar atualizar ou redesenhar a cena.

Se o destino de renderização for uma janela, a etapa 2 ocorrerá sempre que a janela receber uma mensagem de WM_PAINT .

O loop mostrado aqui lida com a perda de dispositivo descartando os recursos dependentes do dispositivo e recriando-os no início do próximo loop (etapa 2a).

Avançar

DPI e pixels de Device-Independent