Ios 多个glDrawArrays()调用与缓冲区更新-性能

Ios 多个glDrawArrays()调用与缓冲区更新-性能,ios,performance,opengl-es-2.0,Ios,Performance,Opengl Es 2.0,我在OpenGL ES2.0(iOS)中使用顶点数组绘制了许多类似的2D四边形,试图保持最佳性能。我知道,出于性能原因,建议将所有计算出的几何图形放入VBO中,并使用尽可能少的对glDrawArrays()的调用次数 但是,如果有许多相似的四边形,每个四边形在每个帧中变换,那么创建一个非常小的VBO(例如,只向其中添加四个顶点(或两个三角形),然后继续进行每帧变换,并为每个四边形单独调用一个GLDrawArray(GL_TRIANGLE_STRIP,0,4)不是更快吗 在这种情况下,我希望从CP

我在OpenGL ES2.0(iOS)中使用顶点数组绘制了许多类似的2D四边形,试图保持最佳性能。我知道,出于性能原因,建议将所有计算出的几何图形放入VBO中,并使用尽可能少的对glDrawArrays()的调用次数

但是,如果有许多相似的四边形,每个四边形在每个帧中变换,那么创建一个非常小的VBO(例如,只向其中添加四个顶点(或两个三角形),然后继续进行每帧变换,并为每个四边形单独调用一个GLDrawArray(GL_TRIANGLE_STRIP,0,4)不是更快吗

在这种情况下,我希望从CPU到GPU的数据传输更少,性能更好,因为VBO内容小且静态。多个glDrawArrays()调用将使用作为统一对象传递的不同模型视图投影矩阵重复重画相同的几何体。以下代码可能会阐明我尝试执行的操作:

/// Executed only once:

/// The quad attributes (only position to simplify the example).
NSInteger idx = 0;
attributes[idx++] = -0.5;
attributes[idx++] = -0.5;
attributes[idx++] = 0.5;
attributes[idx++] = -0.5;
attributes[idx++] = -0.5;
attributes[idx++] = 0.5;
attributes[idx++] = 0.5;
attributes[idx++] = 0.5;

/// The buffer data
if(NO == glIsVertexArrayOES(vertexArray)) {
    glGenVertexArraysOES(1, &vertexArray);
    glGenBuffers(1, &bufferObject);
}
glBindVertexArrayOES(vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, bufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(attributes), attributes, GL_STATIC_DRAW);
glEnableVertexAttribArray(positionAttributeLocation);
glVertexAttribPointer(positionAttributeLocation, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (char *)NULL);

///...

/// Executed per frame:

glBindVertexArrayOES(vertexArray);
for(NSInteger i = 0; i < numQuads; i++) {
   quad = [quads objectAtIndex:i];
   m4 = GLKMatrix4Identity;
   m4 = GLKMatrix4MakeScale(quad.size, quad.size, 1.0);
   m4 = GLKMatrix4Multiply(GLKMatrix4MakeRotation(quad.angle, 0.0, 0.0, 1.0), m4);
   m4 = GLKMatrix4Multiply(GLKMatrix4MakeTranslation(quad.position.x, quad.position.y, 0.0), m4);
   modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, m4);
   glUniformMatrix4fv(uniformLocationMVP, 1, GL_FLASE, modelViewProjectionMatrix.m);
   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
///只执行一次:
///四元属性(仅用于简化示例的位置)。
NSInteger idx=0;
属性[idx++]=-0.5;
属性[idx++]=-0.5;
属性[idx++]=0.5;
属性[idx++]=-0.5;
属性[idx++]=-0.5;
属性[idx++]=0.5;
属性[idx++]=0.5;
属性[idx++]=0.5;
///缓冲区数据
如果(否==glisvertexarray(vertexArray)){
GLGEnVertexArray(1和vertexArray);
glGenBuffers(1和bufferObject);
}
GLBindVertexArray(vertexArray);
glBindBuffer(GL_数组_BUFFER,bufferObject);
glBufferData(GL_数组_缓冲区、sizeof(属性)、属性、GL_静态图);
GlenableVertexAttributeArray(位置属性位置);
glvertexattributepointer(positionAttributeLocation,2,GL_FLOAT,GL_FALSE,2*sizeof(FLOAT),(char*)NULL);
///...
///每帧执行:
GLBindVertexArray(vertexArray);
对于(NSInteger i=0;i

与单个glDrawArrays()调用相比,这种方法是否有任何性能优势?

draw调用非常昂贵。尽可能避免多次呼叫。想象一下,使用一千个draw调用绘制一千条直线(大小和方向不同)。想象一下,创建一个包含2000个点和一个draw调用的缓冲区。数据的传递将花费相同的时间,但绘图需要锁定屏幕,绘制,然后释放一千次,而不是一次。“数据的传递将花费相同的时间”-但使用单个短缓冲区并不意味着在GPU端重复使用它,没有传递数据?我仍然认为绘图调用比传递信息花费的时间多得多。实际上,我已经用直线和多边形对此进行了大量测试。打一次平局对我来说速度有了很大的提高。并不是说永远都是这样,但根据我的经验,多次抽签会降低性能。谢谢。看来我可能需要重新考虑我的方法。除了传递数据之外,我还希望在顶点着色器中添加统一的组合变换可以防止在CPU上进行许多几何体计算(一个矩阵而不是六个两个三角形)。另一方面,我的瓶颈是GPU,而不是CPU。