Желательно, чтобы информация о часто меняющихся цветах обновлялась в вашей собственной копии в ОЗУ и передавала данные в 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+ лет).старые) драйверы.Реально не о чем беспокоиться.