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
- 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 };
- 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 }
- 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 }
- 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 }
- 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);
- 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ó:
- Modifica el pixel shader per canviar el color a blau.
- 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.
Curs de Programació DirectX
Mòdul 1: Introducció a DirectX
- Què és DirectX?
- Configuració de l'Entorn de Desenvolupament
- Comprendre l'API de DirectX
- Crear la Teva Primera Aplicació DirectX
Mòdul 2: Conceptes Bàsics de Direct3D
- Introducció a Direct3D
- Inicialitzar Direct3D
- Renderitzar un Triangle
- Gestionar el Bucle de Renderització
Mòdul 3: Treballar amb Shaders
Mòdul 4: Tècniques Avançades de Renderització
Mòdul 5: Models 3D i Animació
Mòdul 6: Optimització del Rendiment
- Perfilat i Depuració
- Optimitzar el Rendiment de la Renderització
- Gestió de Memòria
- Multifil en DirectX