En aquest tema, aprendrem a carregar models 3D en una aplicació DirectX. Els models 3D són essencials per a la creació de jocs i aplicacions gràfiques, ja que representen objectes complexos en un espai tridimensional. Aquest mòdul cobrirà els conceptes bàsics de la càrrega de models, incloent-hi els formats de fitxer comuns, les tècniques de càrrega i la integració dels models en una escena DirectX.

Objectius del Tema

  • Comprendre els formats de fitxer de models 3D més comuns.
  • Aprendre a carregar models 3D en una aplicació DirectX.
  • Integrar models 3D en una escena DirectX.

Formats de Fitxer de Models 3D

Abans de carregar un model 3D, és important conèixer els formats de fitxer més comuns utilitzats per emmagatzemar models 3D. A continuació es presenten alguns dels formats més populars:

Format Descripció
.obj Un format de fitxer simple i àmpliament utilitzat que emmagatzema la geometria del model.
.fbx Un format de fitxer complex que pot emmagatzemar geometria, materials, animacions i altres dades.
.dae Un format basat en XML que pot emmagatzemar geometria, materials i animacions.
.3ds Un format de fitxer antic però encara utilitzat en moltes aplicacions.

Carregar un Model 3D en DirectX

Per carregar un model 3D en DirectX, seguirem els passos següents:

  1. Preparar el Model 3D: Assegura't que el model estigui en un format compatible i que tingui les textures i materials necessaris.
  2. Llegir el Fitxer del Model: Utilitza una biblioteca o escriu codi per llegir el fitxer del model i extreure'n la informació necessària.
  3. Crear Buffers de Vertex i Índex: Utilitza la informació del model per crear buffers de vertex i índex en DirectX.
  4. Renderitzar el Model: Utilitza els shaders i el pipeline de renderització de DirectX per dibuixar el model a la pantalla.

Exemple Pràctic: Carregar un Model .obj

A continuació, es mostra un exemple pràctic de com carregar un model .obj en una aplicació DirectX.

Pas 1: Preparar el Model .obj

Assegura't que tens un fitxer .obj i les seves textures associades. Per a aquest exemple, utilitzarem un model simple de cub.

Pas 2: Llegir el Fitxer .obj

Utilitzarem una biblioteca de tercers, com ara tinyobjloader, per llegir el fitxer .obj. Afegeix la biblioteca al teu projecte i utilitza el següent codi per carregar el model:

#include "tiny_obj_loader.h"
#include <vector>
#include <string>

struct Vertex {
    DirectX::XMFLOAT3 position;
    DirectX::XMFLOAT3 normal;
    DirectX::XMFLOAT2 texcoord;
};

std::vector<Vertex> vertices;
std::vector<uint32_t> indices;

bool LoadOBJ(const std::string& filename) {
    tinyobj::attrib_t attrib;
    std::vector<tinyobj::shape_t> shapes;
    std::vector<tinyobj::material_t> materials;
    std::string warn, err;

    if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filename.c_str())) {
        std::cerr << warn << err << std::endl;
        return false;
    }

    for (const auto& shape : shapes) {
        for (const auto& index : shape.mesh.indices) {
            Vertex vertex = {};
            vertex.position = {
                attrib.vertices[3 * index.vertex_index + 0],
                attrib.vertices[3 * index.vertex_index + 1],
                attrib.vertices[3 * index.vertex_index + 2]
            };
            vertex.normal = {
                attrib.normals[3 * index.normal_index + 0],
                attrib.normals[3 * index.normal_index + 1],
                attrib.normals[3 * index.normal_index + 2]
            };
            vertex.texcoord = {
                attrib.texcoords[2 * index.texcoord_index + 0],
                attrib.texcoords[2 * index.texcoord_index + 1]
            };
            vertices.push_back(vertex);
            indices.push_back(indices.size());
        }
    }

    return true;
}

Pas 3: Crear Buffers de Vertex i Índex

Un cop carregat el model, crearem els buffers de vertex i índex en DirectX:

ID3D11Buffer* vertexBuffer = nullptr;
ID3D11Buffer* indexBuffer = nullptr;

void CreateBuffers(ID3D11Device* device) {
    D3D11_BUFFER_DESC vertexBufferDesc = {};
    vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    vertexBufferDesc.ByteWidth = sizeof(Vertex) * vertices.size();
    vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vertexBufferDesc.CPUAccessFlags = 0;

    D3D11_SUBRESOURCE_DATA vertexData = {};
    vertexData.pSysMem = vertices.data();

    device->CreateBuffer(&vertexBufferDesc, &vertexData, &vertexBuffer);

    D3D11_BUFFER_DESC indexBufferDesc = {};
    indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    indexBufferDesc.ByteWidth = sizeof(uint32_t) * indices.size();
    indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    indexBufferDesc.CPUAccessFlags = 0;

    D3D11_SUBRESOURCE_DATA indexData = {};
    indexData.pSysMem = indices.data();

    device->CreateBuffer(&indexBufferDesc, &indexData, &indexBuffer);
}

Pas 4: Renderitzar el Model

Finalment, renderitzarem el model utilitzant els shaders i el pipeline de renderització de DirectX:

void Render(ID3D11DeviceContext* context) {
    UINT stride = sizeof(Vertex);
    UINT offset = 0;
    context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
    context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
    context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    // Configura els shaders i altres estats de renderització aquí

    context->DrawIndexed(indices.size(), 0, 0);
}

Exercici Pràctic

Exercici 1: Carregar i Renderitzar un Model .obj

  1. Troba un model .obj simple en línia o crea'n un amb un programari de modelatge 3D.
  2. Utilitza el codi proporcionat per carregar el model en la teva aplicació DirectX.
  3. Renderitza el model a la pantalla.
  4. Experimenta amb diferents models i textures per veure com es representen en la teva aplicació.

Solució de l'Exercici

La solució de l'exercici es troba en el codi proporcionat anteriorment. Assegura't de seguir els passos i adaptar el codi a les teves necessitats específiques.

Conclusió

En aquest tema, hem après a carregar models 3D en una aplicació DirectX. Hem explorat els formats de fitxer més comuns, hem utilitzat una biblioteca de tercers per llegir un fitxer .obj i hem creat buffers de vertex i índex per renderitzar el model. Aquestes habilitats són fonamentals per a la creació de jocs i aplicacions gràfiques complexes. En el proper tema, explorarem com animar models 3D per donar vida als nostres objectes tridimensionals.

© Copyright 2024. Tots els drets reservats