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
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!
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!

0 Comentários