Можете ли вы использовать несколько целей с одним VBO? - PullRequest
6 голосов
/ 01 января 2012

Пример кода:

1. glGenBuffers(1, &VboId);
2. glBindBuffer(GL_ARRAY_BUFFER, VboId);
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

Итак, мы генерируем универсальный дескриптор VBO, а затем связываем его с помощью "GL_ARRAY_BUFFER".Связывание с ним имеет две цели:

  1. Мы должны связать буфер до того, как сможем скопировать данные в GPU через glBufferData
  2. Мы должны связать буфер, прежде чем мы сможем добавить атрибутык нему через glVertexAttribPointer

И я думаю, что это единственный раз, когда вам нужно связать VBO.У меня вопрос, есть ли сценарий, в котором цель (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER или GL_PIXEL_UNPACK_BUFFER) будет отличаться в строках 2 и 3?Или мы хотели бы привязать его к другой цели перед строкой 4?

Можем ли мы привязать несколько буферных целей к одному VBO?

1 Ответ

11 голосов
/ 01 января 2012

Вы не привязываете цели к объекту буфера.Цели - это местоположения в контексте OpenGL, с которыми вы можете связать вещи (например, объекты буфера).Таким образом, вы связываете буферные объекты с целями, а не наоборот.

A буферный объект (такого понятия, как VBO, не существует. Есть просто буферные объекты) - это просто неформатированный линейный массив памяти, принадлежащий драйверу OpenGL.Вы можете использовать его в качестве источника данных массива вершин, связав буфер с GL_ARRAY_BUFFER и вызвав одну из функций gl*Pointer.Эти функции только работают с буфером, в настоящее время связанным с GL_ARRAY_BUFFER.Вы можете использовать их в качестве источника данных индекса, связав их с GL_ELEMENT_ARRAY_BUFFER и вызвав одну из функций glDrawElements.

Функции, используемые для изменения содержимого объектов буфера (glBufferData, glMapBufferglBufferSubData и т. Д.) Все они специально выбирают цель для своих операций.Так что glBufferData(GL_ARRAY_BUFFER, ...) выполняет свою работу с любым буфером, в данный момент связанным с GL_ARRAY_BUFFER.

Таким образом, существует два вида функций, которые влияют на объекты буфера: те, которые изменяют их содержимое, и те, которые используют их в действии.Последние специфичны для источника;glVertexAttribPointer всегда использует буфер, в настоящее время связанный с GL_ARRAY_BUFFER.Вы не можете заставить его использовать другую цель.Аналогично, glReadPixels всегда использует буфер, связанный с GL_PIXEL_PACK_BUFFER.И так далее.Если функция работает с объектами буфера, но не принимает цель в качестве параметра, то в документации будет указано, из какой цели она ищет свой буфер.

Примечание: Вершинные массивыдовольно странноАссоциация между атрибутом вершины и буферным объектом осуществляется путем вызова glVertexAttribPointer.Эта функция устанавливает соответствующие данные для этого атрибута, используя объект буфера, который в настоящее время связан с GL_ARRAY_BUFFER.Под «текущей привязкой» я подразумеваю связанную в то время, когда эта функция называется .Таким образом, сразу после вызова этой функции вы можете вызвать glBindBuffer(GL_ARRAY_BUFFER, 0), и она не изменит ничего о том, что происходит, когда вы идете на рендеринг.Он будет отображаться очень хорошо.

Таким образом, вы можете использовать разные буферные объекты для разных атрибутов.Информация будет сохраняться до тех пор, пока вы не измените ее с помощью другого glVertexAttribPointer вызова для этого конкретного атрибута.

...