Возможно ли изменить размеры VBO на месте?

Название говорит все, но для того, чтобы быть ясным, я добавлю дополнительные слова.

В этом случае изменение размера означает:

  • получить больше места для хранения в конце старого vbo
  • сохранение старых данных на передней панели
  • (надеюсь, что не копируем, но по крайней мере не на стороне процессора, то есть драйвер должен справиться с этим)

ИЗМЕНИТЬ

Как объяснить некоторые подробности и оправдать мой вопрос:
Я буду хранить данные (в forehand) неизвестного размера для VBO, но я знаю только верхний предел, который является очень грубой оценкой (в 10 - 100 раз больше или даже больше в необычных условиях).

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

Вот почему я не хочу копировать (особенно на стороне процессора):
Я делаю все это на GPU, чтобы получить интерактивные частоты кадров. Когда мне приходится копировать, это очень медленно или даже невозможно, потому что места недостаточно. Хуже всего копировать данные по процессору, следовательно, передавать все по шине, в новую область памяти с достаточным размером, а затем glBufferData с VBO с новым размером и новой областью памяти в качестве источника. Это будет убийца производительности.

обойдена

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

Ответ 1

Я думаю, что без выполнения копии вы не обойдетесь, потому что единственный способ изменить размер буфера - вызвать glBufferData, и IMO не сможет сказать драйверу сохранить старые данные.

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

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

Ответ 2

Повторяя этот вопрос через несколько лет, пейзаж немного изменился с новыми версиями и расширениями.

Копирование на GPU

Расширение, упомянутое в ответе Christian Rau, является ключевым с 3.1, которое позволяет нам копировать содержимое (через glCopyBufferSubData) от одного VBO к другому, Надеюсь, драйвер сделает это на стороне GPU!

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

Истинное изменение размера

Хорошая новость: с разреженные буферы еще лучшее решение находится на горизонте.

Учитывая это расширение, мы можем выделить виртуальный буфер с более чем достаточным пространством для наших данных, не заплатив за ненужное пространство. Нам нужно только "зафиксировать" области памяти, которые мы физически хотим хранить в данных. Это означает, что мы можем "вырастить" VBO, совершая новые страницы в конце.

Плохая новость: с текущей версии OpenGL (4.5) это все еще расширение и еще не ядро, поэтому принятие этого может оказаться невозможным. Вы также не должны указывать некоторые детали в спецификации, которые еще не разработаны. Например, отображение разреженных буферов запрещено в текущем расширении, но поддержка может быть добавлена ​​в будущих версиях.

Я бы очень хотел услышать о доступности этого расширения, если у вас есть данные об этом.

Ответ 3

Предполагая, что у вас есть поддержка недавнего стандарта OpenGL, альтернативой VBOs может быть сохранение ваших данных в текстурах (опять же, если у вас на карте достаточно памяти). Копирование данных между старыми и новыми текстурами будет происходить на карте и не влияет на передачу данных.

Именно то, как вы достигаете этого, зависит от того, что именно делает ваш код. Но в принципе вы используете данные текстуры для перезаписи фиктивных данных вершин в ваших вызовах рисования или, может быть, использования instancing. Это потребует много размышлений и доработки.