在iPad上第一次调用glDrawArrays非常慢

时间:2010-11-02 14:24:55

标签: ipad ios opengl-es

我有一个带有用OpenGL ES 2.0编写的UI的iPad应用程序,默认情况下隐藏了一些UI元素,当我需要显示它们时,它们实际显示之前有很大的延迟(在包含的控件上大约300-500毫秒)大约20个其他控件在里面),使用Instruments.app我确定当我渲染每个独特的对象时,渲染它需要更长的时间,然后再渲染它至少一次,渲染时间差异很大。这是我用于渲染的代码,这些代码由Instruments承担所有这些延迟:

- (void)render:(id <ESRenderer>)renderer
{
    [shader useShader];
    glEnableVertexAttribArray(ATTRIB_VERTEX);
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, _squareVertices);
    glEnableVertexAttribArray(ATTRIB_TEXTCOORD);
    glVertexAttribPointer(ATTRIB_TEXTCOORD, 2, GL_SHORT, 0, 0, coords);
    float x1 = self.position.x;
    float y1 = self.position.y;
    glUniform1f(shader.ext_uniforms[UNIFORM_TRANSLATE_X], -x1+_squareVertices[0]);
    glUniform1f(shader.ext_uniforms[UNIFORM_TRANSLATE_Y], -y1+_squareVertices[1]);
    glUniform1f(shader.ext_uniforms[UNIFORM_ROTATE], self.rotation); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisableVertexAttribArray(ATTRIB_VERTEX);
    glDisableVertexAttribArray(ATTRIB_TEXTCOORD);
}

当它至少被调用一次时,它的工作速度非常快。 我的着色器也非常简单:

vec4 col = texture2D(texture, coordVarying);
gl_FragColor = col;

谢谢!

3 个答案:

答案 0 :(得分:1)

我猜这是实际的数据传输到GPU只发生一次。您应该能够在第一次渲染之前的某个时刻强制加载/编译,以消除性能损失。顶点数据传输(如果它很大)或着色器传输/编译。

编辑:如其他答案中所述,还有可以传输的纹理数据。

答案 1 :(得分:0)

OpenGL实现通常会“懒洋洋地”加载纹理,即纹理仅在第一次使用时实际初始化(几乎是jv42所说的,但不是几何数据)。这可能是这里发生的事情。如果你不改变对象之间的纹理,你会得到同样的减速吗?

一种解决方案是绘制一些琐碎的离屏三角形,在初始化时绑定纹理,以强制在主渲染循环之前加载这些纹理。

顺便说一句,我不会花太多钱来测量像iPhone那样的延迟渲染器上的个别绘制调用的长度。

答案 2 :(得分:0)

我也明白了。 对我来说这是纹理问题。在NVIDA上,事情很快就解决了。但我的光学优化导致ATI卡无法辞职。

我使用尺寸为4720 x 5600(约)的纹理,现代卡可以很好地使用它。

我尝试使用Wrapmode = GL_CLAMP_TO_BORDER_ARB优化边框。因此我需要为glTeximage2D提供border参数,至少为== 1。 由于可疑卡在HW中不支持边框,因此一帧的时间为20秒。回到GL_CLAMP_TO_BORDER + border param == 0让它再次加速。