WebGL 2.0: вызов Draw завершается успешно, даже если VBO удален

Итак, я использую VAO для хранения указателей из VBO. Я хотел проверить, что происходит, когда я удаляю свои буферы данных (vbo, ibo и т. д.) перед привязкой VAO и вызовом отрисовки. Поскольку VAO хранят указатели на данные в соответствующих буферах данных, я ожидал сбоя рендерера. Однако все продолжает работать. Как это возможно? Я использую контекст WebGL 2.0. В документации указано, что VAO реализованы в соответствии с документацией OpenGL. Связано ли это с тем, как JavaScript работает с объектами? Возможно, мой vbo где-то кэшируется (по незнанию), прежде чем я вызову для него deleteBuffer. Это возможно? Что здесь происходит?


person SuperTasche    schedule 14.11.2017    source источник


Ответы (1)


Если gl.DeleteBuffers пытается удалить буферный объект, то буферный объект не удаляется, если он присоединен к несвязанному объекту массива вершин. В этом случае имя объекта становится недействительным и он помечается как неиспользуемый:

gl.bindVertexArray( vao );
gl.bindBuffer( gl.ARRAY_BUFFER, vbo );
gl.vertexAttribPointer( ... );
.....
gl.bindVertexArray( 0 );
gl.deleteBuffers( 1, vbo );


Но если объект массива вершин привязан, то буферный объект отсоединяется и удаляется:

gl.bindVertexArray( vao );
gl.bindBuffer( gl.ARRAY_BUFFER, vbo );
gl.vertexAttribPointer( ... );
.....
gl.deleteBuffers( 1, vbo );
gl.bindVertexArray( 0 ); 


См. Спецификацию OpenGL ES 3.2–5.1. 3 Срок службы удаленных объектов и имен объектов, стр. 45:

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

Вложения к несвязанным объектам-контейнерам, такие как удаление буфера, присоединенного к объекту массива вершин, который не привязан к контексту, не затрагиваются и продолжают действовать как ссылки на удаленный объект....

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

person Rabbid76    schedule 14.11.2017
comment
Также к вашему сведению, поведение удаления объектов в OpenGL ES является недостаточно протестированной частью большинства драйверов. Предполагается, что WebGL работает лучше, и для шейдеров/программ было проведено обширное тестирование поведения удаленных шейдеров и программ. Для VAO тоже положено тестировать а вот для WebGL1 не тестировалось.. забыли. Для WebGL2 это проверено, но Chrome еще не проходит тест. Вот ошибка, отслеживающая проблему. - person gman; 14.11.2017
comment
@gman О, я не читал тег WebGL, я только прочитал вопрос, моя вина. Я изменил код и теперь ссылаюсь на OpenGL ES. - person Rabbid76; 14.11.2017
comment
извините, что не прояснил это ... черт возьми, я использую контекст webgl 2.0, однако я тестирую в chrome. спасибо за вклад. - person SuperTasche; 14.11.2017