Я заметил, что если я не перезвоню VertexAttribPointer, там не войдут в шейдеры после BindBuffer. Это необходимо? Шейдеры могут не меняться в письменной форме, а используются только используемые буферы.
Нужен ли VertexAttribPointer после каждого BindBuffer?
Ответ 1
tibur уже ответил на фактический вопрос, но я подумал, что добавлю какой-то контекст.
glBindBuffer(GL_ARRAY_BUFFER, ...)
сам по себе ничего не делает. Подумайте об этом как о дополнительном аргументе glVertexAttribPointer
.
Помните, что вы можете связывать несколько буферов с разными атрибутами (например, атрибут 0 использует vbo 1, а атрибут 1 и 2 - vbo 2). Какой API-код вы бы указали для этой настройки?
С фактическим API, это что-то вроде:
glBindBuffer(GL_ARRAY_BUFFER, 1);
glVertexAttribPointer(0, ...)
glBindBuffer(GL_ARRAY_BUFFER, 2);
glVertexAttribPointer(1, ...)
glVertexAttribPointer(2, ...)
glDraw*(...)
Почему спецификация работает именно так? Ну, это обратная совместимость, поднимающая голову. Когда вводились VBOs, glVertexPointer
et al. не было никакого параметра для передачи того, какой буферный объект использовать. Либо было много новых точек входа для каждой семантики (VertexPointer/NormalPointer/TexCoordPointer...), либо это была дополнительная точка входа сама по себе, которая просто выступала в качестве дополнительного параметра для вызовов * Указатель. Они выбрали последний (как примечание, это также означает, что вам нужно передать смещение внутри буфера в качестве указателя).
Ответ 2
Согласно OpenGL спецификации OpenGL, стр. 51 (состояние объекта буфера), состояние, соответствующее указателям массива, хранит идентификатор буфера. Это означает, что если вы хотите изменить объект-буфер для рисования, вам нужно вызвать функцию glVertexAttribPointer
.
glBindBuffer(1);
glVertexPointer(...);
glDrawArrays(...); /// Drawing will use buffer 1
glBindBuffer(2);
glDrawArrays(...); /// Drawing will still use buffer 1
glVertexPointer(...);
glDrawArrays(...); /// Drawing will now use buffer 2