glBufferDataARB или glBufferSubDataARB? - PullRequest
       32

glBufferDataARB или glBufferSubDataARB?

3 голосов
/ 26 октября 2011

Я разрабатываю физическую игру на основе плиток, как Falling Sand Game. В настоящее время я использую Static VBO для вершин и Dynamic VBO для цветов, связанных с каждым типом блока. При таком типе игры данные в цвете VBO меняются очень часто. (когда-либо изменение блока) В настоящее время я вызываю glBufferSubDataARB для каждого изменения блока. Я обнаружил, что это работает, но оно плохо масштабируется с разрешением. (Гораздо медленнее с каждым увеличением разрешения) Я надеялся, что смогу удвоить свое текущее воспроизводимое разрешение. (256x256)

Должен ли я вызывать BufferSubData очень часто или BufferData один раз за кадр? Должен ли я отбросить VBO и перейти с массивом вершин?

Что можно сделать с видеокартами, которые не поддерживают VBO?

(Примечание: каждый блок больше одного пикселя)

Ответы [ 2 ]

5 голосов
/ 26 октября 2011

Прежде всего, вы должны прекратить использовать обе функции.Буферные объекты были основной функциональностью OpenGL с 2002 года;нет никаких оснований использовать их расширение формы.Вы должны использовать glBufferData и glBufferSubData, а не версии ARB.

Во-вторых, если вы хотите высокопроизводительную потоковую передачу объектов буфера, подсказки можно найти в OpenGL wiki .Но в целом, вызов glBufferSubData много раз за кадр в одной и той же памяти бесполезен.Вероятно, было бы лучше отобразить буфер и изменить его напрямую.

К вашему последнему вопросу я бы сказал следующее: почему вас это должно волновать?Как указывалось ранее, объекты буфера старые .Это все равно, что спросить, что вы должны сделать для оборудования, которое поддерживает только D3D 5.0.

Игнорировать это;никто не будет заботиться.

3 голосов
/ 26 октября 2011

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

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

Лучшая стратегиябудет звонить glDraw(Elements|Arrays|Whatever) с последующим glBufferData(...NULL).Это говорит OpenGL, что вы больше не заботитесь о буфере, и он может выбросить содержимое, как только завершит рисование (когда вы отобразите этот буфер или скопируете в него сейчас, OpenGL будет тайно использовать новый буфер, не сообщая вамТаким образом, вы можете работать с новым буфером, пока старый не завершил рисование, это позволяет избежать задержки).

Теперь вы запускаете физическую симуляцию и изменяете данные о цвете так, как хотите.Как только вы закончите, либо glMapBuffer, memcpy и glUnmapBuffer, либо просто используйте glBufferData (отображение иногда лучше, но в этом случае оно должно иметь мало или вообще не иметь значения). Это данные, которые вы нарисуете в следующем кадре .Наконец, поменяйте местами буферы.

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

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

Конечно, существуют реализации, которые не поддерживают VBO, но они должны быть действительно старыми (например, 10+ лет).старые) драйверы.Реально не о чем беспокоиться.

...