#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
.