Partilhar via


Buffers de índice (Direct3D 9)

Os bufferes de índice, representados pela interface IDirect3DIndexBuffer9do, são buffers de memória que contêm dados de índice. Os dados de índice, ou índices, são deslocamentos inteiros em buffers de vértice e são usados para renderizar primitivos usando o métodoIDirect3DDevice9::DrawIndexedPrimitive.

Um buffer de vértices contém vértices; portanto, pode-se desenhar um buffer de vértices com ou sem primitivas indexadas. No entanto, como um buffer de índice contém índices, não é possível usar um buffer de índice sem um buffer de vértice correspondente. (Como uma observação lateral, IDirect3DDevice9::DrawIndexedPrimitiveUP e IDirect3DDevice9::DrawPrimitiveUP são os únicos métodos de desenho que funcionam sem um índice ou um buffer de vértice.)

Descrição do buffer de índice

Um buffer de índice é descrito em termos de suas capacidades, como onde ele existe na memória, se ele suporta leitura e gravação e o tipo e número de índices que ele pode conter. Estas características são mantidas em uma estrutura D3DINDEXBUFFER_DESC.

As descrições do buffer de índice informam ao seu aplicativo como um buffer existente foi criado. Você fornece uma estrutura de descrição vazia para o sistema preencher com os recursos de um buffer de índice criado anteriormente.

  • O elemento Format descreve o formato de superfície dos dados de buffer de índice.
  • O Tipo identifica o tipo de recurso do buffer de índice.
  • O membro da estrutura "Usage" contém bandeiras de capacidade geral. O sinalizador D3DUSAGE_SOFTWAREPROCESSING indica que o buffer de índice deve ser usado com o processamento de vértices de software. A presença do sinalizador D3DUSAGE_WRITEONLY em Uso indica que a memória do buffer de índice é usada apenas para operações de gravação. Isso libera o driver para colocar os dados de índice no melhor local de memória para permitir o processamento e renderização rápidos. Se o sinalizador D3DUSAGE_WRITEONLY não for usado, é menos provável que o driver coloque os dados em um local ineficiente para operações de leitura. Isso sacrifica alguma velocidade de processamento e renderização. Se esse sinalizador não for especificado, presume-se que os aplicativos executam operações de leitura e gravação nos dados no buffer de índice.
  • Pool especifica a classe de memória alocada para o buffer de índice. O sinalizador D3DPOOL_SYSTEMMEM indica que o sistema criou o buffer de índice na memória do sistema.
  • O membro Tamanho armazena o tamanho, em bytes, dos dados do buffer de vértice.
  • O último parâmetro pSharedHandle não é usado. Defina-o como NULL.

Requisitos de processamento de índice

O desempenho das operações de processamento de índice depende muito de onde o buffer de índice existe na memória e que tipo de dispositivo de renderização está sendo usado. Os aplicativos controlam a alocação de memória para buffers de índice quando eles são criados. Quando o sinalizador de memória D3DPOOL_SYSTEMMEM é definido, o buffer de índice é criado na memória do sistema. Quando o sinalizador de memória D3DPOOL_DEFAULT é utilizado, o driver do dispositivo determina o local ideal para alocar a memória para o buffer de índice, frequentemente referida como memória otimizada pelo driver. A memória ideal do driver pode ser memória de vídeo local, memória de vídeo não local ou memória do sistema.

Ao definir o sinalizador de comportamento D3DUSAGE_SOFTWAREPROCESSING ao chamar o método IDirect3DDevice9::CreateIndexBuffer , fica especificado que o buffer de índice deve ser utilizado com processamento de vértices por software. Este flag é necessário no processamento de vértice de modo misto (D3DCREATE_MIXED_VERTEXPROCESSING) quando o processamento de vértice de software é utilizado.

O aplicativo pode gravar índices diretamente em um buffer de índice alocado na memória ideal do driver. Esta técnica impede uma operação de cópia redundante mais tarde. Essa técnica não funciona bem se seu aplicativo lê dados de volta de um buffer de índice, porque as operações de leitura feitas pelo host a partir da memória ideal do driver podem ser muito lentas. Portanto, se seu aplicativo precisa ler durante o processamento ou gravar dados no buffer de forma irregular, um buffer de índice de memória do sistema é uma escolha melhor.

Observação

Sempre usa D3DPOOL_DEFAULT, exceto quando não quiseres usar memória de vídeo ou usar grandes quantidades de RAM bloqueada por página quando o driver estiver a armazenar buffers de vértices ou índices na memória AGP.

 

Criar um buffer de índice

Crie um objeto de buffer de índice chamando o IDirect3DDevice9::CreateIndexBuffer método, que aceita seis parâmetros.

  • O primeiro parâmetro especifica o comprimento do buffer de índice, em bytes.

  • O segundo parâmetro é um conjunto de controles de uso. Entre outras coisas, o seu valor determina se os vértices referidos pelos índices são capazes de conter informações de recorte. Para melhorar o desempenho, especifique D3DUSAGE_DONOTCLIP quando o clipping não é necessário.

    O sinalizador D3DUSAGE_SOFTWAREPROCESSING pode ser definido quando o processamento de vértice de modo misto ou software (D3DCREATE_MIXED_VERTEXPROCESSING / D3DCREATE_SOFTWARE_VERTEXPROCESSING) esteja ativado para esse dispositivo. D3DUSAGE_SOFTWAREPROCESSING deve ser definido para buffers que serão utilizados com o processamento de vértices por software em modo misto, mas não deve ser definido para obter o melhor desempenho possível ao utilizar o processamento de índices por hardware em modo misto (D3DCREATE_HARDWARE_VERTEXPROCESSING). No entanto, definir D3DUSAGE_SOFTWAREPROCESSING é a única opção quando um único buffer é usado com processamento de vértice de hardware e software. D3DUSAGE_SOFTWAREPROCESSING é permitido para dispositivos mistos e de software.

    É possível forçar buffers de vértice e de índice para a memória do sistema especificando D3DPOOL_SYSTEMMEM, mesmo quando o processamento de índices é realizado em hardware. Esta é uma maneira de evitar quantidades excessivamente grandes de memória bloqueada por página quando um driver está colocando esses buffers na memória AGP.

  • O terceiro parâmetro é o D3DFMT_INDEX16 ou D3DFMT_INDEX32 membro do tipo enumerado D3DFORMAT que especifica o tamanho de cada índice.

  • O quarto parâmetro é um membro do D3DPOOL tipo enumerado que informa ao sistema onde na memória para colocar o novo buffer de índice.

  • O parâmetro final que IDirect3DDevice9::CreateIndexBuffer aceita é o endereço de uma variável que é preenchida com um ponteiro para o novo IDirect3DIndexBuffer9 interface do objeto de buffer de vértice, se a chamada for bem-sucedida.

O exemplo de código C++ a seguir mostra como a criação de um buffer de índice pode parecer no 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;

Acessar um buffer de índice

Os objetos de buffer de índice permitem que os aplicativos acessem diretamente a memória alocada para dados de índice. Você pode recuperar um ponteiro para a memória do buffer de índice chamando o IDirect3DIndexBuffer9::Lock método e, em seguida, acessando a memória conforme necessário para preencher o buffer com novos dados de índice ou para ler quaisquer dados que ele contenha. O método Lock aceita quatro parâmetros. O primeiro, OffsetToLock, é o deslocamento nos dados do índice. O segundo parâmetro é o tamanho, medido em bytes, dos dados do índice. O terceiro parâmetro aceito pelo método IDirect3DIndexBuffer9::Lock, ppbData, é o endereço de um ponteiro BYTE preenchido com um ponteiro para os dados do índice, se a chamada for bem-sucedida.

O último parâmetro, Flags, informa ao sistema como a memória deve ser bloqueada. Você pode usá-lo para indicar como o aplicativo acessa os dados no buffer. Especifique constantes para o parâmetro Flags de acordo com a forma como os dados do índice serão acessados pela sua aplicação. Isso permite que o driver bloqueie a memória e forneça o melhor desempenho dado o tipo de acesso solicitado. Utilize o sinalizador D3DLOCK_READONLY se a sua aplicação ler apenas a partir da memória do buffer de índice. A inclusão desse sinalizador permite que o Direct3D otimize seus procedimentos internos para melhorar a eficiência, dado que o acesso à memória será somente leitura.

Depois de preencher ou ler os dados de índice, chame o IDirect3DIndexBuffer9::Unlock método, conforme mostrado no exemplo de código a seguir.

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

Observação

Caso crie um buffer de índice com o sinalizador D3DUSAGE_WRITEONLY, não use o sinalizador de bloqueio D3DLOCK_READONLY. Use o sinalizador D3DLOCK_READONLY se seu aplicativo ler somente a partir da memória do buffer de índice. A inclusão desse sinalizador permite que o Direct3D otimize seus procedimentos internos para melhorar a eficiência, dado que o acesso à memória será somente leitura.

Para obter informações sobre como usar D3DLOCK_DISCARD ou D3DLOCK_NOOVERWRITE para o parâmetro Flags do método IDirect3DIndexBuffer9::Lock, consulte Otimizações de desempenho (Direct3D 9) .

 

Em C++, como você acessa diretamente a memória alocada para o buffer de índice, certifique-se de que seu aplicativo acesse corretamente a memória alocada. Caso contrário, você corre o risco de tornar essa memória inválida. Use a passada do formato de índice que seu aplicativo usa para mover de um índice no buffer alocado para outro.

Recupere informações sobre um buffer de índice chamando o IDirect3DIndexBuffer9::GetDesc método. Esse método preenche os membros da estrutura D3DINDEXBUFFER_DESC com informações sobre o buffer de índice.

Recursos Direct3D

renderização a partir de buffers de vértice e índice (Direct3D 9)

Buffers de Vértices (Direct3D 9)