我有一个带有用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;
谢谢!
答案 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让它再次加速。