Это сложный вопрос с множеством мелких деталей, которые действительно важны, производительность зависит от платформы и приложения. Поэтому вы должны определить возможные узкие места, прежде чем инвестировать в оптимизацию.
Тем не менее, во-первых, я предполагаю, что вы должны максимально уменьшить количество загрузок и обновлений, например, использовать экземпляры.
Во-вторых, обратите внимание, что графические процессоры не могут передавать буферы и визуализировать одновременно, поэтому все команды OpenGL в очереди команд обрабатываются устройством последовательно. Есть разные способы скопировать данные и / или сделать их доступными для использования графическим процессором.
Существуют различные способы потоковой передачи данных в графический процессор
1- glBufferData
или glBufferSubData
метод
Использование glBufferData
или glBufferSubData
как memcpy. Вы передаете указатель, и операция DMA может быть выполнена, я сказал, может, потому что память может быть закреплена в памяти процессора и использоваться непосредственно GPU без фактической передачи памяти в GPU, в зависимости от флага использования (GL_STREAM). По мнению, вы должны попробовать это сначала, потому что это проще реализовать.
2- получение указателя на внутреннюю память с использованием glMapBuffer
Если вышеприведенное не достаточно хорошо, что вы можете использовать glMapBuffer
, вы получаете указатель на внутреннюю память, и вы можете использовать этот указатель для непосредственного заполнения буфера, это хорошо для операций чтения и записи файла, так как вы можете напрямую отобразить данные файла в память GPU, а не копировать во временный буфер. Если вы не хотите отображать весь буфер, вы можете использовать glMapBufferRange
его для отображения части буфера.
Одна хитрость - создать большой буфер, использовать первую половину для рендеринга, а вторую - для обновления.
3- Буфер сирот
Что касается потерянного буфера, это можно сделать, используя glBufferData со значением null и теми же параметрами, что и у него. Драйвер вернет блок памяти, если он не используется. И будет использоваться при следующем вызове glBufferData (новая память не будет выделена).
Все упомянутые методы вызывают много дорогой синхронизации, опять же, графические процессоры не могут передавать буферы и визуализировать одновременно.
4- Unsynchronized Buffers
Самый быстрый (и самый трудный для понимания) метод - использовать буферы без синхронизации, с которой вы можете использовать GL_MAP_UNSYNCHRONIZED_BIT
флаг glMapBufferRange
, проблема в том, что синхронизация не выполняется, поэтому мы можем загрузить данные в буфер, который будет использоваться, и, следовательно, все испортить. Вы можете использовать несколько буферов с несинхронизированным битом, чтобы сделать вещи немного проще.