Я использую OpenGL ES 2.0, но я думаю, что он также актуален для не-ES: как узнать, какое «использование» выбрать при создании VBO?
Этот конкретный VBO будет использоваться от 1 до 4 раз перед полным обновлением, и я не уверен, должен ли я выбрать GL_STREAM_DRAW или GL_DYNAMIC_DRAW.
В соответствии с OpenGL API вы должны использовать DYNAMIC_DRAW .
STREAM
Вы должны использовать STREAM_DRAW, когда содержимое хранилища данных будет изменено один раз и использовано самое большее несколько раз.
STATIC
Используйте STATIC_DRAW, когда содержимое хранилища данных будет изменено один раз и использовано много раз.
DYNAMIC
Используйте DYNAMIC_DRAW, когда содержимое хранилища данных будет неоднократно изменяться и использоваться много раз.
Обязательно обновите VBO с помощью glBufferSubData ()
Помимо ответов, которые были даны до сих пор, и хотя это не имеет прямого отношения к GLES, я бы хотел вставить этот бит из выпуска 2 расширения ARB_buffer_storage
(вводится вместе с рабочим столом GL 4.4) :
2) Новые флаги не отображаются напрямую в параметр для glBufferData, и один не может быть выражен через другой. Имеет ли это значение?
Большинство приложений ошибаются
usage
, и в любом случае они только подсказки. Флаги - это жесткие и быстрые правила, которые необходимо соблюдать. Они служат другой цели. Идея здесь состоит в том, чтобы позволить реализации не пытаться угадать приложение и выполнять меньшее отслеживание, и чтобы приложение имело больший контроль. Мы определяем BufferData в терминах BufferStorage с наиболее либеральными допустимыми флагами (по сути, все идет), но все же передаем подсказку реализации, чтобы она продолжала в дальнейшем угадывать приложение.
Проблема с этими флагами всегда заключалась в том, что каждая реализация может иметь разные идеи о том, как оптимизировать различные пути, предлагаемые подсказкой об использовании, и каждое приложение, похоже, имеет разные ожидания того, как работает эта оптимизация.
Драйвер GL рабочего стола Nvidias в профиле отладки напечатает некоторые решения, которые он принял для объектов буфера, особенно если они хранятся в ОЗУ клиента или непосредственно в графическом процессоре. Играя с этим, я получил следующее:
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in HOST memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in VIDEO memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in HOST memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in SYSTEM HEAP memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Здесь я использовал PBO для потоковой передачи обновлений текстуры в графический процессор, с одним обновлением на кадр через отображение буфера. Естественным выбором здесь было бы использование GL_STREAM_DRAW
, но я указал GL_STATIC_DRAW
. Драйвер сначала дал мне некоторый буфер с резервной копией VRAM и сделал отображение ввода / вывода для первых двух обновлений, которые я сделал. Но затем он передумал и использует буфер, поддерживаемый клиентом, - давая мне именно тот результат, который я получил бы, если бы сначала попросил GL_STREAM_DRAW
. То, что мы видим здесь, является примером для second guessing
, о котором был процитирован текст выше.
Все это сильно зависит от реализации. И это также одна из причин, по которой было создано вышеупомянутое расширение GL, которое даст программисту гораздо больший контроль над такими вещами. Однако, насколько мне известно, это расширение недоступно в сфере OpenGL ES.