我编写了一个游戏,当调用onDrawFrame()时,我首先更新游戏状态(游戏逻辑和绘图缓冲区),然后继续进行实际绘图。在Moto G和Nexus 7上,一切都运行顺畅,每个onDrawFrame()调用只需要1-5ms。但是,在三星Galaxy S3上,90%的时间onDrawFrame()调用需要30-50ms才能更新。
进一步研究这个问题我发现问题完全在于我在下面附上的第一个渲染方法: - (编辑:块现在是glclear();删除了不必要的调用以获取句柄,请参阅注释)
public void render(float[] m, FloatBuffer vertex, FloatBuffer texture, ShortBuffer indices, int TextureNumber) {
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, vertex);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 0, texture);
GLES20.glEnableVertexAttribArray(mTexCoordLoc);
GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);
int mSamplerLoc = GLES20.glGetUniformLocation(fhGraphicTools.sp_Image, "s_texture");
GLES20.glUniform1i(mSamplerLoc, TextureNumber);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.capacity(), GLES20.GL_UNSIGNED_SHORT, indices);
// Disable vertex arrays used
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTexCoordLoc);
}
在每个onDrawFrame()中调用上述方法5次,以在不同的纹理图集上绘制内容。 (前4个实际上是游戏的背景,即1个长矩形)。记录了代码的每一行所花费的时间后,我发现S3上的延迟始终位于以下行之一:
int mPositionHandle = GLES20.glGetAttribLocation(fhGraphicTools.sp_Image, "vPosition");
或
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.capacity(), GLES20.GL_UNSIGNED_SHORT, indices);
延迟仅发生在render()的第一次调用中,因为后续调用每次大约需要1-2ms。我已经尝试禁用第一个render()调用,但是之后第二个只需要1-2ms就可以成为延迟的来源,在同一行下。
有没有人知道我的代码中S3无法处理的错误?似乎S3在每个onDrawFrame()的开头都有问题开始GL调用,但为什么这样的行为让我感到困惑。可以采取哪些措施来减少“启动”延迟?
非常感谢您耐心阅读。
编辑代码以接受Selvin的推荐。
答案 0 :(得分:0)
当我将所有png图像文件从/ drawable移动到/ drawable-nodpi时,我已经解决了这个问题,游戏速度在S3上恢复正常。 我假设Android完成的自动缩放导致我提供给“坏”大小的opengl的原始位图导致每个onDrawFrame上的不必要的纹理过滤工作,导致调用错过vsync并在等待下一个时为glClear提供长时间延迟垂直同步。如果我错了,请纠正我,仍然是图形的新手。