Representación desde búferes de vértices e índices (Direct3D 9)

Direct3D admite los métodos de dibujo indizado y no indexado. Los métodos indexados usan un único conjunto de índices para todos los componentes de vértice. Los datos de vértice se almacenan en búferes de vértices y los datos de índice se almacenan en búferes de índice. A continuación se enumeran algunos escenarios comunes para dibujar primitivos mediante búferes de vértices e índices.

Estos ejemplos comparan el uso de IDirect3DDevice9::D rawPrimitive e IDirect3DDevice9::D rawIndexedPrimitive

Escenario 1: Dibujar dos triángulos sin indexación

Supongamos que quiere dibujar el cuadrante que se muestra en la ilustración siguiente.

ilustración de un cuadrado que consta de dos triángulos

Si usa el tipo primitivo Lista de triángulos para representar los dos triángulos, cada triángulo se almacenará como 3 vértices individuales, lo que dará como resultado un búfer de vértices similar a la ilustración siguiente.

diagrama de un búfer de vértices que define tres vértices para dos triángulos

La llamada de dibujo es muy sencilla; comenzando en la ubicación 0 dentro del búfer de vértices, dibuje dos triángulos. Si se habilita la selección, el orden de los vértices será importante. En este ejemplo se da por supuesto el estado predeterminado de selección en sentido contrario a las agujas del reloj, por lo que los triángulos visibles deben dibujarse en orden en el sentido de las agujas del reloj. El tipo primitivo Lista de triángulos simplemente lee tres vértices en orden lineal del búfer para cada triángulo, por lo que esta llamada dibujará triángulos (0, 1, 2) y (3, 4, 5):

DrawPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
               0,                  // StartVertex
               2 );                // PrimitiveCount

Escenario 2: Dibujar dos triángulos con indexación

Como observará, el búfer de vértices contiene datos duplicados en las ubicaciones 0 y 4, 2 y 5. Eso tiene sentido porque los dos triángulos comparten dos vértices comunes. Estos datos duplicados son inútiles y el búfer de vértices se puede comprimir mediante un búfer de índice. Un búfer de vértices más pequeño reduce la cantidad de datos de vértices que se deben enviar al adaptador de gráficos. Aún más importante, el uso de un búfer de índice permite al adaptador almacenar vértices en una caché de vértices; Si el primitivo que se dibuja contiene un vértice usado recientemente, ese vértice se puede capturar desde la memoria caché en lugar de leerlo desde el búfer de vértices, lo que da como resultado un gran aumento del rendimiento.

Un búfer de índice "índices" en el búfer de vértices, por lo que cada vértice único debe almacenarse solo una vez en el búfer de vértices. En el diagrama siguiente se muestra un enfoque indizado para el escenario de dibujo anterior.

diagrama de un búfer de índice para el búfer de vértices anterior

El búfer de índices almacena valores de índice de VB, que hacen referencia a un vértice determinado dentro del búfer de vértices. Un búfer de vértices se puede considerar como una matriz de vértices, por lo que vb Index es simplemente el índice en el búfer de vértices para el vértice de destino. Del mismo modo, un índice IB es un índice en el búfer de índices. Esto puede resultar muy confuso muy rápidamente si no tiene cuidado, así que asegúrese de que está claro en el vocabulario que se está usando: ÍNDICE de valores de índice de VB en el búfer de vértices, índice de valores de índice IB en el búfer de índice y el propio búfer de índices almacena valores de VB Index.

A continuación se muestra la llamada de dibujo. Los significados de todos los argumentos se tratan en longitud para el siguiente escenario de dibujo; por ahora, simplemente tenga en cuenta que esta llamada vuelve a indicar a Direct3D que represente una lista de triángulos que contenga dos triángulos, empezando por la ubicación 0 dentro del búfer de índice. Esta llamada dibujará los mismos dos triángulos exactamente en el mismo orden que antes, lo que garantiza una orientación correcta en el sentido de las agujas del reloj:

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    0,                  // StartIndex
                    2 );                // PrimitiveCount

Escenario 3: Dibujar un triángulo con indexación

Finga ahora que solo quieres dibujar el segundo triángulo, pero quieres usar el mismo búfer de vértices y búfer de índice que se usan al dibujar todo el cuadrángulo, como se muestra en el diagrama siguiente.

diagrama del búfer de índice y del búfer de vértices para el segundo triángulo

Para esta llamada de dibujo, el primer índice ib utilizado es 3; este valor se denomina StartIndex. El índice vb más bajo utilizado es 0; este valor se denomina MinIndex. Aunque solo se requieren tres vértices para dibujar el triángulo, esos tres vértices se distribuyen entre cuatro ubicaciones adyacentes en el búfer de vértices; El número de ubicaciones dentro del bloque contiguo de memoria del búfer de vértices necesaria para la llamada de dibujo se denomina NumVertices y se establecerá en 4 en esta llamada. Los valores MinIndex y NumVertices son simplemente sugerencias para ayudar a Direct3D a optimizar el acceso a la memoria durante el procesamiento de vértices de software y simplemente se podría establecer para incluir todo el búfer de vértices al precio del rendimiento.

Esta es la llamada de dibujo para el caso de triángulo único; El significado del argumento BaseVertexIndex se explicará a continuación:

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount

Escenario 4: Dibujar un triángulo con indexación de desplazamiento

BaseVertexIndex es un valor que se agrega eficazmente a todos los índices de VB almacenados en el búfer de índices. Por ejemplo, si se hubiera pasado un valor de 50 para BaseVertexIndex durante la llamada anterior, eso sería funcionalmente el mismo que usar el búfer de índice en el diagrama siguiente durante la llamada a DrawIndexedPrimitive:

diagrama de un búfer de índice con un valor de 50 para basevertexindex

Este valor rara vez se establece en algo distinto de 0, pero puede ser útil si desea desacoplar el búfer de índice del búfer de vértices: si al rellenar el búfer de índice para una malla determinada, la ubicación de la malla dentro del búfer de vértices aún no se conoce, puede simplemente fingir que los vértices de malla se ubicarán al principio del búfer de vértices; cuando llegue el momento de realizar la llamada a Draw, simplemente pase la ubicación inicial real como BaseVertexIndex.

Esta técnica también se puede usar al dibujar varias instancias de una malla mediante un único búfer de índice; por ejemplo, si el búfer de vértices contenía dos mallas con un orden de dibujo idéntico pero vértices ligeramente diferentes (quizás diferentes colores difusos o coordenadas de textura), ambas mallas podrían dibujarse mediante valores diferentes para BaseVertexIndex. Tomando este concepto un paso más allá, podría usar un búfer de índice para dibujar varias instancias de una malla, cada una contenida en un búfer de vértices diferente, simplemente mediante el ciclo del búfer de vértices que está activo y ajustando BaseVertexIndex según sea necesario. Tenga en cuenta que el valor BaseVertexIndex también se agrega automáticamente al argumento MinIndex, lo que tiene sentido cuando se ve cómo se usa:

Finga ahora que de nuevo queremos dibujar solo el segundo triángulo del cuadrante usando el mismo búfer de índice que antes; sin embargo, se usa un búfer de vértices diferente en el que el cuadráculo se encuentra en VB Index 50. El orden relativo de los vértices cuadráticos permanece sin cambios, solo la ubicación inicial dentro del búfer de vértices es diferente. El búfer de índices y el búfer de vértices tendrían el siguiente aspecto.

diagrama del búfer de índices y del búfer de vértices con un índice vb de 50

Esta es la llamada de dibujo adecuada; Tenga en cuenta que BaseVertexIndex es el único valor que ha cambiado del escenario anterior:

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    50,                 // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount

Representación de primitivos