OpenGL 2.1: субрегион повторной буферизации в VBO

У меня есть сетка ландшафта, хранящаяся в VBO. Сетка представляет собой сетку, состоящую из прямоугольных треугольников. Другими словами, это выглядит как прямолинейная сетка с диагоналями. Ширина и высота меша известны, поэтому легко вычислить индексы вершин для заданного XY или наоборот.

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

Первое, что приходит на ум, это glBufferSubData. Но я не могу придумать способ выложить свой VBO так, чтобы glBufferSubData влиял только на грязные вершины. Например, предположим, что моя сетка имеет размер 5 x 5 вершин. (На самом деле он был бы намного больше; это просто пример.) Вот так:

 0  1  2  3  4
 5  6  7  8  9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24

(Каждое число на диаграмме выше представляет собой смещение вершины от начала VBO.)

Предположим, что область 3 x 3 в центре нуждается в повторной буферизации. Это означает, что я хочу поразить вершины 6, 7, 8, 11, 12, 13, 16, 17 и 18. Поэтому я мог бы вызвать glBufferSubData, начиная с индекса 6 и заканчивая 18:

  0   1   2   3   4
  5  *6  *7  *8  *9
*10 *11 *12 *13 *14
*15 *16 *17 *18  19
 20  21  22  23  24

(На приведенной выше диаграмме вершины, отмеченные *, повторно буферизуются.)

Обратите внимание, что вершины 10, 14 и 15 не грязные, и все же они подвергаются повторной буферизации, потому что они находятся в диапазоне, указанном для glBufferSubData. Это кажется мне неэффективным. Для большой сетки я бы в большинстве случаев повторно буферизировал больше данных, чем мне нужно.

Есть ли известное решение этой проблемы? Должен ли я вызывать glBufferSubData один раз для каждой строки (что решило бы существующую проблему, но привело бы к собственным накладным расходам)? Или стандартно просто буферизовать весь диапазон и съесть стоимость ненужной записи?

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


person rlkw1024    schedule 04.01.2012    source источник


Ответы (1)


Вы должны использовать буферный объект отображение. Вы можете получить доступ к объекту буфера как к массиву памяти, действительно обращаясь к разреженным вершинам. Драйвер (надеюсь) оптимизирует его для вас.

Использование GL_DYNAMIC_DRAW правильно.

person Luca    schedule 05.01.2012