Introducción a la fase de ensamblador de entrada

Hay algunos pasos necesarios para inicializar la fase del ensamblador de entrada (IA). Por ejemplo, debe crear recursos de búfer con los datos de vértice que necesita la canalización, indicar a la fase de IA dónde se encuentran los búferes y qué tipo de datos contienen y especificar el tipo de primitivos que se van a ensamblar a partir de los datos.

En este tema, se tratan los pasos básicos implicados en la configuración de la fase de IA, que se muestran en la siguiente tabla.

Paso Descripción
Creación de búferes de entrada Cree e inicialice búferes de entrada con datos de vértices de entrada.
Creación del objeto Input-Layout Defina cómo se transmitirán los datos del búfer de vértices a la fase de IA mediante un objeto de diseño de entrada.
Enlace de objetos a la fase del ensamblador de entrada Enlace los objetos creados (búferes de entrada y el objeto de diseño de entrada) a la fase de IA.
Especificar el tipo primitivo Identifique cómo se ensamblarán los vértices en primitivos.
Llamada a métodos draw Envíe los datos enlazados a la fase de IA a través de la canalización.

 

Después de comprender estos pasos, vaya a Uso de valores generados por el sistema.

Creación de búferes de entrada

Hay dos tipos de búferes de entrada: búferes de vértices y búferes de índice. Los búferes de vértices proporcionan datos de vértices a la fase de IA. Los búferes de índice son opcionales; proporcionan índices a vértices del búfer de vértices. Puede crear uno o varios búferes de vértices y, si lo desea, un búfer de índice.

Después de crear los recursos de búfer, debe crear un objeto de diseño de entrada para describir el diseño de datos en la fase de IA y, a continuación, debe enlazar los recursos de búfer a la fase de IA. No es necesario crear y enlazar búferes si los sombreadores no usan búferes. Para obtener un ejemplo de un sombreador de vértices y píxeles sencillo que dibuja un único triángulo, consulte Uso de la fase del ensamblador de entrada sin búferes.

Para obtener ayuda con la creación de un búfer de vértices, consulte Procedimientos: creación de un búfer de vértices. Para obtener ayuda con la creación de un búfer de índice, consulte Procedimiento: cómo crear un búfer de índice.

Creación del objeto Input-Layout

El objeto de diseño de entrada encapsula el estado de entrada de la fase (IA). Esto incluye una descripción de los datos de entrada enlazados a la fase de IA. Los datos se transmiten a la fase de IA desde la memoria, desde uno o varios búferes de vértices. La descripción identifica los datos de entrada enlazados desde uno o varios búferes de vértices y proporciona al tiempo de ejecución la capacidad de comprobar los tipos de datos de entrada en los tipos de parámetros de entrada del sombreador. Esta comprobación de tipos no solo comprueba que los tipos son compatibles, sino también que cada uno de los elementos que requiere el sombreador está disponible en los recursos del búfer.

Un objeto de diseño de entrada se crea a partir de una matriz de descripciones de elementos de entrada y un puntero al sombreador compilado (consulte ID3D11Device::CreateInputLayout). La matriz contiene uno o varios elementos de entrada; cada elemento de entrada describe un único elemento de datos de vértices de un solo búfer de vértices. El conjunto completo de descripciones de elementos de entrada describe todos los elementos de datos de vértices de todos los búferes de vértices que se enlazarán a la fase ia.

En la descripción del diseño siguiente se describe un único búfer de vértices que contiene tres elementos de datos de vértices:

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 },
};

Una descripción de elemento de entrada describe cada elemento contenido por un único vértice en un búfer de vértices, incluido el tamaño, el tipo, la ubicación y el propósito. Cada fila identifica el tipo de datos mediante la semántica, el índice semántico y el formato de datos. Una semántica es una cadena de texto que identifica cómo se usarán los datos. En este ejemplo, la primera fila identifica los datos de posición de 3 componentes (xyz, por ejemplo); la segunda fila identifica los datos de textura de 2 componentes (UV, por ejemplo); y la tercera fila identifica los datos normales.

En este ejemplo de una descripción de elemento de entrada, el índice semántico (que es el segundo parámetro) se establece en cero para las tres filas. El índice semántico ayuda a distinguir entre dos filas que usan la misma semántica. Dado que no hay semántica similar en este ejemplo, el índice semántico se puede establecer en su valor predeterminado, cero.

El tercer parámetro es el formato. El formato (consulte DXGI_FORMAT) especifica el número de componentes por elemento y el tipo de datos, que define el tamaño de los datos para cada elemento. El formato se puede escribir completamente en el momento de la creación de recursos o puede crear un recurso mediante un DXGI_FORMAT, que identifica el número de componentes de un elemento, pero deja el tipo de datos sin definir.

Ranuras de entrada

Los datos entran en la fase de IA a través de entradas denominadas ranuras de entrada, como se muestra en la siguiente lustración . La fase IA tiene n ranuras de entrada, diseñadas para acomodar hasta n búferes de vértices que proporcionan datos de entrada. Cada búfer de vértices debe asignarse a una ranura diferente; esta información se almacena en la declaración input-layout cuando se crea el objeto input-layout. También puede especificar un desplazamiento desde el inicio de cada búfer hasta el primer elemento del búfer que se va a leer.

illustration of the input slots for the ia stage

Los dos parámetros siguientes son ranuras de entrada y offset de entrada. Al usar varios búferes, puede enlazarlos a una o varias ranuras de entrada. El offset de entrada es el número de bytes entre el inicio del búfer y el principio de los datos.

Reutilización de objetos de diseño de entrada

Cada objeto de diseño de entrada se crea en función de una firma de sombreador; esto permite a la API validar los elementos input-layout-object en la firma de entrada del sombreador para asegurarse de que hay una coincidencia exacta de tipos y semántica. Puede crear un único objeto de diseño de entrada para muchos sombreadores, siempre que todas las firmas de entrada del sombreador coincidan exactamente.

Enlace de objetos a la fase del ensamblador de entrada

Después de crear recursos de búfer de vértices y un objeto de diseño de entrada, puede enlazarlos a la fase de IA llamando a ID3D11DeviceContext::IASetVertexBuffers y ID3D11DeviceContext::IASetInputLayout. En el siguiente ejemplo se muestra el enlace de un único búfer de vértices y un objeto de diseño de entrada a la fase de IA:

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 );

Enlazar el objeto de diseño de entrada solo requiere un puntero al objeto .

En el ejemplo anterior, se enlaza un único búfer de vértices; sin embargo, varios búferes de vértices se pueden enlazar mediante una sola llamada a ID3D11DeviceContext::IASetVertexBuffers y el código siguiente muestra dicha llamada para enlazar tres búferes de vértices:

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

Un búfer de índice se enlaza a la fase de IA llamando a ID3D11DeviceContext::IASetIndexBuffer.

Especificar el tipo primitivo

Una vez enlazados los búferes de entrada, se debe indicar a la fase IA cómo ensamblar los vértices en primitivos. Para ello, se especifica el tipo primitivo llamando a ID3D11DeviceContext::IASetPrimitiveTopology el código siguiente llama a esta función para definir los datos como una lista de triángulos sin adyacencia:

g_pd3dDevice->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

El resto de los tipos primitivos se enumeran en D3D_PRIMITIVE_TOPOLOGY.

Llamada a métodos draw

Una vez enlazados los recursos de entrada a la canalización, una aplicación llama a un método draw para representar primitivos. Hay varios métodos de dibujo, que se muestran en la siguiente tabla; algunos usan búferes de índice, algunos usan datos de instancia y algunos reutilizan datos de la fase de salida de streaming como entrada en la fase del ensamblador de entrada.

Métodos Draw Descripción
ID3D11DeviceContext::Draw Dibujos primitivos no indexados y sin instancias.
ID3D11DeviceContext::DrawInstanced Dibujos no indexados e instancias primitivas.
ID3D11DeviceContext::DrawIndexed Dibujos primitivos indexados y sin instancias.
ID3D11DeviceContext::DrawIndexedInstanced Dibujos indexados e instancias primitivas.
ID3D11DeviceContext::DrawAuto Dibuje primitivos no indexados y no con instancias de los datos de entrada que proceden de la fase de salida de streaming.

 

Cada método draw representa un único tipo de topología. Durante la representación, los primitivos incompletos (aquellos sin suficientes vértices, faltan índices, primitivos parciales, etc.) se descartan silenciosamente.

Fase del ensamblador de entrada