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:
- Preencha a tela de fundo com uma cor sólida.
- Desenhe um círculo preenchido.
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:
- O método ID2D1RenderTarget::BeginDraw sinaliza o início do desenho.
- 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.
- 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.
- 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.
- Criar recursos independentes do dispositivo.
- Renderize a cena.
- 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.
- Chame ID2D1RenderTarget::BeginDraw.
- Emita comandos de desenho.
- Chame ID2D1RenderTarget::EndDraw.
- Se EndDraw retornar D2DERR_RECREATE_TARGET, descarte o destino de renderização e os recursos dependentes do dispositivo.
- 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