Ответ 1
Вторая невероятно эффективна.
Изменение состояний, в частности преобразований и матриц, приводит к перерасчету других состояний и, как правило, большей математике.
Обновление геометрии, однако, просто включает перезапись буфера.
С современным видеооборудованием на довольно массивных шинах с пропускной способностью, отправка нескольких поплавков через тривиальную. Они предназначены для быстрого перемещения тонны данных, что является побочным эффектом работы. Обновление буферов вершин - это именно то, что они делают часто и быстро. Если мы принимаем точки по 32 байта каждый (позиция и цвет float4), 100000 сегментов линии меньше 6 МБ, а PCIe 2.0 x16 составляет около 8 ГБ/с, я полагаю.
В некоторых случаях, в зависимости от того, как преобразовывается драйвер или карта, изменение может привести к некоторому умножению матрицы и пересчету других значений, включая трансформирование, отбраковка и обрезку самолетов и т.д. Это не проблема, если вы измените состояние, нарисуйте несколько тысяч полисов и повторите, но когда изменения штата часто происходят, у них будет значительная стоимость.
Хорошим примером этого, который ранее был решен, является концепция дозирования, сводящая к минимуму изменения состояния, поэтому между ними может быть проведена большая геометрия. Это используется для более эффективного рисования больших объемов геометрии.
В качестве очень ясного примера рассмотрим наилучший вариант для # 1: преобразовать триггеры без дополнительных вычислений и буфферы драйвера усердно и отлично. Чтобы нарисовать 100000 строк, вам нужно:
- 100000 наборов матриц (в системной памяти)
- 100000 матричных вызовов с функцией служебных вызовов функций (к видеодрайверу, копирование матрицы в буфер там)
- 100000 матриц, скопированных в видеопамять, выполняются в одном куске
- 100000 вызовов рисования линии
Одна только функция служебного вызова функции будет убивать производительность.
С другой стороны, пакетная обработка включает в себя:
- 100000 точек вычислений и наборов, в системном ОЗУ
- 1 копия vbo в видеопамять. Это будет большой кусок, но один непрерывный кусок и обе стороны знают, чего ожидать. Его можно обработать хорошо.
- 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);