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