Путаница с вершинным буфером OpenGL

Кто-нибудь захочет объяснить разницу между VertexBuffer, VertexArray, VertexBufferObject и VertexArrayObject? Я даже не уверен, что это все термины для разных вещей, но я видел, как все они появляются в спецификации OpenGL.

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

Я использую то, что я считаю VertexArray, который хранит состояние всех установленных вершинных буферов, а также любых указателей вершин. Привязка VertexArray автоматически связывает буфер вершин и устанавливает указатели вершин. Я использовал это (в основном) успешно тоже.

Но что такое VertexBufferObject и VertexArrayObject? Они лучше? Разве VertexArray не дает мне все, что мне нужно?

2 ответа

Решение

Массив вершин - это просто некоторые данные в вашей программе (внутри вашего адресного пространства), о которых вы сообщаете OpenGL, указывая указатель на них.
Хотя они более эффективны, чем указание каждой отдельной вершины в отдельности, они все же имеют проблемы с производительностью. GL должен сделать копию во время вызова DrawElements (или аналогичной функции), потому что это единственный раз, когда можно быть уверенным, что данные действительны (в конце концов, ничто не мешает вам сразу же перезаписать данные). Это означает, что существует значительная помеха параллелизму и, следовательно, проблема производительности.

Буферные объекты вершин ("буферы вершин") - это необработанные блоки данных, которыми вы не владеете, то есть они не находятся в вашем адресном пространстве. Вы можете скопировать данные в буферный объект с помощью функции Копировать (Под) данные или временно сопоставив их с вашим адресным пространством. Как только вы удалите карту из буфера, он больше не принадлежит вам. Огромное преимущество заключается в том, что теперь GL может решить, что с ним делать и когда его загружать. Он знает, что данные будут действительными, потому что вы не можете получить к ним доступ. Это значительно упрощает параллелизм CPU/GPU.

Объекты массива вершин немного неправильны. В них нет вершин или массивов. Они являются просто своего рода "блоком описания состояния", который инкапсулирует привязки одного или нескольких объектов буфера вершин (включая любые вызовы VertexAttribPointer). Как таковые, они оба являются удобной функцией и несколько более эффективны (меньше вызовов функций), но не являются строго необходимыми. Вы можете делать все, что делает ВАО, тоже вручную.

  • BufferObject: буфер памяти, выделенный графическим процессором
    • Vertex Buffer Object: объект BufferObject, содержащий информацию о вершинах (цвета, положение, пользовательские данные, используемые шейдером,...)
    • Pixel Buffer Object: объект Buffer, содержащий информацию о пикселях или текселях. В основном используется для загрузки текстур.
    • Элемент Buffer Object: объект BufferObject, содержащий индексы (используется glDrawElements).
  • Vertex Array: память, используемая вызовом gl*Pointer. Может быть памятью хоста или объектом буфера вершин, если он связан с помощью команды glBindBuffer с GL_ARRAY_BUFFER,
  • Элемент Array: память, используемая вызовом glDrawElements. Может быть памятью хоста или объектом буфера элемента, если он связан с помощью команды glBindBuffer с GL_ELEMENT_ARRAY_BUFFER,
Другие вопросы по тегам