Второй невероятно эффективнее.
Изменение состояний, особенно преобразований и матриц, приводит к пересчету других состояний и, как правило, к большей математике.
Обновление геометрии, однако, просто включает перезапись буфера.
При использовании современного видеооборудования на довольно большой полосе пропускания передача нескольких потоков является тривиальной. Они предназначены для быстрого перемещения тонны данных, это побочный эффект работы. Обновление вершинных буферов - это именно то, что они делают часто и быстро. Если мы предположим, что у каждого по 32 байта (позиция и цвет float4), 100000 линейных сегментов меньше 6 МБ, а PCIe 2.0 x16 - около 8 ГБ / с, я полагаю.
В некоторых случаях, в зависимости от того, как драйвер или карта обрабатывает преобразования, его изменение может привести к некоторому умножению матрицы и пересчету других значений, включая плоскости преобразования, отбраковки и отсечения и т. Д. Это не проблема, если изменить состояние, нарисуйте несколько тысяч полисов, и повторите, но когда изменения состояния часто, они будут иметь значительную стоимость.
Хорошим примером того, как это было решено ранее, является концепция пакетирования, минимизирующая изменения состояния, чтобы между ними можно было нарисовать больше геометрии. Это используется для более эффективного рисования большого количества геометрии.
В качестве очень ясного примера рассмотрим лучший вариант для # 1: набор преобразований не вызывает дополнительных вычислений, а драйвер буферизует усердно и идеально. Чтобы нарисовать 100000 линий, вам нужно:
- 100000 матричных наборов (в системной памяти)
- 100000 вызовов набора матриц с накладными расходами вызовов функций (для видеодрайвера, копирование матрицы в буфер)
- 100000 матриц, скопированных в ОЗУ видео, выполненных за один прием
- 100000 звонков на линии
Только накладные расходы на вызов функции приведут к уничтожению производительности.
С другой стороны, пакетирование включает в себя:
- 100000 точечных вычислений и наборов в оперативной памяти системы
- 1 VBO скопировать в видео RAM. Это будет большой кусок, но один непрерывный кусок, и обе стороны знают, чего ожидать. С ним можно хорошо обращаться.
- 1 матричный набор вызовов
- 1 матричная копия в видео ОЗУ
- 1 розыгрыш
Вы копируете больше данных, но есть большая вероятность, что содержимое VBO все же не так дорого, как копирование матричных данных. Кроме того, вы экономите огромное количество процессорного времени на вызовах функций (от 200000 до 2). Это упрощает жизнь вам, драйверу (который должен буферизовать все и проверять избыточные вызовы, а также оптимизировать и обрабатывать загрузку) и, возможно, также видеокарте (которую, возможно, пришлось пересчитать). Чтобы сделать это действительно понятным, представьте для него простой код:
1
for (i = 0; i < 100000; ++i)
{
matrix = calcMatrix(i);
setMatrix(matrix);
drawLines(1, vbo);
}
(теперь разверните это)
* 2 * тысяча сорок-девять:
matrix = calcMatrix();
setMatrix(matrix);
for (i = 0; i < 100000; ++i)
{
localVBO[i] = point[i];
}
setVBO(localVBO);
drawLines(100000, vbo);