Как вы используете 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 вещи:
Почему не работает пример (кубы не рисуются), когда я "исправляю" 3-ю строку кода в
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, gCubeVertexData );
Как правильно вызывать 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
если вы хотите начать рисование с начала буфера.