Не нужно много предисловия, кроме того, что это используется в / для системы частиц, которая использует обратную связь преобразования. Есть два vbos, которые я пинг понг между циклами рендеринга. Вот начальная настройка буфера:
glGenBuffers(1, &p_vbo_r); glBindBuffer(GL_ARRAY_BUFFER, p_vbo_r);
glBufferData(GL_ARRAY_BUFFER, (MAX_PARTICLES*2) * sizeof(particle), &pp[0], GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &p_vbo_w); glBindBuffer(GL_ARRAY_BUFFER, p_vbo_w);
glBufferData(GL_ARRAY_BUFFER, (MAX_PARTICLES*2) * sizeof(particle), &pp[0], GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
MAX_PARTICLES
установлен на 262144. particle
это структура, которая содержит 2 glm::vec3
и 2 GLfloat
в общей сложности до 32 байт, поэтому моя текущая установка создает буферы размером чуть более 16 МБ. pp
является массивом, содержащим данные фиктивных частиц, поскольку прямые нули не так сильно выделяются при использовании gDebugger.
glBindBuffer(GL_ARRAY_BUFFER, p_vbo_r);
glBufferSubData(GL_ARRAY_BUFFER, total_part*sizeof(particle), pp.size() * sizeof(particle), &pp[0]);
glBindBuffer(GL_ARRAY_BUFFER, p_vbo_w);
glBufferSubData(GL_ARRAY_BUFFER, total_part*sizeof(particle), pp.size() * sizeof(particle), &pp[0]);
p.buf_start = total_part;
total_part += pp.size();
Это происходит каждый раз, когда в систему частиц добавляется уникальный излучатель. Все возможные излучатели в данной сцене добавляются перед выполнением любого рендеринга (в настоящее время), и это на самом деле работает, как и предполагалось! Он сохраняет смещение, используемое при добавлении эмиттера в p.buf_start, когда это сделано, и добавляет к рабочему смещению.
Теперь, как ни странно, использование того же самого параметра позже во время рендеринга / выполнения заставляет команду glBufferSubData начинаться с 0, а не с предоставленного смещения, как показано ниже:
glBindBuffer(GL_ARRAY_BUFFER, p_vbo_r);
glBufferSubData(GL_ARRAY_BUFFER, p_sys[i].buf_start * sizeof(particle), pp.size() * sizeof(particle), &pp[0]);
glBindBuffer(GL_ARRAY_BUFFER, p_vbo_w);
glBufferSubData(GL_ARRAY_BUFFER, p_sys[i].buf_start * sizeof(particle), pp.size() * sizeof(particle), &pp[0]);
Это делается в цикле, который проверяет, нуждается ли буфер в перезагрузке, и делает это. Любой субъект может запросить сброс в любое время после рендеринга, и буфер выполняет вышеуказанный код после завершения фрейма, но до того, как следующий фрейм начнет рендеринг. Первый из перечисленных излучателей работает, как предполагалось, но впоследствии любой излучатель всегда перезаписывает VBO с 0, а не с заданным смещением. Не могу ли я перезаписать буферы пинг-понга, участвующие в обратной связи преобразования? Было немного сложно понять это. Спасибо!
РЕДАКТИРОВАТЬ: я также попытался GL_DYNAMIC_DRAW / GL_STATIC_DRAW для начальной настройки буфера безрезультатно.
Задача ещё не решена.
Других решений пока нет …