我正在使用OpenGL ES 2.0中的顶点缓冲对象(VBO)。
我有一组顶点数据,它被永久地存储在正常的RAM中。原因是从头计算顶点位置代价很高,但可以添加一个增量到上一个位置来便宜地更新它。
实际要绘制的顶点数量会随时间迅速变化。在一帧中,可能有1000个,而在下一帧中有2500个。根据此前收到的建议,现在指定整数UPPER
作为最多可绘制的顶点上限。我只在启动时基于这个值malloc
我的顶点和索引数据数组一次。
每次调用glBindBuffer
时,我传递GL_STREAM_DRAW
使用提示以指示数据每帧都会更改。
为了尽可能高效,我创建了以下设置:
// SETUP: Called only once.
glBindBuffer(GL_ARRAY_BUFFER,...);
glBufferData(GL_ARRAY_BUFFER,...); // Pass vertex data for UPPER vertices.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,...); // Pass index values 0 - (UPPER-1).
glEnableVertexAttribArray(...); // Setup vertex attributes.
glVertexAttribPointer(...);
glUseProgram(...); // Use program with custom shaders.
glUniformMatrix4fv(...); // Identify shader uniforms.
// UPDATE: Called when vertex data changes (on each frame).
glBindBuffer(GL_ARRAY_BUFFER,...);
glBufferSubData(GL_ARRAY_BUFFER,...); // Update VBO data.
// RENDER: Called on each frame.
glDrawElements(GL_TRIANGLES, numberOfVerticesThisFrame, ...); // Number of vertices and indices to be used is inherently specified in here.
然而,这会在 glDrawElements 上出现 EXC_BAD_ACCESS 错误,我知道这是由于我的 gl 命令的顺序问题导致的。
我之前有一个类似的设置,它可以正常工作:
// UPDATE: Called when vertex data changes (on each frame).
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,...); // Pass index values 0 - (actual number of vertices to draw - 1)
// RENDER: Called on each frame.
glBindBuffer(GL_ARRAY_BUFFER,...);
glBufferData(GL_ARRAY_BUFFER,...); // Pass vertex data for actual number of vertices (not UPPER).
glEnableVertexAttribArray(...); // Setup vertex attributes.
glVertexAttribPointer(...);
glUseProgram(...); // Use program with custom shaders.
glUniformMatrix4fv(...); // Identify shader uniforms.
glDrawElements(GL_TRIANGLES, numberOfVerticesThisFrame, ...);
然而,这种设置需要每帧更多的工作量,并且正如您所见,它涉及更改VBO大小(因为它使用实际大小,而不是
UPPER
),据我所知,这会导致性能大幅下降。请问有人可以向我解释一下我的新设置存在的任何明显问题,并最重要的是在
glDrawElements
之前每帧我必须调用哪些命令?我假设我可以提前准备好所有可能的索引,然后将实际顶点数传递到glDrawElements
中,但显然是错误的。