Лучший способ нарисовать точечный график с большим количеством точек данных на C++ с использованием OpenGL

Я пишу программу на С++, которая получает данные 4-х мерных точек через сокет UDP, а затем отображает данные в 6 отдельных 2D-диаграммах рассеяния. Например, если мы назовем размеры: A, B, C, D, шесть 2D-графиков будут AxB, AxC, AxD, BxC, BxD и CxD. В течение нескольких часов программа набирает ~50 тысяч баллов.

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

Я думал о поддержке массива вершин (с двумя измерениями) для каждой системы координат, но для этого потребовалось бы 6 отдельных массивов и в 3 раза больше памяти, чем для поддержки массива со всеми четырьмя измерениями.

Правильно ли я думаю об этом? Каково правильное решение этой проблемы?

Конечная цель — иметь приложение, отображающее данные как можно ближе к реальному времени.

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


person slayton    schedule 03.08.2011    source источник


Ответы (1)


Использование объектов буфера вершин может увеличить скорость рендеринга, поскольку геометрия для рисования может храниться непосредственно в памяти графической карты. Однако в вашем случае, если данные всегда меняются, я не могу сказать вам, будет ли этот метод быстрее, чем немедленный режим, потому что вам, возможно, придется реконструировать объект массива вершин каждый раз, когда данные изменяются. Если вы только добавляете точки, возможно, вы можете создать несколько VBO для группировки точек и визуализировать последние полученные точки, используя немедленный режим, пока вы не сможете создать новую группу. Например, если вы получили 100 054 точки, возможно, вы можете сделать 10 групп по 10 000 точек и визуализировать последние 54 точки в непосредственном режиме.

Что касается проблемы с памятью, я думаю, что можно было бы хранить в графической карте вершины с 4 элементами - тогда вы могли бы использовать разные вершинные шейдеры, которые выбирают, какие компоненты вашей вершины использовать в качестве координат рендеринга. Используя этот метод, использование памяти будет вдвое больше, чем вы получили: один для полученных вами данных и один для объекта буфера вершин.

person neodelphi    schedule 03.08.2011
comment
VBO должны быть, по крайней мере, не медленнее, чем массивы на стороне клиента, и определенно быстрее, чем немедленный режим. VBO (и массивы вершин в целом) предназначены не только для копирования памяти, но и для вызова драйвера. - person Christian Rau; 03.08.2011
comment
Вероятно, можно было бы обойтись изменением аргументов stride и pointer на glVertexPointer вместо того, чтобы иметь разные вершинные шейдеры для разных представлений. - person user786653; 03.08.2011
comment
@Christian Спасибо за ваш комментарий, я не был уверен в этом. - person neodelphi; 03.08.2011
comment
@user786653 user786653 Не уверен, в случае, когда он использует координаты A и D, я не знаю, как он мог пропустить координаты B и C. Возможно, использование юниформ-атрибутов поможет использовать один шейдер (выбор будет сделан шейдером с использованием заданных атрибутов), но это может быть не так быстро, как использование нескольких шейдеров). - person neodelphi; 03.08.2011
comment
@neodelphi: К сожалению, вы правы, я поторопился. Я согласен, что шейдер - лучший выбор. (Еще одна, возможно, глупая идея, чтобы избежать шейдеров, может состоять в том, чтобы использовать 4-координатный вектор и просто иметь соответствующие матрицы вида/проекции 4x4 для этого вида, обнуляя B&c в случае A&D.) - person user786653; 03.08.2011
comment
Буферы могут быть сопоставлены. Если добавляются точки, отправляется только разница. По возможности следует избегать немедленного режима. - person Luca; 03.08.2011
comment
@Luca Как openGl обнаруживает разницу или нам нужно сообщить ему вручную? Это интересно. - person neodelphi; 03.08.2011
comment
@neodelphi Вы можете использовать расширение glBufferSubData или map_buffer_range, чтобы драйвер мог оптимизировать это и копировать только то, что необходимо. - person Christian Rau; 03.08.2011
comment
@Christian Спасибо, не знал, отличные новости! Думаю, мне понравятся такие функции. - person neodelphi; 03.08.2011