Поделиться через


Буферы индекса (Direct3D 9)

Буферы индексов, представленные интерфейсом IDirect3DIndexBuffer9 , — это буферы памяти, содержащие данные индекса. Индексные данные или индексы представляют собой целочисленные смещения в буферы вершин и используются для отрисовки примитивов с помощью метода IDirect3Device9::D rawIndexedPrimitive.

Буфер вершин содержит вершины; Таким образом, можно нарисовать буфер вершин либо с индексированных примитивов, либо без нее. Однако, так как буфер индекса содержит индексы, нельзя использовать буфер индекса без соответствующего буфера вершин. (В качестве боковой заметки, IDirect3Device9::D rawIndexedPrimitiveUP и IDirect3DDevice9::D rawPrimitiveUP являются единственными методами рисования без индекса или буфера вершин.)

Описание буфера индекса

Буфер индекса описывается с точки зрения его возможностей, таких как, где он существует в памяти, поддерживает ли он чтение и запись, а также тип и количество индексов, которые он может содержать. Эти признаки хранятся в D3DINDEXBUFFER_DESC структуре.

Описания буфера индекса сообщают приложению, как был создан существующий буфер. Вы предоставляете пустую структуру описания для системы, чтобы заполнить возможности ранее созданного буфера индекса.

  • Элемент Format описывает формат поверхности данных буфера индекса.
  • Тип определяет тип ресурса буфера индекса.
  • Элемент структуры использования содержит общие флаги возможностей. Флаг D3DUSAGE_SOFTWAREPROCESSING указывает, что буфер индекса должен использоваться с обработкой вершин программного обеспечения. Наличие флага D3DUSAGE_WRITEONLY в использовании указывает, что память буфера индекса используется только для операций записи. Это позволяет драйверу разместить данные индекса в лучшем расположении памяти, чтобы обеспечить быструю обработку и отрисовку. Если флаг D3DUSAGE_WRITEONLY не используется, драйвер, скорее всего, помещает данные в расположение, которое неэффективно для операций чтения. Это жертвует некоторой скоростью обработки и отрисовки. Если этот флаг не указан, предполагается, что приложения выполняют операции чтения и записи данных в буфере индекса.
  • Пул задает класс памяти, выделенный для буфера индекса. Флаг D3DPOOL_SYSTEMMEM указывает, что система создала буфер индекса в системной памяти.
  • Элемент Size сохраняет размер в байтах данных буфера вершин.
  • Последний параметр pSharedHandle не используется. Задайте для него значение NULL.

Требования к обработке индексов

Производительность операций обработки индексов сильно зависит от того, где буфер индекса существует в памяти и какой тип устройства отрисовки используется. Приложения управляют выделением памяти для буферов индексов при их создании. При установке флага памяти D3DPOOL_SYSTEMMEM буфер индекса создается в системной памяти. Если используется флаг памяти D3DPOOL_DEFAULT, драйвер устройства определяет, где память для буфера индекса лучше всего выделена, часто называемая оптимальной памятью драйвера. Оптимальная память драйвера может быть локальной памятью видео, не локальной памятью видео или системной памятью.

Задание флага поведения D3DUSAGE_SOFTWAREPROCESSING при вызове метода IDirect3DDevice9::CreateIndexBuffer указывает, что буфер индекса должен использоваться с обработкой вершин программного обеспечения. Этот флаг необходим при обработке вершин в смешанном режиме (D3DCREATE_MIXED_VERTEXPROCESSING) при использовании обработки вершин программного обеспечения.

Приложение может напрямую записывать индексы в буфер индекса, выделенный в оптимальной памяти драйвера. Этот метод предотвращает операцию избыточного копирования позже. Этот метод не работает хорошо, если приложение считывает данные обратно из буфера индекса, так как операции чтения, выполняемые узлом из оптимальной памяти драйвера, могут быть очень медленными. Таким образом, если приложению необходимо считывать во время обработки или записи данных в буфер, то буфер индекса системной памяти лучше всего подходит.

Примечание.

Всегда используйте D3DPOOL_DEFAULT, за исключением случаев, если вы не хотите использовать память видео или использовать большие объемы заблокированной страницы ОЗУ, если драйвер помещает вершины или буферы индекса в память AGP.

 

Создание буфера индекса

Создайте объект буфера индекса, вызвав метод IDirect3DDevice9::CreateIndexBuffer , который принимает шесть параметров.

  • Первый параметр задает длину буфера индекса в байтах.

  • Второй параметр — это набор элементов управления использованием. Помимо прочего, его значение определяет, могут ли вершины, на которые ссылаются индексы, содержать сведения об обрезки. Чтобы повысить производительность, укажите D3DUSAGE_DONOTCLIP, если вырезка не требуется.

    Флаг D3DUSAGE_SOFTWAREPROCESSING можно задать при включенной смешанной обработке вершин (D3DCREATE_MIXED_VERTEXPROCESSING / D3DCREATE_SOFTWARE_VERTEXPROCESSING) для этого устройства. D3DUSAGE_SOFTWAREPROCESSING необходимо задать для буферов, которые будут использоваться с обработкой вершин программного обеспечения в смешанном режиме, но при использовании аппаратной обработки индексов в смешанном режиме (D3DCREATE_HARDWARE_VERTEXPROCESSING) не следует задавать оптимальную производительность. Однако параметр D3DUSAGE_SOFTWAREPROCESSING является единственным вариантом, если один буфер используется как с аппаратной, так и программной обработкой вершин. D3DUSAGE_SOFTWAREPROCESSING разрешено для смешанных и программных устройств.

    Можно принудительно принудительно применить буферы вершин и индексов в системную память, указав D3DPOOL_SYSTEMMEM, даже если обработка индекса выполняется в оборудовании. Это способ избежать чрезмерно больших объемов заблокированной страницы памяти, когда драйвер помещает эти буферы в память AGP.

  • Третий параметр — это либо D3DFMT_INDEX16, либо элемент D3DFMT_INDEX32 перечисленного типа D3DFORMAT , указывающий размер каждого индекса.

  • Четвертый параметр является членом перечисленного типа D3DPOOL , который сообщает системе, где в памяти помещается новый буфер индекса.

  • Окончательный параметр IDirect3Device9::CreateIndexBuffer принимает адрес переменной, заполненной указателем на новый интерфейс IDirect3DIndexBuffer9 объекта буфера вершин, если вызов выполнен успешно.

В следующем примере кода C++ показано, как может выглядеть создание буфера индекса в коде.

/*
 * 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;

Доступ к буферу индекса

Объекты буфера индекса позволяют приложениям напрямую обращаться к памяти, выделенной для данных индекса. Указатель на буфер памяти можно получить, вызвав метод IDirect3DIndexBuffer9::Lock , а затем получить доступ к памяти при необходимости, чтобы заполнить буфер новыми данными индекса или считывать все содержащиеся в нем данные. Метод Lock принимает четыре параметра. Первым, OffsetToLock, является смещение в данные индекса. Второй параметр — это размер, измеряемый в байтах, данных индекса. Третий параметр, принятый методом IDirect3DIndexBuffer9::Lock , ppbData, является адресом указателя BYTE, заполненным указателем на данные индекса, если вызов завершается успешно.

Последний параметр, флаги, сообщает системе, как должна быть заблокирована память. Его можно использовать, чтобы указать, как приложение обращается к данным в буфере. Укажите константы для параметра Flags в соответствии с способом доступа к данным индекса в приложении. Это позволяет драйверу заблокировать память и обеспечить лучшую производительность, учитывая запрошенный тип доступа. Используйте флаг D3DLOCK_READONLY, если приложение будет читать только из памяти буфера индекса. В том числе этот флаг позволяет Direct3D оптимизировать свои внутренние процедуры для повышения эффективности, учитывая, что доступ к памяти будет доступны только для чтения.

После заполнения или чтения данных индекса вызовите метод IDirect3DIndexBuffer9::Unlock , как показано в следующем примере кода.

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

Примечание.

Если вы создаете буфер индекса с флагом D3DUSAGE_WRITEONLY, не используйте флаг блокировки D3DLOCK_READONLY. Используйте флаг D3DLOCK_READONLY, если приложение будет читать только из памяти буфера индекса. В том числе этот флаг позволяет Direct3D оптимизировать свои внутренние процедуры для повышения эффективности, учитывая, что доступ к памяти будет доступны только для чтения.

Сведения об использовании D3DLOCK_DISCARD или D3DLOCK_NOOVERWRITE для параметра Flags метода IDirect3DIndexBuffer9::Lock см. в разделе "Оптимизация производительности" (Direct3D 9).

 

В C++, так как вы напрямую обращаетесь к памяти, выделенной для буфера индекса, убедитесь, что приложение правильно обращается к выделенной памяти. В противном случае вы рискуете выполнить отрисовку недопустимой памяти. Используйте шаг формата индекса, который приложение использует для перемещения из одного индекса в выделенный буфер в другой.

Получение сведений об буфере индекса путем вызова метода IDirect3DIndexBuffer9::GetDesc. Этот метод заполняет элементы структуры D3DINDEXBUFFER_DESC сведениями о буфере индекса.

Ресурсы Direct3D

Отрисовка из буферов вершин и индексов (Direct3D 9)

Буферы вершин (Direct3D 9)