Задержка перед рендерингом проблемы с использованием OpenGL сохранения и рендеринга используется - PullRequest
0 голосов
/ 03 мая 2020

Я создал вычислительную программу c ++ с использованием GLFW OpenGL, которая вычисляет простую физику гравитации на частицах в течение заранее определенного периода времени, сохраняя вычисленные результаты в стандартном GL_ARRAY_BUFFER. Это настраивается стандартным способом:

glGenBuffers(1, &vboSTATE);
glBindBuffer(GL_ARRAY_BUFFER, vboSTATE);
int bufferSize = (pCount * (4 * sizeof(GLfloat))) * (totalSteps);
glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_DYNAMIC_DRAW);

Данные сохраняются с использованием glCopyBufferSubData для получения данных, передаваемых между буферами GPU.

По истечении времени моделирования результаты (позиции) обрабатываются с помощью простого вызова отрисовки следующим образом, циклически перебирая записанные данные пошагово:

glDrawArrays(GL_POINTS, step, particleCount);

«шаг» - физический шаг для рендеринга в текущем кадре Перед началом рендеринга l oop существует пауза, которая является линейной по отношению к количеству частиц. При использовании 1 частицы задержка, по-видимому, исчезает, 100, а задержка составляет около 5 секунд, 1000 частиц, и задержка находится в районе минуты или около того и может даже зависнуть и взломать sh программу.

Единственное, что я замечаю, это то, что размер буфера увеличивается с увеличением количества частиц в симуляции, но это не то, о чем я бы подумал - безумно - менее 1 МБ на 100 частиц.

У меня была предыдущая программа он вычислял и рендерил в режиме реального времени в пределах одного кадра, но количество частиц было ограничено (я надеюсь получить тысячи в конце), но никаких задержек не было. Это произошло, когда я перешел к этой программе стилей отображения после решения.

Есть идеи? Спасибо,

Ответы [ 2 ]

2 голосов
/ 03 мая 2020

Чтобы прочитать данные, записанные CS, эти данные должны быть получены. И чем больше данных нужно будет получить, тем дольше это займет. И поэтому, чем дольше они будут находиться между командами записи и чтения.

Операция копирования в буфер, которую вы изложите, бессмысленна. Буферные объекты OpenGL не имеют типа. Можно использовать буфер как SSBO в одной операции на 100%, а затем присоединить его к VAO для использования в качестве исходного массива данных вершин для другой операции.

Теперь, поскольку запись в SSBO использует некогерентная запись , вам понадобится соответствующий glMemoryBarrier между записью и операцией рендеринга, которая использует буфер. Но вам все равно нужен был один из них между записью и буферной копией.

0 голосов
/ 04 мая 2020

Эта проблема была решена с помощью glFini sh () после каждой операции копирования, чтобы гарантировать фактическое копирование данных. Я нашел решение с помощью предложений, предоставленных сообществом здесь. Это значительно увеличивает l oop раз, но, по крайней мере, вы точно знаете, что openGL закончил запись и данные готовы к использованию ...

Спасибо всем!

...