Как вы используете glVerttexAttribPointer в сочетании с glBufferData?

В стандартном OpenGL-примере с "вращающимся кубом" для iOS 5 они имеют следующий код:

glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

Запутанная часть есть последний аргумент glVertexAttribPointer, Документы говорят, что последний аргумент является указателем на массив.

Но в этой программе они используют прямые числа. В самом деле, BUFFER_OFFSET определяется как

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

Так они полагаются на свои gCubeVertexData массив начинается с адреса памяти 0?

Итак, я не понимаю 2 вещи:

  1. Почему не работает пример (кубы не рисуются), когда я "исправляю" 3-ю строку кода в

    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, gCubeVertexData );
    
  2. Как правильно вызывать glVertexAttribPointer?

Я думал, что вы должны передать указатель памяти для последнего индекса, как сказано в документации. Действительно, здесь другой пример использует glVertexAttribPointer:

glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(vertexStruct), &vertices[0].position);
glEnableVertexAttribArray(ATTRIB_POSITION);
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertexStruct), &vertices[0].color);
glEnableVertexAttribArray(ATTRIB_COLOR);

Итак, вы видите, что в последнем примере они передали адреса памяти для указателя (последний аргумент), а не для прямых чисел.

1 ответ

Решение

glVertexAttribPointer может использоваться двумя способами:

1) С массивами вершин на стороне клиента. В этом случае последний аргумент - это указатель на массив, в этом вы правы.

2) В дополнение к тому, что он используется в качестве указателя, если вы читаете дальше на той странице документации, на которую вы ссылаетесь, это говорит следующее:

Если ненулевой именованный объект буфера привязан к цели GL_ARRAY_BUFFER (см. GlBindBuffer), в то время как указан универсальный массив атрибутов вершины, указатель обрабатывается как смещение байта в хранилище данных объекта буфера.

Это для случаев, когда вы используете glVertexAttribPointer для указания на VBO, буфер, который вы ранее загрузили в opengl (glBindBuffer/glBufferData).

Чтобы уточнить:

Если у вас нет активного буфера, связанного с glBindBuffer, glVertexAttribArray получает указатель. Если у вас есть привязка к буферу, то glVertexAttribArray принимает смещение в связанный буфер. Это будет значение 0 если вы хотите начать рисование с начала буфера.

Другие вопросы по тегам