netlib.narod.ru | < Назад | Оглавление | Далее > |
Буферы вершин и индексов обладают сходными интерфейсами и предоставляют одинаковые методы, так что мы будем их рассматривать вместе. Буфер вершин представляет собой непрерывный участок памяти в котором хранятся данные вершин. Аналогичным образом, буфер индексов — это непрерывный участок памяти в котором хранятся данные индексов. Мы используем буферы вершин и индексов для хранения данных из соответствующих массивов по той причине, что эти буферы могут располагаться в памяти видеокарты. Визуализация данных, находящихся в памяти видеокарты, выполняется гораздо быстрее, чем визуализация данных, расположенных в системной памяти.
В коде буфер вершин представляется интерфейсом IDirect3DVertexBuffer9, а буфер индексов представляется интерфейсом IDirect3DIndexBuffer9.
Для создания буферов вершин и индексов используются следующие два метода:
HRESULT IDirect3DDevice9::CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle ); HRESULT IDirect3DDevice9::CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle );
У обоих методов большая часть параметров идентична, так что рассмотрим параметры обоих методов вместе:
Length — Количество байт, выделяемых под буфер. Если нам требуется буфер достаточного размера для хранения восьми вершин, в этом параметре следует указать 8 * sizeof(Vertex), где Vertex — это ваша структура данных вершины.
Usage — Задает ряд дополнительных параметров, определяющих особенности использования буфера. Можно указать 0, если дополнительные параметры отсутствуют, или комбинацию из одного или нескольких следующих флагов:
D3DUSAGE_DYNAMIC — Флаг указывает, что данный буфер будет динамическим. Различия между статическими и динамическими буферами мы обсудим чуть позже.
D3DUSAGE_POINTS — Флаг указывает, что буфер будет использовваться для хранения примитивов точек. Примитивы точек рассматриваются в главе 14. Этот флаг может применяться только для буферов вершин.
D3DUSAGE_SOFTWAREPROCESSING — Обработка вершин будет выполняться программно.
D3DUSAGE_WRITEONLY — Указывает, что приложение может только записывать данные в буфер. Это позволяет драйверу разместить буфер в области памяти, обеспечивающей максимальную скорость записи. Обратите внимание, что попытка прочитать данные из буфера, созданного с указанием этого флага, приведет к ошибке.
FVF — Настраиваемый формат вершин, которые будут храниться в создаваемом буфере вершин.
Pool — Пул памяти, в котором будет размещен буфер.
ppVertexBuffer — Адрес ля возврата указателя на созданный буфер вершин.
pSharedHandle — Не используется, должен быть равен 0.
Format — Задает размер индексов; используйте D3DFMT_INDEX16 для 16-разрядных индексов или D3DFMT_INDEX32 для 32-разрядных индексов. Обратите внимание, что не все устройства поддерживают 32-разрядные индексы, не забывайте проверять возможности устройства.
ppIndexBuffer — Адрес для возврата указателя на созданный буфер индексов.
В приведенном ниже фрагменте кода создается статический буфер вершин в котором можно хранить до восьми вершин типа Vertex.
IDirect3DVertexBuffer9* vb; _device->CreateVertexBuffer( 8 * sizeof(Vertex), 0, D3DFVF_XYZ, D3DPOOL_MANAGED, &vb, 0);
Следующий фрагмент кода показывает как создать динамический буфер индексов, в котором можно хранить до 36 16-разрядных индексов.
IDirect3DIndexBuffer9* ib; _device->CreateIndexBuffer( 36 * sizeof(WORD), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, 0);
Для доступа к памяти буфера вершин или индексов нам необходимо получить указатель на область памяти с содержимым буфера. Мы получаем указатель на содержимое с помощью метода Lock. Не забудьте после завершения работы с буфером разблокировать его. Получив указатель на область памяти, можно считывать и записывать информацию.
HRESULT IDirect3DVertexBuffer9::Lock( UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags ); HRESULT IDirect3DIndexBuffer9::Lock( UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags );
Рис. 3.1. Параметры OffsetToLock и SizeToLock определяют блокируемую область памяти. Если обоим параметрам присвоить нулевые значения, будет заблокирован весь буфер |
Параметры у обоих методов одинаковы.
OffsetToLock — смещение в байтах от начала буфера до начала блокируемой области (рис. 3.1).
SizeToLock — количество блокируемых байтов.
ppbData — Адрес для возврата указателя на начало заблокированной области памяти.
Flags — Флаги, задающие режим блокировки. Можно указать ноль, либо комбинацию из одного или нескольких перечисленных ниже флагов:
D3DLOCK_DISCARD — Этот флаг используется только для динамических буферов. Он приказывает аппаратуре оставить старый буфер и возвратить указатель на новый буфер, который должен быть создан. Данная возможность полезна потому что позволяет аппаратуре продолжать визуализацию с использованием старого буфера в то время как пользователь работает с новым буфером. Это предотвращает простои оборудования.
D3DLOCK_NOOVERWRITE — Данный флаг используется только для динамических буферов. Он сообщает, что вы будете только добавлять данные в буфер. Это значит, что вы не будете перезаписывать никакие данные, которые уже используются для визуализации. Следовательно видеокарта может продолжать выполнять визуализацию, в то время когда вы добавляете новые данные в буфер.
D3DLOCK_READONLY — Этот флаг указывает, что вы хотите заблокировать буфер только для чтения и ничего не будете записывать в него. Благодаря этому система может выполнить внутреннюю оптимизацию.
Флаги D3DLOCK_DISCARD и D3DLOCK_NOOVERWRITE опираются на тот факт, что в момент вызова функции блокировки часть памяти буфера может использоваться для визуализации. Если обстоятельства позволяют указывать эти флаги, то благодаря их использованию можно избежать простоев визуализации, которые могли бы произойти в ином случае.
Приведенный ниже пример демонстрирует обычный вариант использования метода Lock. Обратите внимание, что закончив работу мы сразу вызываем метод Unlock.
Vertex* vertices; _vb->Lock(0, 0, (void**)&vertices, 0); // заблокировать весь буфер vertices[0] = Vertex(-1.0f, 0.0f, 2.0f); // записать данные вершин vertices[1] = Vertex( 0.0f, 1.0f, 2.0f); // в буфер vertices[2] = Vertex( 1.0f, 0.0f, 2.0f); _vb->Unlock(); // разблокировать буфер, когда // мы закончили работать с ним
Иногда нам может потребоваться получить информацию о буфере вершин или индексов. Приведенный ниже фрагмент кода показывает методы, используемые для получения этой информации:
D3DVERTEXBUFFER_DESC vbDescription; _vertexBuffer->GetDesc(&vbDescription); // получаем информацию о буфере вершин D3DINDEXBUFFER_DESC ibDescription; _indexBuffer->GetDesc(&ibDescription); // получаем информацию о буфере индексов
Объявление структур D3DVERTEXBUFFER_DESC и D3DINDEXBUFFER_DESC выглядит следующим образом:
typedef struct _D3DVERTEXBUFFER_DESC { D3DFORMAT Format; D3DRESOURCETYPE Type; DWORD Usage; D3DPOOL Pool; UINT Size; DWORD FVF; } D3DVERTEXBUFFER_DESC; typedef struct _D3DINDEXBUFFER_DESC { D3DFORMAT Format; D3DRESOURCETYPE Type; DWORD Usage; D3DPOOL Pool; UINT Size; } D3DINDEXBUFFER_DESC;
netlib.narod.ru | < Назад | Оглавление | Далее > |