Когда я читаю документацию по webGL или OpenGL, можно увидеть некоторые закономерности использования имен функций и объектов. Но я не могу понять разницу между буферным объектом и массивом.
Существуют «объекты буфера вершин», «объекты массива вершин» и даже какой-то «буферный массив» или «буфер массива».
В контексте OpenGL, когда что-то является «массивом» и когда оно должно называться «буфером»?
char* buffer = socketRead();
(псевдокод). Журнал, с другой стороны, живет в течение всего жизненного цикла приложения. Таким образом, вы создаете массив где-то и начинаете читать сокет, каждый раз, когда вы получаете данные, которые записываете этот кусок в массив, давая вам аккуратный список всех полученных вами данных.Ответы:
Наименование объекта Vertex Array несколько неудачно. Есть три разные вещи, которые появляются (используются, чтобы появляться) в / с / вокруг вашего приложения, и которые (исторически) называются по-разному, с именем «массив» или «буфер» (ну, есть и объекты фреймбуфера, но я это проигнорирую).
Цель этого состояла в том, чтобы сделать доступ более эффективным, так как OpenGL мог бы просто скопировать все это за один раз в четко определенное время, когда вы дали обещание, что данные согласованы, и переместить их через AGP или что-то еще в одном блоке. Это больше не существует.
OpenGL может перемещать эти данные более или менее свободно, и вам разрешено / разрешено копировать в / из буфера только через соответствующий API или получать доступ к данным во время их отображения. Это то, что вы называете буферным объектом ( объект буфера вершин, если он содержит вершины, но на самом деле это не обязательно, это могут быть также данные изображения или униформа, только вершины, которые были поддержаны первыми, когда-то давно).
Цель этого состоит в том, чтобы гарантировать, что OpenGL может (в принципе) делать то, что он хочет, он может даже спекулятивно увеличить буфер над PCIe, прежде чем вы начнете рисовать. Это работает, потому что вы не владеете данными (OpenGL делает!), И вы можете получить к ним доступ только через данный API, поэтому всегда известно, что данные действительны. Драйвер может даже отказаться от использования буферной памяти на видеокарте, когда ему требуется память для чего-то другого, а затем восстановить ее из секретной копии, когда это необходимо.
Теперь цель объекта массива вершин состоит в том, чтобы уменьшить количество вызовов API и уменьшить количество проверок согласованности, которые OpenGL должен выполнить внутри, и, конечно, использовать аппаратное обеспечение как оно есть. Если вы связываете 5 буферов, то каждый должен пройти некоторые, возможно, дорогостоящие проверки, и каждый из них является кандидатом на отсутствие кеша в драйвере, плюс каждый требует обмена данными с графической картой для изменения дескриптора и т. Д. И т. Д. Если вы вместо этого привязав один VAO, драйвер может (часто) просто переключать дескриптор, установленный на видеокарте, и все готово.
источник
(вытащил из хроноса )
Каждый буфер имеет тенденцию составлять один атрибут массива вершин (объект). VAO может содержать много атрибутов вершин (например, положение, цвет, UV). Каждый из них может храниться в своем собственном буфере, где буфер указывает неформатированную последовательность смежных байтов, и где вам нужно явно указать размер (тип) для каждого элемента буфера как для вызовов OpenGL на стороне процессора, так и для работы шейдеров на стороне GPU.
Это один из способов. Другие способы это может работать:
Диаграмма ниже иллюстрирует эти два последних случая.
Итог: если фраза «массив вершин» используется без определения в OpenGL, можно предположить, что это означает VAO, что в контексте OpenGL (в частности) действительно очень отличается от буфера.
РЕДАКТИРОВАТЬ ваш комментарий:
GL_ARRAY_BUFFER
указывает на намерение использовать этот буферный объект для данных атрибута вершины, как описано выше. Это связано с тем, что буферы используются не только для атрибутов вершин. Однако, поскольку это наиболее распространенный вариант использования, и вы спрашиваете о VAO, я не буду вдаваться в другие; Здесь, однако, приведен список других типов буферов, которые можно настроить.источник
struct
типом. Данные могут чередоваться или быть полностью однородными для каждого буфера. Вы можете индексировать их так же, как с помощью традиционного массива C в ЦП. Массив объектов (используйте эту правильную терминологию или в конечном итоге запутываете себя!) ... (продолжение ниже)Эта терминология уходит корнями в историю OpenGL. Важно помнить, что для большинства актуальных здесь версий GL OpenGL развивался поэтапно и добавлял новые функциональные возможности к уже существующему API, а не изменял API.
Первая версия OpenGL не имела ни одного из этих типов объектов. Рисование было достигнуто с помощью нескольких вызовов glBegin / glEnd, и одной из проблем этой модели было то, что она была очень неэффективной с точки зрения затрат на вызов функции.
OpenGL 1.1 предпринял первые шаги для решения этой проблемы, представив массивы вершин. Вместо непосредственного указания данных вершин вы можете теперь получать их из массивов C / C ++ - отсюда и название. Таким образом, массив вершин - это всего лишь массив вершин и состояние GL, необходимое для их определения.
Следующая основная эволюция пришла с GL 1.5 и позволила хранить данные массива вершин в памяти графического процессора, а не в системной («клиентской») памяти. Слабым местом спецификации массива вершин GL 1.1 было то, что полный набор данных вершин должен был передаваться в GPU каждый раз, когда вы хотели его использовать; если он уже был на GPU, то такой передачи можно было бы избежать и добиться потенциального увеличения производительности.
Таким образом, был создан новый тип объекта GL, позволяющий хранить эти данные на графическом процессоре. Так же, как объект текстуры используется для хранения данных текстуры, объект буфера вершин хранит данные вершин. На самом деле это просто особый случай более общего типа объекта буфера, который может хранить неспецифические данные.
API для использования объектов буфера вершин был поддержан уже существующим API вершинных массивов, поэтому вы видите странные вещи, такие как преобразование смещений байтов в указатели в нем. Итак, теперь у нас есть API-интерфейс для массивов вершин, который просто хранит состояние, причем данные поступают из буферных объектов, а не из массивов в памяти.
Это подводит нас почти к концу нашей истории. Получившийся API был довольно многословным, когда дело дошло до определения состояния массива вершин, поэтому еще одним способом оптимизации было создание нового типа объекта, который собирал все это состояние вместе, допускал множественные изменения состояния массива вершин в одном вызове API и разрешал графические процессоры потенциально выполнять оптимизацию из-за возможности знать, какое состояние будет использоваться заранее.
Введите объект массива вершин, который собирает все это вместе.
Итак, подведем итог: массив вершин начал свою жизнь как набор состояний и данных (хранящихся в массиве) для рисования. Буфер вершин заменяет хранение массива в памяти с типом объекта GL, оставляя массив вершин просто быть состоянием. Объект массива вершин - это просто контейнерный объект для этого состояния, позволяющий изменять его проще и с меньшим количеством вызовов API.
источник
Я не работал с OpenGL какое-то время, поэтому я могу быть только наполовину прав. Вообще говоря: буферы хранят массив неформатированной памяти. Массив является общим термином непрерывной памяти.
Буфер должен быть привязан к контексту, а массив - это просто массив данных. Если я правильно помню, данные в буфере должны быть скопированы на графическую карту (отсюда и привязка).
Надеюсь, что это помогает немного
источник