Аргументы glGenVertexArrays и glGenBuffers

В руководстве по OpenGL 3.0+ мы создаем объект Vertex Array и объект Vertex Buffer следующим образом:

GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

Здесь ВАО является unsigned int (GLuint) и мы передаем a address ̶r̶e̶f̶e̶r̶e̶n̶c̶e̶ его адрес в функцию glGenVertexArray, Однако, согласно документации, вторым аргументом функции должен быть массив unsigned int (GLuint*). То же самое касается VBO и glGenBuffers, Я не понимаю, почему приведенный выше код работает с такими аргументами.

Я попытался заменить приведенный выше код на этот (и сделать необходимые изменения в другом месте в моем коде):

GLuint VAO[1];
GLuint VBO[1];
glGenVertexArrays(1, VAO);
glGenBuffers(1, VBO);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);

Он компилируется и выполняется, но я получаю неожиданное поведение: мой текстурированный прямоугольник отображается с первым синтаксисом, а не со вторым. Я тоже не понимаю, почему это происходит.

РЕДАКТИРОВАТЬ: Спасибо. Как уже говорилось, во втором коде есть ошибка индексации.

2

Решение

Сигнатура функции в спецификации:

void glGenVertexArrays( GLsizei n,
GLuint *arrays);

Так arrays ожидает GLuint указатель где действительно написать n * sizeof(GLuint) байтов данных в.

Это прекрасно и правильно написать:

GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

Так как glGenVertexArrays хочет иметь указатель на GLuint где действительно написать n * sizeof(GLuint) байтов данных (в вашем случае 1) и потому что VAO может содержать этот объем данных, это правильно записать таким образом. И предпочтительнее, если вы создаете только один идентификатор на вызов.

Как уже было сказано другими, первый элемент в массиве имеет индекс 0, По этому это должно быть:

GLuint VAO[1];
GLuint VBO[1];
glGenVertexArrays(1, VAO);
glGenBuffers(1, VBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);

Если вы хотите создать больше элементов за один вызов, вы хотите использовать std::array над [],

std::array<GLuint,3> VAOs;
std::array<GLuint,3> VBOs;

glGenVertexArrays(VAOs.size(), &VAOs[0]);
glGenBuffers(VBOs.size(), &VBOs[0]);

Как примечание unsigned int а также GLuint не обязательно того же типа или размера, unsigned int имеет минимальный гарантированный диапазон номеров, но размер может варьироваться на разных платформах. GLuint с другой стороны, имеет определенный размер.

2

Другие решения

Первый индекс 0

GLuint VAO[1];
GLuint VBO[1];
glGenVertexArrays(1, VAO);
glGenBuffers(1, VBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
2

Массив в C и C ++ представлен в виде указателя. Иными словами, указатель эквивалентен массиву из одного элемента. Поэтому, если вы создаете один буферный объект, вы можете просто объявить одну переменную и передать на нее указатель, как в первом примере (это не ссылка, а указатель), и в этом нет ничего плохого. Я всегда так делал сам.

Почему ваш второй пример не работает, см. Ответ Джонатана Олсона выше.

1
По вопросам рекламы [email protected]