| 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 | < Назад | Оглавление | Далее > |