Búferes de índice (Direct3D 9)

Los búferes de índice, representados por la interfaz IDirect3DIndexBuffer9 , son búferes de memoria que contienen datos de índice. Los datos de índice, o índices, son desplazamientos enteros en búferes de vértices y se usan para representar primitivos mediante el método IDirect3DDevice9::D rawIndexedPrimitive .

Un búfer de vértices contiene vértices; por lo tanto, puede dibujar un búfer de vértices con o sin primitivos indizados. Sin embargo, como un búfer de índices contiene índices, no puede usar un búfer de índices sin un búfer de vértices correspondiente. (Como nota lateral, IDirect3DDevice9::D rawIndexedPrimitiveUP e IDirect3DDevice9::D rawPrimitiveUP son los únicos métodos draw que dibujan sin un índice o un búfer de vértices).

Descripción del búfer de índices

Un búfer de índices se describe en términos de sus funcionalidades, como su ubicación en la memoria, si admite la lectura y escritura y el tipo y la cantidad de índices que puede contener. Estos rasgos se mantienen en una estructura D3DINDEXBUFFER_DESC .

Las descripciones del búfer de índices indican a la aplicación cómo se creó un búfer existente. Debe proporcionar una estructura de descripción vacía para que el sistema la rellene con las capacidades de un búfer de índices creado anteriormente.

  • El miembro Format describe el formato de superficie de los datos del búfer de índice.
  • El tipo identifica el tipo de recurso del búfer de índice.
  • El miembro de estructura Usage contiene marcas de funcionalidad generales. La marca D3DUSAGE_SOFTWAREPROCESSING indica que el búfer de índice se va a usar con el procesamiento de vértices de software. La presencia de la marca D3DUSAGE_WRITEONLY en Uso indica que la memoria del búfer de índice solo se usa para las operaciones de escritura. Esto libera al controlador para colocar los datos de índice en la mejor ubicación de memoria para permitir el procesamiento y la representación rápidos. Si no se usa la marca D3DUSAGE_WRITEONLY, es menos probable que el controlador coloque los datos en una ubicación ineficaz para las operaciones de lectura. Esto sacrifica cierta velocidad de procesamiento y representación. Si no se especifica esta marca, se supone que las aplicaciones realizan operaciones de lectura y escritura en los datos del búfer de índice.
  • Pool especifica la clase de memoria asignada para el búfer de índice. La marca D3DPOOL_SYSTEMMEM indica que el sistema creó el búfer de índice en la memoria del sistema.
  • El miembro Size almacena el tamaño, en bytes, de los datos del búfer de vértices.
  • No se usa el último parámetro pSharedHandle. Establézcalo en NULL.

Requisitos de procesamiento de índices

El rendimiento de las operaciones de procesamiento de índices depende en gran medida de que el búfer de índices exista en la memoria y del tipo de dispositivo de representación que se usa. Las aplicaciones controlan la asignación de memoria para los búferes de índices cuando se crean. Cuando se establece la marca de memoria D3DPOOL_SYSTEMMEM, el búfer de índice se crea en la memoria del sistema. Cuando se usa la marca de memoria D3DPOOL_DEFAULT, el controlador de dispositivo determina dónde se asigna mejor la memoria del búfer de índice, a menudo denominada memoria óptima para el controlador. La memoria óptima del controlador puede ser memoria de vídeo local, memoria de vídeo no local o memoria del sistema.

Al establecer la marca de comportamiento de D3DUSAGE_SOFTWAREPROCESSING al llamar al método IDirect3DDevice9::CreateIndexBuffer , se especifica que el búfer de índice se usará con el procesamiento de vértices de software. Esta marca es necesaria en el procesamiento de vértices en modo mixto (D3DCREATE_MIXED_VERTEXPROCESSING) cuando se usa el procesamiento de vértices de software.

La aplicación puede escribir directamente índices en un búfer de índices asignado en la memoria óptima para el controlador. Esta técnica impide que se haga una operación de copia redundante más adelante. Esta técnica no funciona bien si la aplicación vuelve a leer datos de un búfer de índices, ya que las operaciones de lectura que lleva a cabo el host de la memoria óptima para el controlador pueden ser muy lentas. Por lo tanto, si la aplicación tiene que leer durante el procesamiento o escribe datos en el búfer de forma errática, un búfer de índices de memoria del sistema es una elección mejor.

Nota

Use siempre D3DPOOL_DEFAULT, excepto cuando no quiera usar memoria de vídeo o use grandes cantidades de RAM bloqueadas por páginas cuando el controlador coloca búferes de vértices o índices en memoria AGP.

 

Crear un búfer de índice

Cree un objeto de búfer de índice llamando al método IDirect3DDevice9::CreateIndexBuffer , que acepta seis parámetros.

  • El primer parámetro especifica la longitud del búfer de índice, en bytes.

  • El segundo parámetro es un conjunto de controles de uso. Entre otras cosas, su valor determina si los vértices a los que hacen referencia los índices pueden contener información de recorte. Para mejorar el rendimiento, especifique D3DUSAGE_DONOTCLIP cuando no se requiera el recorte.

    La marca de D3DUSAGE_SOFTWAREPROCESSING se puede establecer cuando el procesamiento de vértices de software o modo mixto (D3DCREATE_MIXED_VERTEXPROCESSING/D3DCREATE_SOFTWARE_VERTEXPROCESSING) está habilitado para ese dispositivo. D3DUSAGE_SOFTWAREPROCESSING debe establecerse para que los búferes se usen con el procesamiento de vértices de software en modo mixto, pero no debe establecerse para el mejor rendimiento posible al usar el procesamiento de índices de hardware en modo mixto (D3DCREATE_HARDWARE_VERTEXPROCESSING). Sin embargo, establecer D3DUSAGE_SOFTWAREPROCESSING es la única opción cuando se usa un solo búfer con el procesamiento de vértices de hardware y software. D3DUSAGE_SOFTWAREPROCESSING se permite para dispositivos mixtos y de software.

    Es posible forzar los búferes de vértices e índices en la memoria del sistema especificando D3DPOOL_SYSTEMMEM, incluso cuando se realiza el procesamiento del índice en el hardware. Esta es una manera de evitar grandes cantidades de memoria bloqueada por páginas cuando un controlador coloca estos búferes en memoria AGP.

  • El tercer parámetro es el miembro D3DFMT_INDEX16 o D3DFMT_INDEX32 del tipo enumerado D3DFORMAT que especifica el tamaño de cada índice.

  • El cuarto parámetro es un miembro del tipo enumerado D3DPOOL que indica al sistema dónde en memoria colocar el nuevo búfer de índice.

  • El parámetro final que acepta IDirect3DDevice9::CreateIndexBuffer es la dirección de una variable que se rellena con un puntero a la nueva interfaz IDirect3DIndexBuffer9 del objeto de búfer de vértices, si la llamada se realiza correctamente.

En el ejemplo de código de C++ siguiente se muestra el aspecto que podría tener la creación de un búfer de índice en el código.

/*
 * For the purposes of this example, the d3dDevice variable is the 
 * address of an IDirect3DDevice9 interface exposed by a 
 * Direct3DDevice object, g_IB is a variable of type 
 * LPDIRECT3DINDEXBUFFER9.
 */

if( FAILED( d3dDevice->CreateIndexBuffer( 16384 *sizeof(WORD),
           D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, 
           &g_IB, NULL ) ) )
    return E_FAIL;

Acceso a un búfer de índice

Los objetos de búfer de índices permiten a las aplicaciones acceder directamente a la memoria asignada para los datos de índice. Puede recuperar un puntero a la memoria del búfer de índice llamando al método IDirect3DIndexBuffer9::Lock y, a continuación, accediendo a la memoria según sea necesario para rellenar el búfer con nuevos datos de índice o para leer los datos que contiene. El método Lock acepta cuatro parámetros. El primero, OffsetToLock, es el desplazamiento en los datos de índice. El segundo parámetro es el tamaño, medido en bytes, de los datos de índice. El tercer parámetro aceptado por el método IDirect3DIndexBuffer9::Lock , ppbData, es la dirección de un puntero BYTE rellenado con un puntero a los datos de índice, si la llamada se realiza correctamente.

El último parámetro, Flags, indica al sistema cómo se debe bloquear la memoria. Puede usarlo para indicar cómo la aplicación accede a los datos en el búfer. Especifique constantes para el parámetro Flags según el modo en que la aplicación tendrá acceso a los datos de índice. Esto permite al controlador bloquear la memoria y proporcionar el mejor rendimiento según el tipo de acceso solicitado. Use D3DLOCK_READONLY marca si la aplicación solo leerá la memoria del búfer de índice. Incluir esta marca permite a Direct3D optimizar sus procedimientos internos para mejorar la eficacia, dado que el acceso a la memoria será de solo lectura.

Después de rellenar o leer los datos de índice, llame al método IDirect3DIndexBuffer9::Unlock , como se muestra en el ejemplo de código siguiente.

// This code example assumes the m_pIndexBuffer is a variable of type 
// LPDIRECT3DINDEXBUFFER9 and that g_Indices has been properly 
// initialized with indices.

// To fill the index buffer, you must lock the buffer to gain 
// access to the indices. This mechanism is required because index
// buffers may be in device memory.

VOID* pIndices;

if( FAILED( m_pIndexBuffer->Lock( 
      0,                 // Fill from start of the buffer
      sizeof(g_Indices), // Size of the data to load
      BYTE**)&pIndices,  // Returned index data
      0 ) ) )            // Send default flags to the lock
{
    SAFE_RELEASE(m_pIndexBuffer);
    return E_FAIL;
}

memcpy( pIndices, g_Indices, sizeof(g_Indices) );
m_pIndexBuffer->Unlock();

Nota

Si crea un búfer de índice con la marca D3DUSAGE_WRITEONLY, no use la marca de bloqueo D3DLOCK_READONLY. Use la marca D3DLOCK_READONLY si la aplicación solo leerá de la memoria del búfer de índice. Incluir esta marca permite a Direct3D optimizar sus procedimientos internos para mejorar la eficacia, dado que el acceso a la memoria será de solo lectura.

Para obtener información sobre el uso de D3DLOCK_DISCARD o D3DLOCK_NOOVERWRITE para el parámetro Flags del método IDirect3DIndexBuffer9::Lock, vea Optimizaciones de rendimiento (Direct3D 9).

 

En C++, dado que accede directamente a la memoria asignada para el búfer de índice, asegúrese de que la aplicación accede correctamente a la memoria asignada. De lo contrario, corre el riesgo de representar esa memoria no válida. Use el intervalo del formato de índice que usa la aplicación para pasar de un índice del búfer asignado a otro.

Recupere información sobre un búfer de índice llamando al método IDirect3DIndexBuffer9::GetDesc . Este método rellena los miembros de la estructura D3DINDEXBUFFER_DESC con información sobre el búfer de índice.

Recursos de Direct3D

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

Búferes de vértices (Direct3D 9)