Войти
ПрограммированиеФорумГрафика

OpenGL, VAO, VBO

Страницы: 1 2 Следующая »
#0

Доброго дня!
В любом руководстве будет написано, что: "VAO хранит состояние, необходимое для переключения между различными конфигурациями вершинных массивов/буферов", или что-то вроде того.
То есть команда

glBindVertexArray
должна устанавливать сохраненные раннее в конкретный VAO буферы и состояния командами
glBindBuffer, glVertexAttrib*, glVertexAttribPointer, ...
Теперь расссмотрим следующий код
glBindVertexArray(vao1);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);

glBindVertexArray(vao2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);

glBindVertexArray(0);

А дальше запишем следующий код.

glBindVertexArray(vao1);
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &currentVBO);

По логике, после установки vao1, она должна установить vbo1 в GL_ARRAY_BUFFER. Однако, в currentVBO останется vbo2, даже несмотря на то, что в предыдущем листинге было

glBindVertexArray(0);
Таким образом возникает вопрос:
Правильно ли я понимаю, что привязка VAO и VBO абсолютно независимы и никак не влияют на друг друга. Только лишь во время drawcall'а, текущий VAO неявно установит свои настройки касаемо конфигураций вершинных массивов/буферов, а после восстановит все как было?

PS: Хочу это знать, чтобы понимать, что происходит под коробкой. Это нужно для того, чтобы запилить кэширование текущих буферов и не вызывать glBindBuffer для уже установленного буфера.

1 мар. 2018 (Правка: 16:29)

#1

https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Array_Object

Think of it like this. glBindBuffer sets a global variable, then glVertexAttribPointer reads that global variable and stores it in the VAO. Changing that global variable after it's been read doesn't affect the VAO. You can think of it that way because that's exactly how it works.

P.S.
При этом ibo вполне себе сохраняется в vao.

1 мар. 2018 (Правка: 16:44)

#2

Dampire
Спасибо, разобрался.
Действительно,

glBindBuffer
устанавливает глобальное состояние. Во время установленного VAO, такие команды как
glVertexAttrib*, glVertexAttribPointer
запоминают в указанный attributeIndex установленный раннее индекс VBO. Получить этот id можно следующим образом
glBindVertexArray(vao);
glGetVertexAttribiv(attribIndex, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &vboId);

1 мар. 2018

#3

AMM1AK
Смотри на расширение direct state access, там понятнее что к чему и когда привязывается

1 мар. 2018

#4

Доброго дня!
Подниму тему, так как возник еще один вопрос.
Dampire
> P.S.
> При этом ibo вполне себе сохраняется в vao.
В какой момент vao сохраняет себе идентификатор ibo? Для вершинного буфера, я так понял, это делалось в момент вызова glVertexAttribPointer или glVertexAttribIPointer. Как же обстоит дело с индексным буфером? Неужели это происходит прямо внутри glBindBuffer?(при условии что target == GL_ELEMENT_ARRAY_BUFFER)
Если да, то правильно ли я понимаю, что если я не отвяжу vao, то я могу его случайно испортить, если буду потом биндить что-то к  GL_ELEMENT_ARRAY_BUFFER?

12 мар. 2018

#5

Да.

12 мар. 2018

#6

AMM1AK
> В какой момент vao сохраняет себе идентификатор ibo?
А если у вас OpenGL 4.5, то достаточно вызвать glVertexArrayElementBuffer и ничего байндить не нужно.

12 мар. 2018

#7

AMM1AK
> Если да, то правильно ли я понимаю, что если я не отвяжу vao, то я могу его
> случайно испортить, если буду потом биндить что-то к  GL_ELEMENT_ARRAY_BUFFER?
Именно так. Это OpenGL. Тут все на вот таких костылях. Привыкай.  :)

12 мар. 2018

#8

MrShoor
> Это OpenGL. Тут все на вот таких костылях. Привыкай.

Не забудь рассказать про DX12, всё круто, но нужно играть по правилам MS :)

12 мар. 2018

#9

MrShoor
Забыл рассказать про default vao.

12 мар. 2018

#10

Dampire
> Забыл рассказать про default vao.
Что за default vao? 0 который? Не во всех реализациях OGL ES можно биндить ноль. Некоторые выдают INVALID_OPERATION если попытаться забиндить 0.

12 мар. 2018

#11

А есть пример использования glVertexArrayElementBuffer? А то кроме сухонькой http://docs.gl/gl4/glVertexArrayElementBuffer больше ничего не попалось :)

12 мар. 2018

#12

Daniil Petrov
раньше было
glBindVertexArray(vao)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib)

теперь
glVertexArrayElementBuffer(vao, ib)

13 мар. 2018

#13

Запутался :) решил растащить загрузку VBO и их оборачивание в VAO, попутно использовал glVertexArrayElementBuffer.
Гружу VBOs:

+ Показать

Оборачиваю их в VAO:
+ Показать

Но приложение упорно вылетает на
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, ElementCount, GL_UNSIGNED_INT, NULL);
glBindVertexArray(NULL);
так было и с простыми биндингами. Не подскажете, где я допустил ошибку?

13 мар. 2018 (Правка: 3:56)

#14

Daniil Petrov
> glEnableVertexAttribArray(INDEX_BUFFER);
> glVertexAttribPointer(INDEX_BUFFER, 3, GL_UNSIGNED_INT, GL_FALSE, 0, NULL);
а зачем ты это делаешь для индексного буфера?

Здесь и ошибка. индексный буфер не имеет никакого отношения к атрибутам вершин

13 мар. 2018 (Правка: 5:37)

Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика