En esta sección, aprenderemos cómo inicializar Direct3D, que es una de las partes más importantes para comenzar a trabajar con gráficos en DirectX. La inicialización de Direct3D implica configurar varios componentes esenciales que permitirán a nuestra aplicación renderizar gráficos en la pantalla.

Objetivos de Aprendizaje

  • Comprender los componentes básicos necesarios para inicializar Direct3D.
  • Configurar una ventana para renderizar gráficos.
  • Crear y configurar un dispositivo Direct3D.
  • Configurar el contexto de renderizado.

Pasos para Inicializar Direct3D

  1. Configuración de la Ventana

Antes de inicializar Direct3D, necesitamos una ventana donde se renderizarán nuestros gráficos. Aquí hay un ejemplo de cómo crear una ventana básica en una aplicación de Windows:

#include <windows.h>

// Prototipos de funciones
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

// Punto de entrada de la aplicación
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // Estructura de la ventana
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = "WindowClass";

    // Registro de la ventana
    RegisterClassEx(&wc);

    // Creación de la ventana
    HWND hwnd = CreateWindowEx(0, "WindowClass", "Direct3D Window", WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, NULL, NULL, hInstance, NULL);

    // Mostrar la ventana
    ShowWindow(hwnd, nCmdShow);

    // Bucle de mensajes
    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

// Procedimiento de la ventana
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

  1. Creación del Dispositivo Direct3D y el Contexto de Renderizado

Una vez que tenemos una ventana, podemos proceder a crear el dispositivo Direct3D y el contexto de renderizado. Aquí está el código para hacerlo:

#include <d3d11.h>
#pragma comment (lib, "d3d11.lib")

// Variables globales
IDXGISwapChain *swapChain;
ID3D11Device *dev;
ID3D11DeviceContext *devcon;
ID3D11RenderTargetView *backbuffer;

// Función para inicializar Direct3D
void InitD3D(HWND hwnd) {
    // Estructura de la cadena de intercambio
    DXGI_SWAP_CHAIN_DESC scd = {0};
    scd.BufferCount = 1;
    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    scd.OutputWindow = hwnd;
    scd.SampleDesc.Count = 4;
    scd.Windowed = TRUE;

    // Creación del dispositivo, contexto y cadena de intercambio
    D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &scd, &swapChain, &dev, NULL, &devcon);

    // Obtener el buffer de la cadena de intercambio
    ID3D11Texture2D *pBackBuffer;
    swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);

    // Crear la vista de renderizado
    dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
    pBackBuffer->Release();

    // Configurar el contexto de renderizado
    devcon->OMSetRenderTargets(1, &backbuffer, NULL);

    // Configurar el viewport
    D3D11_VIEWPORT viewport = {0};
    viewport.TopLeftX = 0;
    viewport.TopLeftY = 0;
    viewport.Width = 800;
    viewport.Height = 600;
    devcon->RSSetViewports(1, &viewport);
}

  1. Integración de la Inicialización en la Aplicación

Ahora, integramos la función InitD3D en nuestra aplicación principal:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // Estructura de la ventana
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = "WindowClass";

    // Registro de la ventana
    RegisterClassEx(&wc);

    // Creación de la ventana
    HWND hwnd = CreateWindowEx(0, "WindowClass", "Direct3D Window", WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, NULL, NULL, hInstance, NULL);

    // Inicializar Direct3D
    InitD3D(hwnd);

    // Mostrar la ventana
    ShowWindow(hwnd, nCmdShow);

    // Bucle de mensajes
    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

  1. Limpieza de Direct3D

Es importante liberar los recursos de Direct3D cuando la aplicación se cierra. Aquí está cómo hacerlo:

void CleanD3D() {
    swapChain->Release();
    backbuffer->Release();
    dev->Release();
    devcon->Release();
}

// Modificar el procedimiento de la ventana para limpiar Direct3D
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_DESTROY:
            CleanD3D();
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Resumen

En esta sección, hemos cubierto los pasos necesarios para inicializar Direct3D:

  1. Configuración de una ventana para renderizar gráficos.
  2. Creación del dispositivo Direct3D y el contexto de renderizado.
  3. Integración de la inicialización en la aplicación principal.
  4. Limpieza de los recursos de Direct3D.

Con estos pasos, tu aplicación está lista para comenzar a renderizar gráficos utilizando Direct3D. En la próxima sección, aprenderemos a renderizar un triángulo en la pantalla, lo que nos permitirá ver los resultados de nuestra inicialización.

© Copyright 2024. Todos los derechos reservados