OpenGL — правильно обновляет привязку Vertex Buffer объекта Vertex Array

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

while(RUN){
updateBuffers();//updates VAO
drawThis();//binds and unbinds VAO
drawThat();//binds and unbinds VAO -> OpenGL Invalid Operation error at draw call
}

Тогда как это работает:

while(RUN){
updateBuffers();//updates VAO
drawThis();//binds and unbinds VAO
updateBuffers();//updates VAO
drawThat();//binds and unbinds VAO -> works
}

Также это не работает:

updateBuffers();
while(RUN){
drawThis();//OpenGL Invalid Operation error in second frame
}

но это будет работать

updateBuffers();
glBindVertexArray(VAO);
while(RUN){
drawThis();//only makes the draw call
}
glBindVertexArray(0);

… но это не вариант, потому что я также хочу использовать другие VAO в моем цикле кадров (и я хотел бы оставаться гибким с заказом).

Так что эти функции делают внутри?

draw функции просто связывают VAO и шейдер, делают вызов отрисовки (обычно glDrawElementsInstanced) а затем отвяжите шейдер и VAO.

updateBuffers функция обычно пишет в буферный объект (инициализируется с glNamedBufferStorageчерез указатель, который отображает весь буфер, используя GL_MAP_WRITE_BIT, GL_MAP_PERSISTENT_BIT а также GL_MAP_COHERENT_BIT флаги. Чтобы гарантировать, что я не перезаписываю какие-либо данные, которые все еще используются GPU, я всегда пишу в другой раздел буфера. Поэтому перед каждым обновлением я увеличиваю смещение записи на размер предыдущего обновления (или устанавливаю его равным 0, если обновление превышает размер хранилища).

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

Это всегда хорошо работает для одинаковых привязок буфера (смещение обновляется с glBindBufferRange) но когда я обновляю привязку для буфера вершин VAO (с glVertexArrayVertexBuffer), а затем связать и открепить, что ВАО более одного раза, прежде чем звонить glVertexArrayVertexBuffer снова я получаю Invalid Operation ошибка.

Почему glVertexArrayVertexBuffer заставить ВАО вести себя так? Каков будет правильный подход для обновления смещения привязки VAO к буферу вершин?

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]