Я был уверен, что если вы привяжете буфер через glBindBuffer()
, вы можете с уверенностью предположить, что он остается связанным, пока цель не отскочит от другого вызова до glBindBuffer()
. Поэтому я был очень удивлен, когда я обнаружил, что вызов glBindVertexArray()
задает буфер, связанный с мишенью GL_ELEMENT_ARRAY 0.OpenGL 3: glBindVertexArray недействителен GL_ELEMENT_ARRAY_BUFFER
Вот минимальный C++ пример кода:
GLuint buff;
glGenBuffers(1, &buff);
std::cout << "Buffer is " << buff << "\n";
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buff);
GLuint vao;
glGenVertexArrays(1, &vao);
GLint bound_buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff);
std::cout << "Bound before glBindVertexArray: " << bound_buff << "\n";
glBindVertexArray(vao);
// ^- an implicit glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); ?
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff);
std::cout << "Bound after glBindVertexArray: " << bound_buff << "\n";
я запускаю этот код сразу после инициализации OpenGL 3.2 контекст устройства и получить следующий вывод:
Buffer is 1
Bound before glBindVertexArray: 1
Bound after glBindVertexArray: 0
GL_ARRAY_BUFFER с другой стороны, это не изменен вызов. Я проверил версию OpenGL 3.2 (2.10) для glBindVertexArray
и не нашел упоминания об этом неожиданном побочном эффекте.
- Является ли это поведение совместимым с Spec?
- Если да, то каких других побочных эффектов можно ожидать от звонка до
glBindVertexArray
? - В чем причина этого?
Я тестировал это на карте nvidia на машине Win XPx64 с драйвером WHQL 296.10. Быстрый тест на OS X Lion с nvidia GT330M дал те же результаты.
Я думаю, что привязка VAO неявно связывает буферы элементов и вершин. Для этого нужны VAO. Если вы связываете VAO, а затем связываете буфер индекса и вершины, эти буферы затем неявно привязываются всякий раз, когда вы связываете VAO позже. Таким образом, привязка VAO выше, по-видимому, неявно устанавливает массив элементов и вершин в ноль, поскольку они не были включены вами в объект VAO. Это имело смысл? :-) – Robinson
Но почему это только изменяет GL_ELEMENT_ARRAY_BUFFER, а не GL_ARRAY_BUFFER? – ComicSansMS
Поскольку буфер массива является буфером вершин (по крайней мере, различные glEnableVertexAttribArray и glVertexAttribPointer вызывают ваш make с ним), и он включает в себя буфер элемента как часть этого состояния. – Robinson