在Open ES iPhone应用程序中围绕VBO使用VAO在调用glDrawElements时导致EXC_BAD_ACCESS

我正试图把我的代码提高到一个新的水平。 遵循苹果的一些最佳实践,我试图围绕我的顶点缓冲对象(VBO)实现顶点数组对象。 我设置了我的VBO和VAO:

- (void)setupVBOs { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindVertexArrayOES(0); { glGenVertexArraysOES(1, &directArrayObject); glBindVertexArrayOES(directArrayObject); // GLuint texCoordBuffer; glGenBuffers(1, &texCoordBuffer); glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(DirectVertices), DirectVertices, GL_STATIC_DRAW); glVertexAttribPointer(directPositionSlot, 2, GL_FLOAT, GL_FALSE, sizeof(DirectVertex), (GLvoid*)offsetof(DirectVertex, position)); glEnableVertexAttribArray(directPositionSlot); glVertexAttribPointer(texCoordSlot, 2, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(DirectVertex), (GLvoid*)offsetof(DirectVertex, texCoord)); glEnableVertexAttribArray(texCoordSlot); glGenVertexArraysOES(1, &arrayObject); glBindVertexArrayOES(arrayObject); // GLuint vertexBuffer; glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); glEnableVertexAttribArray(positionSlot); glVertexAttribPointer(colorSlot, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Color)); glEnableVertexAttribArray(colorSlot); // GLuint indexBuffer; glGenBuffers(1, &indexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW); } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindVertexArrayOES(0); } 

我从http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=287977拿走,然后像这样使用它:

 - (void) render:(CADisplayLink*)displayLink { glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, backingWidth, backingHeight); [directProgram use]; glBindVertexArrayOES(directArrayObject); glDisable(GL_DEPTH_TEST); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, videoFrameTexture); // // Update uniform values glUniform1i(videoFrameUniform, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); [program use]; glBindVertexArrayOES(arrayObject); glDisable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); CC3GLMatrix *projection = [CC3GLMatrix matrix]; float h = 4.0f * self.frame.size.height / self.frame.size.width; [projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10]; glUniformMatrix4fv(projectionUniform, 1, 0, projection.glMatrix); CC3GLMatrix *modelView = [CC3GLMatrix matrix]; [modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)]; currentRotation += displayLink.duration * 90; [modelView rotateBy:CC3VectorMake(currentRotation, currentRotation, 0)]; glUniformMatrix4fv(modelViewUniform, 1, 0, modelView.glMatrix); glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0); glBindVertexArrayOES(0); BOOL success = [context presentRenderbuffer:GL_RENDERBUFFER]; if(!success) NSLog(@"present failed"); } 

调用glDrawArrays的作品,它填充我的纹理,但是,调用glDrawElements失败,EXC_BAD_ACCESS。 我的着色程序(我使用两个)被封装在一个GLProgram对象中,我从http://iphonedevelopment.blogspot.com/2010/11/opengl-es-20-for-ios-chapter-4.html

删除glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 从您的设置function的结束。

根据OES_vertex_array_object的规范,顶点数组对象封装除了数组缓冲区绑定1 之外的所有状态,所以在绘制的时候没有绑定元素缓冲区,而你可能想要绑定indexBuffer 。 通过在与顶点数组对象绑定的时候indexBuffer绑定的indexBuffer ,确保在返回到顶点数组对象时它会被反弹。


1如果您想知道为什么在顶点数组对象中不跟踪数组缓冲区绑定,这大概是因为从数组中读取顶点数据时不直接使用当前绑定的数组缓冲区 – 而是每个顶点属性都有自己的缓冲区绑定,当函数被调用时,通过查看数组缓冲区绑定来填充它的各自的gl*Pointer函数。