Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Распределение объектов буфера вершин





 

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

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

Для начала, нужно задать несколько наименований для ваших вершинных буферов. Как и стоило ожидать, это делается посредством вызова функции glGen*; в данном случае, glGenBuffers(). В нашем примере NumVBOs( “Vertex-Buffer Objects) были распределены в наш массив buffers. Вот полное описание glGenBuffers().

void glGenBuffers(GLsizei n, GLuint *buffers);

Returns n currently unused names for buffer objects in the array buffers.

The names returned in buffers do not have to be a contiguous set of

integers.

The names returned are marked as used for the purposes of allocating

additional buffer objects, but only acquire a valid state once they have

been bound.

Zero is a reserved buffer object name and is never returned as a buffer

object by glGenBuffers().

Когда вы зададите наименования вашим буферными объектам, вы можете их использовать командой glBindBuffer(). Поскольку в OpenGL много видов объектов буферизации, когда мы привязываем буфер, нам нужно указать, какой вид файла нужно использовать. Поскольку для нашего примера нужны данные вершин графов, мы используем буфер GL_ARRAY_BUFFER. На данный момент есть восемь типов объектов буферизации, каждый из которых используется для своей цели в OpenGL. Мы обсудим каждый тип в соответствующем разделе этой книги. Вот подробности о glBindBuffer():



void glBindBuffer(GLenum target, GLuint buffer);

Specifies the current active buffer object. target must be set to one of

GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER,

GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER,

GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,

GL_TRANSFORM_FEEDBACK_BUFFER, or GL_UNIFORM_BUFFER. buffer

specifies the buffer object to be bound to.

glBindBuffer() does three things: 1. When using buffer of an unsigned

integer other than zero for the first time, a new buffer object is created

and assigned that name. 2. When binding to a previously created buffer

object, that buffer object becomes the active buffer object. 3. When

binding to a buffer value of zero, OpenGL stops using buffer objects for

that target.

 

Как и в случае с другими объектами, вы можете удалить буфер командой glDeleteBuffers().

void glDeleteBuffers(GLsizei n, const GLuint *buffers);

Deletes n buffer objects, named by elements in the array buffers. The

freed buffer objects may now be reused (for example, by glGenBuffers()).

If a buffer object is deleted while bound, all bindings to that object are

reset to the default buffer object, as if glBindBuffer() had been called

with zero as the specified buffer object. Attempts to delete nonexistent

buffer objects or the buffer object named zero are ignored without

generating an error.

 

Вы также можете запросить задано ли наименование объекту буферизации командой gllsBuffer()

GLboolean glIsBuffer(GLuint buffer);

Returns GL_TRUE if buffer is the name of a buffer object that has been

bound, but has not been subsequently deleted. Returns GL_FALSE if

buffer is zero or if buffer is a nonzero value that is not the name of a buffer

object.

 

Загрузка данных в буферный объект

 

После инициализации нашего буфер вершин, нам нужно перевести данные с наших вершинных объектов в буферные. Это делается с помощью команды glBufferData(), которая выполняет два функции: выделить область в памяти для хранения вершинных данных и копировать денные массивов в приложение на сервер OpenGL.

Поскольку данная процедура будет часто использоваться в дальнейшем, пожалуй, стоит подробнее её описать тут. Мы обратимся к использованию этой процедуры ещё не раз в нашей книге. Для начала, вот полное описание glBufferData()

void glBufferData(GLenum target, GLsizeiptr size,

const GLvoid *data, GLenum usage);

Allocates size storage units (usually bytes) of OpenGL server memory for

storing data or indices. Any previous data associated with the currently

bound object will be deleted.

target may be either GL_ARRAY_BUFFER for vertex attribute data;

GL_ELEMENT_ARRAY_BUFFER for index data;

GL_PIXEL_UNPACK_BUFFER for pixel data being passed into OpenGL;

GL_PIXEL_PACK_BUFFER for pixel data being retrieved from

OpenGLGL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER for

data copied between buffers; GL_TEXTURE_BUFFER for texture data

stored as a texture buffer; GL_TRANSFORM_FEEDBACK_BUFFER for

results from executing a transform feedback shader; or

GL_UNIFORM_BUFFER for uniform variable values.

size is the amount of storage required for storing the respective data. This

value is generally number of elements in the data multiplied by their

respective storage size.

data is either a pointer to a client memory that is used to initialize the

buffer object or NULL. If a valid pointer is passed, size units of storage are

copied from the client to the server. If NULL is passed, size units of

storage are reserved for use but are left uninitialized.

usage provides a hint as to how the data will be read and written after

allocation. Valid values are GL_STREAM_DRAW, GL_STREAM_READ,

GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ,

GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ,

GL_DYNAMIC_COPY.

glBufferData() will generate a GL_OUT_OF_MEMORY error if the

requested size exceeds what the server is able to allocate. It will generate a

GL_INVALID_VALUE error if usage is not one of the permitted values.

 

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

Например, наш запрос к glBufferData() абсолютно прямой. Наша вершинная информация хранится в массиве vertices. И хотя в нашем примере мы статично распределили её, вы можете считать эти данные из файла модели, или генерировать значения с помощью алгоритмов. Поскольку наши данные имеют атрибут вершин, мы превратим это в буфер GL_ARRAY_BUFFER, определив эту информацию как первый параметр. Нам также нужно указать объем выделенной памяти в байтах, так что мы просто вычисляем sizeof (vertices), которая сама сделает всю тяжелую работу. Наконец, нам нужно указать, как OpenGL должна обрабатывать эти данные. Поскольку эти данные будут использоваться для отрисовки геометрии, и не будут изменяться вовсе, мы выбирает GL_STATIC_DRAW для параметра применения glBufferData().

Для параметра “применение” есть много опций, о которых будет рассказано в Главе 3.

Взглянув на значения в массиве vertices, вы можете заметить, что они все в диапазоне [-1, 1] по обеим осям (x, y). На деле, OpenGL знает только как нарисовать геометрические примитивы в сетке координат. Эти координаты называются normalized-device coordinates (проще, NDCs). И хотя это похоже не ограничение, это совсем не так. В Главе 5 подробно будут обсуждаться все математические вычисления для создания сложнейших фигур в трехмерном пространстве, и их маппинг в NDCs. Здесь мы использовали NDCs только для облегчения примера. Вам же почти всегда предстоит использовать более сложные сетки координат.

На данный момент, нам успешно удалось создание вершинного объекта и сохранение его в объект буфера. Далее мы зададим шейдеры, которые должна будет использовать наша программа.

 









Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2018 zdamsam.ru Размещенные материалы защищены законодательством РФ.