Introdução à Preparação do Assembler de Entrada

Existem algumas etapas necessárias para inicializar a preparação do assembler de entrada (IA). Por exemplo, você precisa criar recursos de buffer com os dados de vértice que o pipeline precisa, informar à preparação do AI em que os buffers estão e que tipo de dados eles contêm e especificar o tipo de primitivos a serem montados a partir dos dados.

As etapas básicas envolvidas na configuração da preparação do AI, mostradas na tabela a seguir, são abordadas neste tópico.

Etapa Descrição
Criar Buffers de Entrada Cria e inicializa buffers de entrada com dados de vértice de entrada.
Criar o Objeto de Layout de Entrada Define como os dados do buffer de vértice serão transmitidos para a preparação do AI usando um objeto de layout de entrada.
Associar objetos à Preparação do Assembler de Entrada Associe os objetos criados (buffers de entrada e o objeto de layout de entrada) à preparação do AI.
Especificar o Tipo Primitivo Identifica como os vértices serão montados em primitivos.
Chamada de Métodos de Desenho Envia os dados associados à preparação do AI através do pipeline.

 

Após entender essas etapas, mova-se para Usando Valores Gerados pelo Sistema.

Criar buffers de entrada

Existem dois tipos de buffers de entrada: buffers de vértice e buffers de índice. Os buffers de vértice fornecem dados de vértice para a fase IA. Os buffers de índice são opcionais; eles fornecem índices para os vértices do buffer de vértice. Você pode criar um ou mais buffers de vértice e, opcionalmente, um buffer de índice.

Após a criação dos recursos de buffer, é necessário criar um objeto de layout de entrada para descrever o layout de dados para a preparação do AI e, em seguida, associar os recursos de buffer à preparação do AI. Criar e associar buffers não é necessário se seus sombreadores não usarem buffers. Para obter um exemplo de um sombreador simples de vértice e pixel que desenha um único triângulo, confira Usando a Preparação do Assembler de Entrada sem buffers.

Para ajudar na criação de um buffer de vértices, confira Como fazer para: criar um buffer de vértice. Para ajudar na criação de um buffer de índice, confira Como fazer para: criar um buffer de índice.

Criar o objeto do Layout de Entrada

O objeto layout de entrada encapsula o estado de entrada da preparação do AI. Isso inclui uma descrição dos dados de entrada que estão associados à preparação do AI. Os dados são transmitidos para a preparação do AI a partir da memória, de um ou mais buffers de vértice. A descrição identifica os dados de entrada que são associados a um ou mais buffers de vértice e fornece ao runtime a capacidade de verificar os tipos de dados de entrada em relação aos tipos de parâmetros de entrada do sombreador. Essa verificação de tipo não apenas verifica se os tipos são compatíveis, mas também se cada um dos elementos necessários ao sombreador está disponível nos recursos do buffer.

Um objeto de layout de entrada é criado a partir de uma matriz de descrições de elementos de entrada e um ponteiro para o sombreador compilado (consulte ID3D11Device::CreateInputLayout). A matriz contém um ou mais elementos de entrada; cada elemento de entrada descreve um único elemento de dados de vértice de um único buffer de vértice. O conjunto inteiro de descrições de elementos de entrada descreve todos os elementos de dados de vértice de todos os buffers de vértice que serão vinculados ao estágio IA.

A descrição do layout a seguir descreve um buffer de vértice único que contém três elementos de dados de vértice:

D3D11_INPUT_ELEMENT_DESC layout[] =
{
    { L"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, 
          D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { L"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, 
          D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { L"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, 
          D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

Uma descrição do elemento de entrada descreve cada elemento contido em um único vértice em um buffer de vértice, incluindo tamanho, tipo, localização e finalidade. Cada linha identifica o tipo de dados usando a semântica, o índice semântico e o formato dos dados. Uma semântica é uma cadeia de caracteres de texto que identifica como os dados serão utilizados. Neste exemplo, a primeira linha identifica os dados da posição de 3 componentes (xyz, por exemplo); a segunda linha identifica os dados de textura de 2 componentes (UV, por exemplo); e a terceira linha identifica os dados normais.

Neste exemplo de descrição de um elemento de entrada, o índice semântico (que é o segundo parâmetro) está definido como zero para todas as três linhas. O índice semântico ajuda a distinguir entre duas linhas que usam a mesma semântica. Como não existem semânticas semelhantes neste exemplo, o índice semântico pode ser definido como seu valor padrão, zero.

O terceiro parâmetro é o formato. O formato (consulte DXGI_FORMAT) especifica o número de componentes por elemento e o tipo de dados, que define o tamanho dos dados de cada elemento. O formato pode ser totalmente digitado no momento da criação do recurso ou você pode criar um recurso usando um DXGI_FORMAT, que identifica o número de componentes em um elemento, mas deixa o tipo de dados indefinido.

Slots de entrada

Os dados são inseridos na preparação do AI através de entradas chamadas slots de entrada, conforme mostrado na ilustração a seguir. A preparação do AI tem n slots de entrada, projetados para acomodar até n buffers de vértice que fornecem dados de entrada. Cada buffer de vértice deve ser atribuído a um slot diferente; essa informação é armazenada na declaração do layout de entrada quando o objeto de layout de entrada é criado. Você também pode especificar um deslocamento do início de cada buffer para o primeiro elemento do buffer que será lido.

illustration of the input slots for the ia stage

Os dois parâmetros seguintes são o slot de entrada e o deslocamento de entrada. Ao usar vários buffers, você pode associá-los a um ou mais slots de entrada. O deslocamento de entrada é o número de bytes entre o início do buffer e o início dos dados.

Reutilização de objetos do layout de entrada

Cada objeto de layout de entrada é criado com base em uma assinatura de sombreador; isso permite que a API valide os elementos do objeto de layout de entrada em relação à assinatura de entrada de sombreador para garantir que exista uma correspondência exata de tipos e semântica. Você pode criar um único objeto de layout de entrada para muitos sombreadores, desde que todas as assinaturas de entrada do sombreador correspondam exatamente.

Associação de objetos à Preparação do Assembler de Entrada

Após criar os recursos de buffer de vértice e um objeto de layout de entrada, você pode associá-los à preparação do AI chamando ID3D11DeviceContext::IASetVertexBuffers e ID3D11DeviceContext::IASetInputLayout. O exemplo a seguir mostra a associação de um único buffer de vértice e um objeto de layout de entrada à preparação do AI:

UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pd3dDevice->IASetVertexBuffers( 
    0,                // the first input slot for binding
    1,                // the number of buffers in the array
    &g_pVertexBuffer, // the array of vertex buffers
    &stride,          // array of stride values, one for each buffer
    &offset );        // array of offset values, one for each buffer

// Set the input layout
g_pd3dDevice->IASetInputLayout( g_pVertexLayout );

A associação do objeto layout de entrada requer apenas um ponteiro para o objeto.

No exemplo anterior, um único buffer de vértice é associado; entretanto, vários buffers de vértice podem ser associados por meio de uma única chamada para ID3D11DeviceContext::IASetVertexBuffers, e o código a seguir mostra uma chamada desse tipo para associar três buffers de vértice:

UINT strides[3];
strides[0] = sizeof(SimpleVertex1);
strides[1] = sizeof(SimpleVertex2);
strides[2] = sizeof(SimpleVertex3);
UINT offsets[3] = { 0, 0, 0 };
g_pd3dDevice->IASetVertexBuffers( 
    0,                 //first input slot for binding
    3,                 //number of buffers in the array
    &g_pVertexBuffers, //array of three vertex buffers
    &strides,          //array of stride values, one for each buffer
    &offsets );        //array of offset values, one for each buffer

Um buffer de índice é associado à preparação do AI chamando ID3D11DeviceContext::IASetIndexBuffer.

Especificar o Tipo Primitivo

Após a associação dos buffers de entrada, a preparação do AI de AI deve ser informada sobre como montar os vértices em primitivos. Isso é feito especificando o tipo primitivo chamando ID3D11DeviceContext::IASetPrimitiveTopology; o código a seguir chama essa função para definir os dados como uma lista de triângulos sem adjacência:

g_pd3dDevice->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

O restante dos tipos primitivos está listado em D3D_PRIMITIVE_TOPOLOGY.

Chamada de Métodos de Desenho

Após os recursos de entrada terem sido vinculados ao pipeline, um aplicativo chama um método de desenho para renderizar primitivos. Existem vários métodos de desenho, que são mostrados na tabela a seguir; alguns usam buffers de índice, outros usam dados de instância e outros reutilizam dados da tabela de saída de streaming como entrada para a preparação do assembler de entrada.

Métodos de desenho Descrição
ID3D11DeviceContext::Draw Desenhar primitivos não indexados e não instanciados.
ID3D11DeviceContext::DrawInstanced Desenhar primitivos instanciados e não indexados.
ID3D11DeviceContext::DrawIndexed Desenhar primitivos indexados e não-instanciados.
ID3D11DeviceContext::DrawIndexedInstanced Desenhar primitivos indexados e instanciados.
ID3D11DeviceContext::DrawAuto Desenhe primitivos não indexados e não instanciados a partir de dados de entrada provenientes da fase de saída de streaming.

 

Cada método de desenho renderiza um único tipo de topologia. Durante a renderização, os primitivos incompletos (aqueles sem vértices suficientes, sem índices, primitivos parciais e assim por diante) são silenciosamente descartadas.

Preparação do Assembler de Entrada