Понимание объектов массива вершин (glGenVertexArrays)

#c #c #opengl #opengl-3

#c #c #opengl #opengl-3

Вопрос:

Меня смущает смысл генерации объекта массива вершин (VAO) с:

 glGenVertexArrays(GLsizei n, GLuint *arrays);
  

и

 glBindVertexArray(GLuint);
  

Потому что я все еще могу создать объект буфера, скажем, для вершин, и описать этот объект буфера с помощью glVertexAttribPointer и glEnableVertexAttribArray , даже не создавая VAO.

Мой вопрос в том, что если вам не нужно фактически создавать VAO для описания данных в объекте buffer, почему такие источники, как OpenGL SuperBible 5ed, включают вызов для создания VAO при создании VBO? Они используются только для более сложных тем, которые мне еще предстоит открыть, я в полном замешательстве?

Также я впервые столкнулся с этим вопросом при чтении статьи Википедии о VBO, и их пример кода не содержит вызовов glGenVertexArrays() , но они все еще описывают данные с помощью glVertexAttribPointer() .Запись VBO в ВикиПример, где VAOS создаются по какой причине?

Ответ №1:

Улучшена производительность.

Во многих случаях настройка ваших атрибутов на хосте требует большого количества вызовов API и значительного объема проверки внутри реализации.

Выполнение всего этого один раз и использование VAO позволяют амортизировать эту работу.

Смотрите, например, анализ Грэма Селлерса для получения фактических данных.

Комментарии:

1. Однако у них есть недостаток — их нельзя совместно использовать в разных контекстах, что делает их довольно бесполезными вне игрового сценария.

2. А также, я думаю, использование no VAOs является устаревшим стилем в GL4. Таким образом, помимо их преимуществ, вам также придется использовать их, если вы хотите обеспечить прямую совместимость.

3. Ну, VAO по умолчанию с именем 0 все еще можно использовать без генерации VAO, так что вам не обязательно делать это в 4.1, в любом случае явно. Но, конечно, теперь, когда я понимаю лучше, вы бы.

4. @bluth «Ну, VAO по умолчанию с именем 0 все еще можно использовать без генерации VAO «: Нет, это невозможно. Не соответствует ядру OpenGL 3.1 и выше. Если вы находитесь в режиме совместимости, то вы можете это сделать. Но не в ядре OpenGL. Обратите внимание, что NVIDIA неправильно реализует эту часть спецификации и позволяет 0 функционировать как VAO. Но AMD действительно следует спецификации, поэтому, если вы запрашиваете основной контекст OpenGL на их оборудовании, вы должны создать и привязать VAO где-нибудь в своей программе.

Ответ №2:

Допустим, вы создаете объект, которому нужны три VBO (разные данные для затенения, возможно, позиции, нормали и какой-нибудь необычный параметр эффекта). Каждый раз, когда вы будете рисовать этот объект, вам придется привязывать все эти VBO и устанавливать любые дополнительные параметры. Если вы используете VAO, вам нужно использовать только один вызов (привязка массива вершин), это настроит всю среду для конкретного объекта.

Комментарии:

1. Это забавная метафора из ShannonLiu помогли мне лучше это понять.

Ответ №3:

Ответ не так сложен, как вы себе представляли. Просто подумайте об этом как о забавной метафоре; VertexArrayObject это босс, и он управляет несколькими сотрудниками, которые являются VetexBufferObjects .