Like On Facebook

header ads

Criando um Projeto DirectX em C++


Após concluir os módulos anteriores, onde abordamos os fundamentos do C++, vamos agora criar um projeto básico utilizando a biblioteca DirectX. Esta seção irá guiá-lo através dos passos essenciais para iniciar seu projeto.


Passo 1: Baixando o SDK do DirectX

Antes de começar, você precisará baixar o SDK do DirectX. Siga estas etapas:

  • Acesse a página do DirectX SDK:
  • Baixe e instale o SDK:
    • 1. Clique em "Download" e siga as instruções para instalar o SDK no seu sistema.

Passo 2: Estrutura do Projeto

  • Crie uma nova pasta para o seu projeto:
    • 1. Nomeie-a, por exemplo, MeuProjetoDirectX.

  • Dentro dessa pasta, crie os seguintes arquivos:
    • 1. main.cppO arquivo principal onde a aplicação será iniciada.
    • 2. Shader.h e Shader.cpp: Para carregar e compilar shaders ( opcional ).
    • 3. Resource.h: Para definir recursos ( caso necessário ).

Passo 3: Código Inicial com Comentários

Aqui está um exemplo de um código básico que inicializa uma janela usando DirectX, com comentários detalhados:

 #include <windows.h>           // Inclui a biblioteca de janelas do Windows
 #include <d3d11.h>           // Inclui a biblioteca Direct3D 11

 // Linka as bibliotecas necessárias para o Direct3D 11
 #pragma comment(lib, "d3d11.lib")

 // Prototipação de funções
 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 void InitializeDirectX(HWND hwnd);

 // Declarações globais para DirectX
 ID3D11Device* g_device = nullptr;                     // Dispositivo Direct3D
 ID3D11DeviceContext* g_context = nullptr;             // Contexto do dispositivo
 ID3D11RenderTargetView* g_renderTargetView = nullptr; // Visão de destino de renderização

 // Função principal do Windows
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nShowCmd) {
     // Registro da classe da janela
     const char CLASS_NAME[] = "Sample Window Class";  // Nome da classe da janela

     WNDCLASS wc = {};  // Inicializa a estrutura WNDCLASS
     wc.lpfnWndProc = WindowProc;  // Define a função de processamento da janela
     wc.hInstance = hInstance;  // Define o identificador da instância
     wc.lpszClassName = CLASS_NAME;  // Define o nome da classe da janela

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

     // Criação da janela
     HWND hwnd = CreateWindowEx(
         0, CLASS_NAME, "Meu Projeto DirectX",  // Estilo da janela e título
         WS_OVERLAPPEDWINDOW,  // Estilo da janela
         CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,  // Posição e tamanho da janela
         nullptr, nullptr, hInstance, nullptr  // Sem menu ou parâmetros adicionais
     );

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

     // Inicializa o DirectX
     InitializeDirectX(hwnd);  // Chama a função para inicializar o DirectX

     // Loop da mensagem
     MSG msg;  // Estrutura para armazenar mensagens
     while (GetMessage(&msg, nullptr, 0, 0)) {  // Enquanto houver mensagens na fila
         TranslateMessage(&msg);  // Traduz mensagens do teclado
         DispatchMessage(&msg);  // Despacha a mensagem para a função de processamento
     }

     // Libera recursos antes de sair
     if (g_renderTargetView) g_renderTargetView->Release();
     if (g_context) g_context->Release();
     if (g_device) g_device->Release();

     return 0;  // Retorna 0 para indicar que a aplicação terminou
 }

 // Função para inicializar o DirectX
 void InitializeDirectX(HWND hwnd) {
     // Níveis de recursos desejados
     D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 };
     D3D_FEATURE_LEVEL featureLevel; // Para armazenar o nível de recurso obtido

     // Descrição da troca de buffer
     DXGI_SWAP_CHAIN_DESC swapChainDesc = {};  // Inicializa a estrutura de descrição
     swapChainDesc.BufferCount = 1;  // Número de buffers na troca
     swapChainDesc.BufferDesc.Width = 800;  // Largura do buffer
     swapChainDesc.BufferDesc.Height = 600;  // Altura do buffer
     swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;  // Formato de cor
     swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;  // Uso do buffer
     swapChainDesc.OutputWindow = hwnd;  // Janela de saída
     swapChainDesc.SampleDesc.Count = 1;  // Número de amostras (antialiasing)
     swapChainDesc.Windowed = TRUE;  // Janela em modo normal

     // Criação do dispositivo e da troca de buffers
     HRESULT hr = D3D11CreateDeviceAndSwapChain(
         nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, 
         featureLevels, ARRAYSIZE(featureLevels),  // Parâmetros do driver
         D3D11_SDK_VERSION, &swapChainDesc, nullptr, &g_device, 
         &featureLevel, &g_context  // Versão do SDK e contexto
     );

     // Verifica se a criação do dispositivo foi bem-sucedida
     if (FAILED(hr)) {
         MessageBox(hwnd, "Falha ao criar o dispositivo Direct3D", "Erro", MB_OK);
         return;
     }

     // Criar uma render target view (visão de destino de renderização)
     D3D11_TEXTURE2D_DESC backBufferDesc = {};
     backBufferDesc.Width = 800;
     backBufferDesc.Height = 600;
     backBufferDesc.MipLevels = 1;
     backBufferDesc.ArraySize = 1;
     backBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
     backBufferDesc.SampleDesc.Count = 1;
     backBufferDesc.Usage = D3D11_USAGE_DEFAULT;
     backBufferDesc.BindFlags = D3D11_BIND_RENDER_TARGET;

     ID3D11Texture2D* backBuffer = nullptr;  // Buffer de fundo
     hr = g_device->CreateTexture2D(&backBufferDesc, nullptr, &backBuffer);  // Cria o buffer de textura
     if (SUCCEEDED(hr)) {
         hr = g_device->CreateRenderTargetView(backBuffer, nullptr, &g_renderTargetView);  // Cria a visão de destino
         backBuffer->Release();  // Libera o buffer de fundo
     }

     if (FAILED(hr)) {
         MessageBox(hwnd, "Falha ao criar a visão de destino", "Erro", MB_OK);
         return;
     }

     g_context->OMSetRenderTargets(1, &g_renderTargetView, nullptr);  // Define a visão de destino
    
     // Definir viewport (área de renderização)
     D3D11_VIEWPORT viewport = {};  // Inicializa a estrutura de viewport
     viewport.Width = 800;  // Largura da viewport
     viewport.Height = 600;  // Altura da viewport
     viewport.TopLeftX = 0;  // Coordenada X do canto superior esquerdo
     viewport.TopLeftY = 0;  // Coordenada Y do canto superior esquerdo
     g_context->RSSetViewports(1, &viewport);  // Define a viewport
 }

 // Função de processamento de mensagens da janela
 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
     switch (uMsg) {  // Verifica o tipo de mensagem
         case WM_DESTROY:  // Mensagem de destruição da janela
             PostQuitMessage(0);  // Envia mensagem de saída
             return 0;  // Retorna 0 para indicar que a mensagem foi tratada
         case WM_PAINT:  // Mensagem de pintura da janela
             {
                 // Limpa a tela
                 float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };  // Cor de limpeza (preto)
                 g_context->ClearRenderTargetView(g_renderTargetView, clearColor);  // Limpa a visão de destino

                 // Apresentar o swap chain (se aplicável)
                 // g_swapChain->Present(0, 0); // Somente se o swap chain estiver configurado
             }
             break;  // Sai do switch
     }
     return DefWindowProc(hwnd, uMsg, wParam, lParam);  // Processa mensagens padrão
 }


🚀Conclusão

Agora você tem um projeto básico do DirectX em C++ com comentários detalhados em cada linha. Isso deve ajudar a entender como cada parte do código funciona. No próximo módulo, vamos explorar e explicar os componentes principais do DirectX, como dispositivos, contextos, swap chains, render targets, e como cada um deles contribui para a construção de gráficos 2D e 3D.

Postar um comentário

0 Comentários