Like On Facebook

header ads

Análise do Código de Renderização com Direct2D

Aqui, examinaremos o código para a criação de uma janela de renderização 2D usando Direct2D, incluindo uma análise detalhada de cada parte do código e uma explicação sobre a função GeometrySink no contexto de criação de formas complexas.


Estrutura do Código

O código de criação da janela de renderização é dividido nas seguintes partes principais:

    1. Definições de Variáveis Globais
    2. Função InitDirect2D para Inicializar o Direct2D
    3. Função WndProc para o Procedimento de Janela
    4. Função Render para Desenho dos Elementos 2D
    5. Função Cleanup para Liberação de Recursos


1. Definições de Variáveis Globais

Aqui definimos variáveis globais para os principais componentes do Direct2D:
 ID2D1Factory* pFactory = nullptr;            // Fábrica Direct2D
 ID2D1HwndRenderTarget* pRenderTarget = nullptr; // Superfície de renderização para a janela
 ID2D1SolidColorBrush* pBrushBlack = nullptr; // Pincel para a cor preta
 ID2D1SolidColorBrush* pBrushRed = nullptr;   // Pincel para a cor vermelha
 ID2D1SolidColorBrush* pBrushGreen = nullptr; // Pincel para a cor verde
  • ID2D1Factory: Cria objetos Direct2D e gerencia recursos. 
  • ID2D1HwndRenderTarget: Representa a superfície de renderização associada à janela. 
  • ID2D1SolidColorBrush: Permite desenhar formas com cores sólidas.

2. Função InitDirect2D para Inicialização do Direct2D 

  Esta função configura o ambiente Direct2D e cria o RenderTarget, essencial para desenhar na janela.
 HRESULT InitDirect2D(HWND hWnd) {
     HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory);
     if (FAILED(hr)) return hr;

     RECT rc;
     GetClientRect(hWnd, &rc);

     hr = pFactory->CreateHwndRenderTarget(
         D2D1::RenderTargetProperties(),
         D2D1::HwndRenderTargetProperties(
             hWnd, D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)
         ),
         &pRenderTarget
     );
     if (FAILED(hr)) return hr;

     pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &pBrushBlack);
     pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red), &pBrushRed);
     pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Green), &pBrushGreen);

     return S_OK;
 }
    1. Criação da Fábrica ( pFactory ): Com D2D1CreateFactory, criamos uma instância da fábrica Direct2D. 
    2. Target de Renderização: Criamos o HwndRenderTarget, uma superfície de renderização associada à janela ( hWnd ), usando as dimensões da área cliente da janela. 
    3. Pincéis ( pBrushBlack, pBrushRed, pBrushGreen ): Criamos pincéis de cores para uso posterior na renderização de formas.

3. Função WndProc para o Procedimento de Janela 

  WndProc gerencia as mensagens enviadas para a janela e aciona o procedimento adequado para cada uma.
 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
     switch (message) {
         case WM_PAINT:
             Render();
             ValidateRect(hWnd, NULL);
             break;
         case WM_DESTROY:
             PostQuitMessage(0);
             break;
         default:
             return DefWindowProc(hWnd, message, wParam, lParam);
     }
     return 0;
 }
 
  • WM_PAINT: Quando a janela precisa ser redesenhada, chama a função Render
  • WM_DESTROY: Envia uma mensagem de encerramento ao sistema.

4. Função Render para Desenho dos Elementos 2D 

  A função Render usa o RenderTarget para desenhar um retângulo, um círculo e um triângulo verde usando uma geometria customizada.
 void Render() {
     pRenderTarget->BeginDraw();
     pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::SkyBlue));
    
     // Retângulo preto
     pRenderTarget->FillRectangle(D2D1::RectF(50, 50, 150, 150), pBrushBlack);

     // Círculo vermelho
     pRenderTarget->FillEllipse(D2D1::Ellipse(D2D1::Point2F(300, 100), 50, 50), pBrushRed);

     // Triângulo verde usando uma GeometrySink
     ID2D1PathGeometry* pPathGeometry = nullptr;
     pFactory->CreatePathGeometry(&pPathGeometry);

     ID2D1GeometrySink* pSink = nullptr;
     pPathGeometry->Open(&pSink);
     pSink->BeginFigure(D2D1::Point2F(500, 50), D2D1_FIGURE_BEGIN_FILLED);
     pSink->AddLine(D2D1::Point2F(450, 150));
     pSink->AddLine(D2D1::Point2F(550, 150));
     pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
     pSink->Close();

     pRenderTarget->FillGeometry(pPathGeometry, pBrushGreen);

     pPathGeometry->Release();
     pSink->Release();

     pRenderTarget->EndDraw();
 }
Explicação do Código para o Triângulo Verde 

A criação do triângulo verde usa a função GeometrySink, que é uma interface do Direct2D para construir formas complexas: 

  • 1. Criação de uma PathGeometry: pFactory->CreatePathGeometry(&pPathGeometry); cria um objeto de geometria de caminho vazio, pPathGeometry, que será preenchido com os vértices do triângulo. 

 

  • 2. Abertura do GeometrySink: pPathGeometry->Open(&pSink); abre o GeometrySink, que é um canal para enviar dados sobre vértices ao Direct2D para criar formas personalizadas. 

  • 3. Desenho do Triângulo
    • Início da Figura: pSink->BeginFigure(D2D1::Point2F(500, 50), D2D1_FIGURE_BEGIN_FILLED); define o primeiro vértice do triângulo e indica que o triângulo deve ser preenchido. 
    • Adição de Linhas: pSink->AddLine(...) adiciona os dois vértices restantes. 
    • Finalização da Figura: pSink->EndFigure(D2D1_FIGURE_END_CLOSED); fecha a figura, conectando o último ponto ao ponto inicial para formar um triângulo. 

  • 4. Fechamento e Renderização: 
    • Fechamento do Sink: pSink->Close(); finaliza o envio de dados para o PathGeometry.
    • Renderização: pRenderTarget->FillGeometry(pPathGeometry, pBrushGreen); preenche a forma com a cor verde. 

O GeometrySink permite desenhar formas complexas ao especificar pontos e segmentos. Ao finalizar e fechar o sink, o Direct2D cria a geometria com base nas informações fornecidas.

5. Função Cleanup para Liberação de Recursos 

  A função Cleanup libera os recursos alocados, evitando vazamento de memória:
 void Cleanup() {
     if (pRenderTarget) pRenderTarget->Release();
     if (pBrushBlack) pBrushBlack->Release();
     if (pBrushRed) pBrushRed->Release();
     if (pBrushGreen) pBrushGreen->Release();
     if (pFactory) pFactory->Release();
 }


🚀 Resumo 

Este código cria uma janela de renderização 2D usando Direct2D com diferentes formas ( retângulo, círculo e triângulo ). A função GeometrySink permite criar formas personalizadas como o triângulo, fornecendo mais controle sobre os vértices e a estrutura da figura.

Postar um comentário

0 Comentários