OpenGL: VBO или glBegin () + glEnd ()?

16

Мне недавно дали эту ссылку на учебный сайт от кого-то, кому я дал оригинальную OGL Redbook. Третий заголовок внизу ясно говорит о том, что следует забыть glBegin () и glEnd () как типичный метод рендеринга Я учился по методу Redbook, но я вижу некоторую выгоду в VBO. Действительно ли это правильный путь, и если да, то есть ли способ легко преобразовать код рендеринга и последующие шейдеры в VBO и последующие типы данных?

С. Фицджеральд
источник

Ответы:

27

Современные VBO в OpenGL - это путь, исправленный функционал (включая glBegin / glEnd и промежуточный материал) устарел с 3.0 и удален с 3.1.

С профилем ядра OpenGL, OpenGL ES 2.0+ и WebGL у вас даже нет доступа к старому.

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

Это не просто VBO, вам нужно использовать шейдеры для всего и выполнять матричные преобразования самостоятельно (или использовать GLM).

Единственная причина использовать старый материал - если вы хотите использовать OpenGL до версии 2.0. который был выпущен в 2003 году. Есть несколько действительно дрянных встроенных чипсетов для нетбуков, которые имеют 1,5, но даже 1,5 должны поддерживать VBO, а не шейдеры. Или OpenGL ES 1.x, который основан на конвейере фиксированных функций (например, он используется на старых iPhone). Или OpenGL SC (для систем, важных для безопасности).

Следующие часто используемые функции устарели:

  • glBegin
  • glEnd
  • glVertex *
  • glNormal *
  • glTextCoord *
  • glTranslate *
  • glRotate *
  • glScale *
  • glLoadIdenity
  • glModelViewMatrix

В учебниках opengl-tutorial.org есть, как мне кажется, лучший способ изучения OpenGL. Они полагаются на некоторые устаревшие совместимые вещи, но на самом деле не учат этому. Например, вы не должны ничего визуализировать без шейдера, но это работает. И вам нужно самостоятельно обрабатывать операции с матрицами (вращать, переводить и т. Д.), Но по умолчанию вы получите базовый плоский 2D-видовой экран.

В дополнение к тому, чтобы избежать устаревших вещей, есть множество функций, которые делают кодирование OpenGL намного приятнее, но со многими из них вы должны решить, согласны ли вы с необходимостью более новых версий OpenGL 3.x + и совместимого оборудования.

Там больше информации в посте, который я сделал здесь .

Если вам по какой-то причине необходимо поддерживать более старый OpenGL, вы можете использовать VBO, когда это возможно, а когда нет, предоставить запасной вариант, который использует glBegin / glEnd и проходит по вашим данным вершин.

С другой стороны, нет никакого реального «простого» способа конвертировать старый код рендеринга. Возможно, вы могли бы реализовать свою собственную версию функций, которые добавляют вершины в массив / вектор, который затем выгружает его в VBO и рисует его, когда вы подделываете вызов glEnd. но это было бы очень неэффективно, поскольку он делал бы это каждый кадр (если вы не поставили галочку, чтобы сделать это только один раз, но это не работает для анимированных объектов) и, вероятно, было бы больше работы, чем просто переключение на VBO. Я полагаю, если бы у вас было много кода, этот подход мог бы работать.

Дэвид С. Бишоп
источник
7

С VBO у вас, как правило, есть два основных преимущества.

Преимущество 1 относится к полностью статическим данным и связано с возможностью сохранять ваши данные вершин в памяти, которая является более оптимальной для графического процессора.

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

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

Хорошая (не на 100% точная, но достаточная, чтобы помочь вам разобраться в этом) аналогия заключается в том, что вы водитель автобуса, который должен доставить 50 человек из одного города в другой. Вы можете загрузить их по одному и совершить 50 отдельных поездок - это glBegin / glEnd. В качестве альтернативы вы можете поместить все 50 из них в автобус и просто совершить одну поездку - это пакетирование с массивами вершин или VBO (в случае VBO 50 человек уже будут в автобусе;)).

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

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

Несколько заключительных мыслей.

Наличие данных модели в формате, который можно легко загрузить в VBO, может значительно облегчить вам весь этот процесс. Это означает, что вам следует избегать более сложных или экзотических форматов, по крайней мере, сначала (и до тех пор, пока вы не освоитесь с процессом); Сохраняйте вещи простыми и простыми, насколько это возможно, при обучении, и будет меньше вещей, которые могут пойти не так, и меньше мест, где придется искать ошибки, если (или когда!) что-то пойдет не так.

Людей иногда отталкивают, если они видят реализацию VBO, использующую больше памяти, чем оптимизированная / сжатая реализация glBegin / glEnd (они могут даже называть это «отходами»). Не будь таким. За исключением крайних случаев, использование памяти действительно не что важно. Здесь очевидный компромисс - вы принимаете потенциально более высокое использование памяти в обмен на существенно более высокую производительность. Также помогает развить мышление, что память - это дешевый и обильный ресурс, который нужно использовать; производительность нет.

И, наконец, старый каштан - если он уже достаточно быстр, значит, ваша работа выполнена. Если вы достигли целевой частоты кадров, если у вас есть запас для переходных условий, то этого достаточно, и вы можете перейти к следующему шагу. Вы можете тратить много времени и энергии, выжимая лишние 10% из чего-то, что на самом деле в этом не нуждается (был там, сделал это, все еще попал в ловушку), поэтому всегда учитывайте, как наиболее оптимально использовать ваше собственное время. Потому что время программиста еще дешевле и менее затратно, чем производительность!

Максимус Минимус
источник