Буфер вершин (Vertex Buffer)
Vertex Buffer (буфер вершин или вершинный буфер) — область данных, хранящая информацию обо всех или нескольких аттрибутах (элементах) вершины.
В библиотеке OpenGL существует непосредственный (Immediate mode) режим вывода геометрии без использования буферов вершин, задавая по очереди все необходимые атрибуты (элементы, в терминологии DirectX) каждой вершины последовательно. Такой способ вывода геометрии довольно медленный, а в некоторых графических GAPI, как DirectX или в новых версиях того же OpenGL, вообще отсутствует.
Буфер вершин позволяет создать блок с атрибутами большого количества вершин и выводить геометрию за один вызов определённых функций GAPI.
Отрисовка с использованием буфера вершин, расположенного в оперативной памяти
Для этого, в OpenGL следует установить указатели на различные атрибуты вершины следующими функциями:
//glVertexPointer рекомендуется ставить последним void glVertexPointer(int size, enum type, sizei stride, void *pointer ); void glNormalPointer( enum type, sizei stride, void *pointer ); void glColorPointer( int size, enum type, sizei stride, void *pointer ); void glSecondaryColorPointer( int size, enum type, sizei stride, void *pointer ); void glTexCoordPointer( int size, enum type, sizei stride, void *pointer ); void glVertexAttribPointer( uint index, int size, enum type, boolean normalized, sizei stride, const void *pointer );
Где pointer это указатель на данные, stride - шаг в байтах от одного атрибута до следующего (0, если они идут один за другим).
Более полный список и полное описание можно найти в спецификации OpenGL.
Так же, функциями glEnableClientState( enum array ) и glEnableVertexAttribArray( uint index ) следует указать что определённый массив активен.
Начиная с forward-compatible контекста GL3.0 и в более новых версиях, многие функции были отмечены устаревшими и теперь следует использовать только glVertexAttribPointer и glEnableVertexAttribArray.
Вывод геометрии в OpenGL производится следующими вызовами:
glDrawArrays(enum mode, int first, sizei count ); glMultiDrawArrays( enum mode, int *first, sizei *count, sizei primcount );
Вторая функция поможет заменить множество вызовов первой с разными параметрами first и count.
В Direct3D9 при отрисовке из оперативной памяти данные должны быть уложены одним куском, и формат вершины задаётся функциями IDirect3DDevice9::SetFVF или IDirect3DDevice9::SetVertexDeclaration.
Вывод выполняется следующей функцией:
IDirect3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride );
В Direct3D10 рисовать геометрию с использованием буфера в оперативной памяти нельзя.
Отрисовка с использованием буфера вершин, расположенного в видеопамяти
Данный вариант более эффективный, так как не приходится при каждом вызове отрисовки гонять буфер из оперативной памяти в память видеокарты.
В OpenGL, для создания буфера вершин в видеопамяти следует использовать расширение Vertex Buffer Object.
Создаём буфер:
glGenBuffersARB(1, &bufferID);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, bufferID); glBufferDataARB( GL_ARRAY_BUFFER_ARB, Length, Data, GL_STATIC_DRAW_ARB);
Теперь при установке указателей на атрибуты, следует указывать сдвиг в байтах от начала буфера.
Вывод геометрии выполняется такими же функциями, как и при использовании буфера в оперативной памяти.
В Direct3D9 буфер вершин создаётся следующим образом: