Я работаю над проектом, который требует рисования большого количества данных, поскольку он приобретается АЦП... что-то вроде 50 000 строк на кадр на мониторе с разрешением 1600 пикселей в ширину. Он отлично работает на системе с Quadro FX 570 2007 года, но в принципе не может справиться с данными на машинах с чипами класса Intel HD 4000. Нагрузка данных составляет 32 канала с 200 Гц данными, полученными партиями по 5 отсчетов на канал 40 раз в секунду. Таким образом, другими словами, карта должна достигать 40 кадров в секунду или лучше.
Я использую один VBO для всех 32 каналов с пространством для 10000 вершин каждый. VBO по существу обрабатывается как серия кольцевых буферов для каждого канала. Когда данные поступают, я делюминирую их на основе используемого временного масштаба. Таким образом, в основном, он отслеживает мин/макс для каждого канала. Когда для столбца с одним пикселем получено достаточно данных, он устанавливает следующие две вершины в VBO для каждого канала и отображает новый кадр.
Я использую glMapBuffer() для доступа к данным один раз, обновления всех каналов, использования glUnmapBuffer, а затем рендеринга при необходимости.
Я вручную вычисляю матрицу преобразования заблаговременно (используя орфографическое преобразование, вычисленное с помощью не общего способа сокращения умножений), а вершинный шейдер выглядит следующим образом:
#version 120
varying vec4 _outColor;
uniform vec4 _lBound=vec4(-1.0);
uniform vec4 _uBound=vec4(1.0);
uniform mat4 _xform=mat4(1.0);
attribute vec2 _inPos;
attribute vec4 _inColor;
void main()
{
gl_Position=clamp(_xform*vec4(_inPos, 0.0, 1.0), _lBound, _uBound);
_outColor=_inColor;
}
Униформа _lBound
, _uBound
и _xform
обновляется один раз на канал. Итак, 32 раза за кадр. Зажим используется для ограничения некоторых каналов на диапазон y-координат на экране.
Фрагментный шейдер просто:
#version 120
varying vec4 _outColor;
void main()
{
gl_FragColor=_outColor;
}
Есть другие вещи, которые отображаются на экране; канальные метки, например, с использованием квадроциклов и текстурного атласа; но профилирование в gDEBugger, по-видимому, указывает на то, что рендеринг строк занимает подавляющее большинство времени на кадр.
Тем не менее, 50 000 строк не кажутся мне ужасно большим числом.
Итак, после всего этого возникает вопрос: есть ли уловки для ускорения рисования линии? Я попытался сделать их в буфер трафарета, а затем обрезать один квад, но это было медленнее. Я думал о том, как рисовать линии текстуры, рисовать квадрат с текстурой. Но это не кажется масштабируемым или даже более быстрым из-за постоянной загрузки больших текстур. Я видел технику, которая хранит значения y в текстуре одной строки, но это больше похоже на оптимизацию памяти, а не на оптимизацию скорости.