2012-01-01 3 views
6

Пример кода:Можете ли вы использовать несколько целей с одним VBO?

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». Связывание, кажется, есть 2 цели:

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

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

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

ответ

11

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

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

Функции, используемые для изменения содержимого буферных объектов (glBufferData, glMapBuffer, glBufferSubData и т. Д.), Все это специально предназначено для работы. Таким образом, 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 для этого конкретного атрибута.

+0

Oooh! Спасибо! Теперь это имеет гораздо больше смысла. Это было мое обратное мышление, которое меня отбрасывало. – mpen

+0

Фактически, в отношении параграфа 3 вы говорите, что 'glBufferData' берет цель для своих операций, чтобы работать ... так что вы говорите, что в основном используется' GL_ARRAY_BUFFER' в качестве временного рабочего буфера? Почему нам нужно привязать объект-буфер к цели, а затем указать цель снова в 'glBufferData'? Я по существу попытался перевести строки 2 и 3 в мой вопрос, и программа больше не работает. Я пытаюсь понять, почему вам нужно будет указать цель дважды, если они не делают что-то другое. – mpen

+1

Nevermind .. Думаю, я просто понял это. Мы привязываем объект буфера к цели, а затем по существу передаем данные этой цели и, таким образом, косвенно к объекту буфера. Поэтому оба необходимы. Думаю ли я об этом правильно? Данные привязаны к буферному объекту, поэтому мы можем стереть «GL_ARRAY_BUFFER» сразу после вызова glBufferData, не теряя ничего. Я думаю, он работает так же, как указатели на атрибуты. – mpen

Смежные вопросы