Подтвердить что ты не робот

Использование объектов вершинного массива и объектов буфера вершин

Я пытаюсь понять эти два, как их использовать и как они связаны. Скажем, я хочу создать простой ландшафт и текстурированный куб. Для обоих объектов у меня есть массив треугольников, а для куба у меня есть массив, содержащий данные текстуры. Мой вопрос: как использовать VAO и VBOs для создания и рендеринга этих двух?

  • Должен ли я создавать VAO и VBO для каждого объекта?
  • или должен создать VAO для каждого объекта VBO (вершины, данные текстур и т.д.)?

Есть много учебников и книг, но я до сих пор не понимаю, как эти понятия следует понимать и использовать.

4b9b3361

Ответ 1

По сути, вам нужно понять две вещи:

  • Объекты вершинного массива (VAO) - концептуально ничего, кроме тонких оболочек состояния.

  • Объекты буфера вершин (VBOs) хранят фактические данные.

Другой способ думать об этом заключается в том, что VAO описывают данные, хранящиеся в одном или нескольких VBOs.

Подумайте о VBOs (и вообще о буферных объектах) как о неструктурированных массивах данных, хранящихся в памяти сервера (GPU). Вы можете компоновать свои данные вершин в нескольких массивах, если хотите, или можете упаковать их в один массив. В любом случае буферные объекты сводятся к местам хранения данных.

Объекты Vertex Array отслеживают фактические указатели для памяти VBO, необходимой для команд рисования.

Они немного сложнее, чем указатели, так как вы знали бы их на языке, таком как C. Указатели вершин отслеживают объект буфера, который был привязан, когда они были указаны, смещение в его адресное пространство, шаг между атрибутами вершин и способы интерпретации базовых данных (например, следует ли сохранять целые значения или преобразовывать их в плавающие точки [ 0.0, 1.0], нормализуясь к диапазону типов данных).

Например, целочисленные данные обычно преобразуются в с плавающей запятой, но это команда, которую вы используете для указания указателя вершин (glVertexAttribPointer (...) vs. glVertexAttribIPointer (...)), который определяет это поведение.

Объекты вершинного массива также отслеживают объект-буфер, привязанный в настоящее время к GL_ELEMENT_ARRAY_BUFFER.

GL_ELEMENT_ARRAY_BUFFER есть команда: glDrawElements (...) издает свой список индексов из (при условии ненулевой привязки), и есть no glElementArrayPointer (...). glDrawElements (...) объединяет команду указателя и рисования в одну операцию и будет использовать привязку, хранящуюся в активном объекте Vertex Array, чтобы выполнить это.


С учетом этого, если ваши объекты не разделяют вершинные данные, вам, как правило, понадобится уникальный набор VBOs для каждого.

Вы можете использовать один VAO для всего своего программного обеспечения, если хотите, или можете воспользоваться тем фактом, что изменение связанного VAO изменяет почти весь набор состояний, необходимых для рисования разных объектов.

Таким образом, рисование ландшафта и куба может быть таким же простым, как изменение связанного VAO. Возможно, вам придется сделать больше, если вам нужно применить разные текстуры к каждому из них, но VAO позаботится обо всех настройках, связанных с вершинами.

Ответ 2

Ваш вопрос нелегко подотчетен здесь, а скорее в учебнике. Возможно, вы уже знаете эти два сайта, но если нет, я оставляю ссылки.

OGLDEV

OpenGL-Tutorial.org

Теперь, пытаясь выяснить ваши вопросы, объект массива Vertex представляет собой объект OpenGL, предназначенный для сокращения накладных расходов API для вызовов вызовов. Вы можете думать об этом как о контейнере для буфера вершин и связанных с ним состояний. Что-то похожее на старые списки. Обычно существует связь 1 к 1 между VAO и VBO; то есть каждое VAO содержит уникальный VBO. Но это не обязательно. У вас может быть несколько VAO, ссылающихся на один и тот же VBO.

Простейший способ моделирования этого кода, я думаю, будет состоять в том, чтобы у вас был класс/тип VAO и метод для присоединения к нему VBO. Затем дайте экземпляр VAO для каждой сетки. В свою очередь, сетка может иметь ссылку на тип VBO, который может быть его собственным или общим.