Ускорение ввода-вывода приложения OpenGL - PullRequest
2 голосов
/ 03 августа 2010

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

Что мне нужно сделать для каждого кадра, так это загрузить большое облако точек, сохраненное в памяти, затем рассчитать карту цветов по высоте (я использую что-то похожее на карту струй Matlab), а затем перенести данные в графический процессор. Это отлично работает при захвате облаков с точками <миллион. Тем не менее, примерно в 2 миллиона точек, это начинает замедляться ниже 30 кадров в секунду. Я понимаю, что это много данных (2 миллиона кадров на точку * [3 плавающих на точку + 3 плавающих на цветную точку] * * 4 байта на плавающий * 30 кадров в секунду = <strong>около 1,34 гигабайта в секунду )

Мой код рендеринга сейчас выглядит примерно так:

glPointSize(ptSize);
glEnableClientState(GL_VERTEX_ARRAY);
if(colorflag) {
    glEnableClientState(GL_COLOR_ARRAY);
} else {
    glDisableClientState(GL_COLOR_ARRAY);
    glColor3f(1,1,1);
}
glBindBuffer(GL_ARRAY_BUFFER, vbobj[VERT_OBJ]);
glBufferData(GL_ARRAY_BUFFER, cloudSize, vertData, GL_STREAM_DRAW);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbobj[COLOR_OBJ]);
glBufferData(GL_ARRAY_BUFFER, cloudSize, colorData, GL_STREAM_DRAW);
glColorPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_POINTS, 0, numPoints);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Указатель для vertData и colorData изменяется каждый кадр.

То, что я хотел бы иметь, - это возможность проигрывать со скоростью не менее 30 кадров в секунду, даже если позднее используются большие облака точек, которые могут достигать до 7 миллионов точек на кадр. Это вообще возможно? Или, может быть, было бы проще объединить их в сетку, построить карту высот и как-то отобразить это? Я все еще довольно плохо знаком с трехмерным программированием, поэтому любой совет будет оценен.

Ответы [ 5 ]

7 голосов
/ 03 августа 2010

Если можете, реализуйте карту цветов, используя 1D текстуру.Вам понадобится только 1 текстурная координата вместо 3-х цветов, и она также выровняет 128-битные вершины.

РЕДАКТИРОВАТЬ: вам просто нужно создать текстуру из вашей карты цветов и использовать glTexCoordPointer вместо glColorPointer (и изменение вершины)значения цвета для текстурных координат в диапазоне [0, 1], конечно).Вот линейно интерполированная цветовая карта 6 текселей:

// Create texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_1D, texture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// Load textureData
GLubyte colorData[] = {
    0xff, 0x00, 0x00,
    0xff, 0xff, 0x00,
    0x00, 0xff, 0x00,
    0x00, 0xff, 0xff,
    0x00, 0x00, 0xff,
    0xff, 0x00, 0xff
};
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 6, 0, GL_RGB, GL_UNSIGNED_BYTE, colorData);
glEnable(GL_TEXTURE_1D);
4 голосов
/ 03 августа 2010

Я ничего не знаю об opengl, но не будет ли сжатие данных естественным решением?Разве нет поддержки целочисленных типов или 16-битных чисел?Также другие цветовые представления, чем 3 поплавка на точку?

3 голосов
/ 03 августа 2010

Если вы готовы справиться с задержкой, вы можете дважды (или более!) Буферизовать ваши VBO, передавая геометрию в один буфер при рендеринге из другого:

while(true)
{
    draw_vbo( cur_vbo_id );
    generate_new_geometry();
    load_vbo( nxt_vbo_id );
    swap( cur_vbo_id, nxt_vbo_id );
}

РЕДАКТИРОВАТЬ: Вы также можете попробовать чередование ваших вершин вместо использования одного VBO на компонент.

1 голос
/ 03 августа 2010

Вы говорите, что это связано с вводом / выводом. Это означает, что вы профилировали его и видели, что он тратит 50% или более времени в ожидании ввода / вывода.

Если это так, то на этом вы должны сосредоточиться, а не на графике.

Если нет, то некоторые другие ответы звучат хорошо для меня. Независимо от профиля, не угадай . Это метод, который я использую.

0 голосов
/ 03 августа 2010

Некоторые указатели:

  • храните как можно больше данных на графической карте и загружайте только то, что действительно необходимо (довольно очевидно)
  • используйте lod уровни в деревьях (kd- или octtrees) и рассчитывайте как можно больше заранее
  • сжатие на диске также полезно для преодоления узких мест
...