нужен VertexAttribPointer после каждого BindBuffer? - PullRequest
10 голосов
/ 08 сентября 2010

Я заметил, что если я не перезвоню VertexAttribPointer, после BindBuffer не будет ввода в шейдеры.Это необходимо?Шейдеры могут не изменяться при записи, а только используемые буферы.

Ответы [ 2 ]

24 голосов
/ 08 сентября 2010

Тибур уже ответил на реальный вопрос, но я подумал, что добавлю некоторый контекст.

glBindBuffer(GL_ARRAY_BUFFER, ...) само по себе не делает ничего.Думайте об этом как о дополнительном аргументе glVertexAttribPointer.

Помните, что вы можете привязать несколько буферов к различным атрибутам (скажем, attrib 0 использует vbo 1, а attrib 1 и 2 используют vbo 2).Какой порядок API вы бы увидели для этой установки?

С настоящим API это что-то вроде:

glBindBuffer(GL_ARRAY_BUFFER, 1);
glVertexAttribPointer(0, ...)
glBindBuffer(GL_ARRAY_BUFFER, 2);
glVertexAttribPointer(1, ...)
glVertexAttribPointer(2, ...)

glDraw*(...)

Почему спецификация будет работать таким образом?Ну, это обратная совместимость, поднимая голову.Когда были введены VBO, glVertexPointer et al.не было никакого параметра для передачи, какой буферный объект использовать.Либо это было много новых точек входа для каждой семантики (VertexPointer / NormalPointer / TexCoordPointer ...), либо это была отдельная дополнительная точка входа, которая просто действовала как дополнительный параметр для вызовов * Pointer.Они выбрали последнее (в качестве примечания, по этой же причине вам нужно передать смещение внутри буфера в качестве указателя).

13 голосов
/ 08 сентября 2010

Согласно 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
...