Like On Facebook

header ads

Renderizando gráficos 2D

Nesta seção, vamos criar uma janela Windows que usa o Direct2D para renderizar gráficos. Este exemplo renderiza um retângulo simples e mostra como configurar o Direct2D para uma aplicação básica de renderização 2D.

Código Dividido e Comentado

1. Inclusão de Bibliotecas e Declarações Globais
 #include <d2d1.h>          // Biblioteca Direct2D
 #include <windows.h>       // Biblioteca Windows API
 #pragma comment(lib, "d2d1.lib") // Linka a biblioteca Direct2D automaticamente

 // Variáveis globais para objetos Direct2D
 ID2D1Factory* pFactory = nullptr;             // Fábrica para criar objetos  Direct2D
 ID2D1HwndRenderTarget* pRenderTarget = nullptr; // Alvo de renderização, associado à janela
 ID2D1SolidColorBrush* pBrushBlack = nullptr; // Pincel para o retângulo preto
 ID2D1SolidColorBrush* pBrushRed = nullptr;   // Pincel para o círculo vermelho
 ID2D1SolidColorBrush* pBrushGreen = nullptr; // Pincel para o triângulo verde
  Aqui, incluímos as bibliotecas d2d1.h e windows.h, necessárias para usar o Direct2D e a API do Windows. Definimos quatro variáveis globais para pincéis que serão usados para desenhar as formas.

2. Declaração das Funções e Prototipação
 void InitializeDirect2D(HWND hwnd); // Inicializa os componentes Direct2D
 void Render();                      // Função para renderizar a cena
 void Cleanup();                     // Função para liberar recursos
  Essas funções encapsulam a lógica de inicialização, renderização e limpeza de recursos. Isso mantém o código organizado e modular.

3. Função de Janela WindowProc
 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
     if (uMsg == WM_DESTROY) {              // Se a janela for fechada
         PostQuitMessage(0);                // Envia uma mensagem para encerrar o loop
         return 0;
     }
     return DefWindowProc(hwnd, uMsg, wParam, lParam); // Processa outras mensagens
 }
  Esta função trata os eventos da janela, como fechamento e outras interações. Quando a mensagem WM_DESTROY é recebida, ela indica que a janela foi fechada, então enviamos uma mensagem de saída com PostQuitMessage(0).

4. Função Principal WinMain
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) {
     // Define a classe da janela
     const wchar_t CLASS_NAME[] = L"Sample Window Class";

     WNDCLASS wc = {};                  // Estrutura para registrar a classe da janela
     wc.lpfnWndProc = WindowProc;       // Define a função de janela
     wc.hInstance = hInstance;
     wc.lpszClassName = CLASS_NAME;

     RegisterClass(&wc);                // Registra a classe da janela

     // Cria a janela
     HWND hwnd = CreateWindowEx(
         0,
         CLASS_NAME,
         L"Renderização Direct2D",
         WS_OVERLAPPEDWINDOW,
         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
         nullptr, nullptr, hInstance, nullptr
     );

     if (!hwnd) return 0;               // Verifica se a janela foi criada

     ShowWindow(hwnd, nCmdShow);        // Exibe a janela

     // Inicializa o Direct2D
     InitializeDirect2D(hwnd);

     // Loop de mensagens e renderização
     MSG msg = {};
     while (GetMessage(&msg, nullptr, 0, 0)) {
         TranslateMessage(&msg);
         DispatchMessage(&msg);

         Render();                      // Renderiza a cena a cada iteração
     }

     // Limpeza dos recursos Direct2D
     Cleanup();

     return 0;
 }
A função WinMain é a entrada principal do programa: 
  • Define uma classe de janela e a registra. 
  • Cria a janela principal e a exibe. 
  • Chama InitializeDirect2D para configurar o Direct2D. 
  • Entra em um loop de mensagens (GetMessage) que mantém a janela ativa e chama a função Render() para desenhar a cena.

5. Função InitializeDirect2D
 void InitializeDirect2D(HWND hwnd) {
     // Cria uma fábrica Direct2D
     D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory);

     // Define o tamanho do alvo de renderização com o tamanho da janela
     RECT rc;
     GetClientRect(hwnd, &rc);
     D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);

     // Cria o alvo de renderização associado à janela
     pFactory->CreateHwndRenderTarget(
         D2D1::RenderTargetProperties(),
         D2D1::HwndRenderTargetProperties(hwnd, size),
         &pRenderTarget
     );

     // Cria pincéis para desenhar
     pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &pBrushBlack);   // Pincel preto para o retângulo
     pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red), &pBrushRed);       // Pincel vermelho para o círculo
     pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Green), &pBrushGreen);   // Pincel verde para o triângulo
}
Esta função configura o Direct2D: 

  • Cria uma fábrica com D2D1CreateFactory
  • Define o tamanho do alvo de renderização com o tamanho da janela (GetClientRect).
  • Cria um HwndRenderTarget associado diretamente à janela, permitindo que o Direct2D desenhe diretamente nela. 
  • Cria três pincéis, um para cada forma a ser desenhada.

6. Função de Renderização Render
 void Render() {
     pRenderTarget->BeginDraw();                  // Inicia o processo de renderização

     pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::SkyBlue)); // Limpa o fundo

     // Desenha um retângulo preto
     D2D1_RECT_F rectangle = D2D1::RectF(100.0f, 100.0f, 300.0f, 200.0f);
     pRenderTarget->FillRectangle(&rectangle, pBrushBlack);

     // Desenha um círculo vermelho
     D2D1_ELLIPSE circle = D2D1::Ellipse(D2D1::Point2F(400.0f, 150.0f), 50.0f, 50.0f);
     pRenderTarget->FillEllipse(&circle, pBrushRed);

     // Desenha um triângulo verde
     ID2D1PathGeometry* pTriangleGeometry = nullptr; // Geometria do triângulo
     pFactory->CreatePathGeometry(&pTriangleGeometry); // Cria a geometria do triângulo

     ID2D1GeometrySink* pSink = nullptr;
     pTriangleGeometry->Open(&pSink); // Abre o geometria para receber dados
     pSink->BeginFigure(D2D1::Point2F(300.0f, 300.0f), D2D1_FIGURE_BEGIN_FILLED); // Primeiro vértice
     pSink->AddLine(D2D1::Point2F(250.0f, 400.0f)); // Segundo vértice
     pSink->AddLine(D2D1::Point2F(350.0f, 400.0f)); // Terceiro vértice
     pSink->EndFigure(D2D1_FIGURE_END_CLOSED); // Fecha o triângulo
     pSink->Close(); // Fecha o sink

     pRenderTarget->FillGeometry(pTriangleGeometry, pBrushGreen, nullptr); // Desenha o triângulo

     // Limpa a geometria após o uso
     pTriangleGeometry->Release(); 
     pRenderTarget->EndDraw();                    // Finaliza a renderização
 }
A função Render: 
  • Inicia o processo de renderização (BeginDraw). 
  • Limpa o fundo da janela com a cor SkyBlue
  • Desenha um retângulo preto usando FillRectangle
  • Desenha um círculo vermelho usando FillEllipse
  • Cria um triângulo verde usando uma ID2D1PathGeometry para definir sua forma. Os vértices do triângulo são definidos usando AddLine
  • Finaliza a renderização com EndDraw.

7. Função de Limpeza Cleanup
 void Cleanup() {
     // Libera recursos
     if (pRenderTarget) pRenderTarget->Release();
     if (pBrushBlack) pBrushBlack->Release();
     if (pBrushRed) pBrushRed->Release();
     if (pBrushGreen) pBrushGreen->Release();
     if (pFactory) pFactory->Release();
 }

  A função Cleanup libera todos os recursos alocados para evitar vazamentos de memória.

Compilação e Execução
 g++ -o render2D.exe render2D.cpp -DUNICODE -D_UNICODE -mwindows -ld2d1 

  Esse exemplo deve fornecer uma base sólida para a renderização de formas 2D com Direct2D. Se você tiver mais perguntas ou precisar de mais funcionalidades, sinta-se à vontade para perguntar!

Postar um comentário

0 Comentários