То, что вы делаете, выглядит правильно, за исключением того, что sizeof (вершины) дает вам размер адреса, а не размер массива.Итак, когда вы вызываете glBufferData, вы выделяете 8 байтов, а когда вы вызываете glBufferSubData, вы заполняете эти 8 байтов первыми четырьмя байтами массива вершин, а затем первыми четырьмя байтами массива нормали.Затем, когда вы идете к вызову glDrawArrays, первый индекс вызывает исключение индекса массива за пределами границ (следовательно, EXC_BAD_ACCESS).
// Data
GLuint geometry_array = 0;
GLuint indice_array = 0;
GLfloat *geometry;
GLuint *indices;
Вы можете выполнить эту инициализацию по-разному, но я чередую все свои данные в 32 байта на массив вершин.Любой способ настройки массива работает, если вы правильно используете glVertexPointer, glNormalPointer и glTexCoordPointer.
// Initialize
geometry = new GLfloat[8*num_geometry];
indices = new GLuint[num_indices];
/* Fill geometry: 0, 1, 2 = vertex_xyz
* 3, 4, 5 = normal_xyz
* 6, 7 = tex_coord_uv
*/
glGenBuffers(1, &geometry_array);
glBindBuffer(GL_ARRAY_BUFFER, geometry_array);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*8*num_geometry, NULL, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat)*8*num_geometry, geometry);
glGenBuffers(1, &indice_array);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indice_array);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*num_indices, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(GLuint)*num_indices, indices);
Функция рендеринга состоит из пяти шагов.Сначала свяжите буферы, чтобы OpenGL знал, где найти вашу геометрию и данные индексов.Во-вторых, включите различные состояния клиента для каждого типа данных.Если вы пропустите один из них, данные этого типа не будут отображаться, а если пропустить все из них, весь ваш объект не будет отображаться.В-третьих, вы должны указать OpenGL, где каждый тип данных содержится в вашем массиве.В этом случае 32-байтовые данные геометрии начинаются с 12 байтов данных вершины, поэтому начальное смещение должно быть нулевым или NULL.Поскольку каждая комбинация vertex-normal-texcoord составляет 32 байта, это размер шага.«sizeof (GLfloat) 8» говорит, что 32 байта от смещения NULL, будет другая группа вершин xyz.В случае нормалей каждая нормальная группа xyz составляет 12 байтов после смещения для группы вершин xyz, следовательно, "(float ) (sizeof (GLfloat) * 3)" в качестве начального смещения.Опять же, размер шага составляет 32 байта.В-четвертых, вы должны сказать ему, чтобы нарисовали все треугольники, связанные с массивом индексов.Наконец, вы должны отключить состояния клиента, если вы хотите использовать другой метод рендеринга.
//Render
// Step 1
glBindBuffer(GL_ARRAY_BUFFER, geometry_array);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indice_array);
// Step 2
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
// Step 3
glTexCoordPointer(3, GL_FLOAT, sizeof(GLfloat)*8, (float*)(sizeof(GLfloat)*5));
glNormalPointer(GL_FLOAT, sizeof(GLfloat)*8, (float*)(sizeof(GLfloat)*3));
glVertexPointer(3, GL_FLOAT, sizeof(GLfloat)*8, NULL);
// Step 4
glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_INT, NULL);
// Step 5
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);