En aquest tema, aprendrem a renderitzar un triangle utilitzant Direct3D. Aquest és un pas fonamental en la programació gràfica, ja que els triangles són les primitives bàsiques utilitzades per construir models 3D més complexos.

Objectius

  • Comprendre com definir i carregar geometria de triangles.
  • Aprendre a configurar els buffers necessaris per a la renderització.
  • Escriure i utilitzar shaders bàsics per renderitzar el triangle.
  • Renderitzar el triangle a la pantalla.

Passos per Renderitzar un Triangle

  1. Definir la Geometria del Triangle

Primer, hem de definir els vèrtexs del triangle. Cada vèrtex tindrà una posició en l'espai 3D.

struct Vertex {
    float x, y, z; // Posició del vèrtex
};

// Definim els tres vèrtexs del triangle
Vertex vertices[] = {
    { 0.0f,  0.5f, 0.0f }, // Vèrtex superior
    { 0.5f, -0.5f, 0.0f }, // Vèrtex inferior dret
    {-0.5f, -0.5f, 0.0f }  // Vèrtex inferior esquerre
};

  1. Crear i Configurar els Buffers

Necessitem crear un buffer de vèrtexs per emmagatzemar la informació dels vèrtexs i enviar-la a la GPU.

// Descripció del buffer de vèrtexs
D3D11_BUFFER_DESC bufferDesc = {};
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof(vertices);
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;

// Dades del subrecurs
D3D11_SUBRESOURCE_DATA initData = {};
initData.pSysMem = vertices;

// Creació del buffer de vèrtexs
ID3D11Buffer* vertexBuffer;
HRESULT hr = device->CreateBuffer(&bufferDesc, &initData, &vertexBuffer);
if (FAILED(hr)) {
    // Manejar l'error
}

  1. Escriure Shaders Bàsics

Els shaders són programes que s'executen a la GPU per processar els vèrtexs i els píxels. Necessitem un vertex shader i un pixel shader.

Vertex Shader (HLSL):

cbuffer ConstantBuffer : register(b0) {
    matrix worldViewProj;
};

struct VS_INPUT {
    float3 pos : POSITION;
};

struct PS_INPUT {
    float4 pos : SV_POSITION;
};

PS_INPUT VS(VS_INPUT input) {
    PS_INPUT output;
    output.pos = mul(float4(input.pos, 1.0f), worldViewProj);
    return output;
}

Pixel Shader (HLSL):

struct PS_INPUT {
    float4 pos : SV_POSITION;
};

float4 PS(PS_INPUT input) : SV_Target {
    return float4(1.0f, 0.0f, 0.0f, 1.0f); // Color vermell
}

  1. Compilar i Carregar els Shaders

Compilarem els shaders i els carregarem a la GPU.

ID3DBlob* vsBlob = nullptr;
ID3DBlob* psBlob = nullptr;
ID3DBlob* errorBlob = nullptr;

// Compilar el vertex shader
hr = D3DCompileFromFile(L"VertexShader.hlsl", nullptr, nullptr, "VS", "vs_5_0", 0, 0, &vsBlob, &errorBlob);
if (FAILED(hr)) {
    // Manejar l'error
}

// Compilar el pixel shader
hr = D3DCompileFromFile(L"PixelShader.hlsl", nullptr, nullptr, "PS", "ps_5_0", 0, 0, &psBlob, &errorBlob);
if (FAILED(hr)) {
    // Manejar l'error
}

// Crear el vertex shader
ID3D11VertexShader* vertexShader;
hr = device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &vertexShader);
if (FAILED(hr)) {
    // Manejar l'error
}

// Crear el pixel shader
ID3D11PixelShader* pixelShader;
hr = device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &pixelShader);
if (FAILED(hr)) {
    // Manejar l'error
}

  1. Configurar el Pipeline de Renderització

Configurarem el pipeline de renderització per utilitzar els shaders i el buffer de vèrtexs.

// Configurar el buffer de vèrtexs
UINT stride = sizeof(Vertex);
UINT offset = 0;
context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);

// Configurar la topologia de la primitiva
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

// Configurar els shaders
context->VSSetShader(vertexShader, nullptr, 0);
context->PSSetShader(pixelShader, nullptr, 0);

  1. Renderitzar el Triangle

Finalment, renderitzarem el triangle.

// Netejar el render target
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; // Color negre
context->ClearRenderTargetView(renderTargetView, clearColor);

// Dibuixar el triangle
context->Draw(3, 0);

// Intercanviar els buffers
swapChain->Present(1, 0);

Exercici Pràctic

Exercici: Modifica el color del triangle a blau i canvia la posició dels vèrtexs per formar un triangle invertit.

Solució:

  1. Modifica el pixel shader per canviar el color a blau.
float4 PS(PS_INPUT input) : SV_Target {
    return float4(0.0f, 0.0f, 1.0f, 1.0f); // Color blau
}
  1. Canvia la definició dels vèrtexs per formar un triangle invertit.
Vertex vertices[] = {
    { 0.0f, -0.5f, 0.0f }, // Vèrtex inferior
    { 0.5f,  0.5f, 0.0f }, // Vèrtex superior dret
    {-0.5f,  0.5f, 0.0f }  // Vèrtex superior esquerre
};

Conclusió

En aquest tema, hem après a renderitzar un triangle utilitzant Direct3D. Hem cobert la definició de la geometria, la creació de buffers, l'escriptura de shaders, la configuració del pipeline de renderització i la renderització del triangle. Aquest coneixement és fonamental per a la creació de gràfics 3D més complexos en el futur.

© Copyright 2024. Tots els drets reservats