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

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

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

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

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

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

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

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

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

Задание флага поведения D3DUSAGE_SOFTWAREPROCESSING при вызове метода IDirect3Device9::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 , который сообщает системе, где в памяти следует разместить новый буфер индекса.

  • Последним параметром, который принимает IDirect3DDevice9::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::LockppbData, — это адрес указателя BYTE, заполненного указателем на данные индекса, если вызов выполнен успешно.

Последний параметр Flags сообщает системе, как должна быть заблокирована память. Его можно использовать для указания того, как приложение обращается к данным в буфере. Укажите константы для параметра 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)