【发布时间】:2014-09-23 09:10:43
【问题描述】:
我编写了一个游戏,在其中调用 onDrawFrame() 时,我首先更新游戏状态(游戏逻辑和绘图缓冲区),然后继续进行实际绘图。在 Moto G 和 Nexus 7 上,一切运行顺利,每个 onDrawFrame() 调用只需要 1-5 毫秒。但是,在三星 Galaxy S3 上,90% 的时间 onDrawFrame() 调用需要 30-50 毫秒才能更新。
进一步调查我发现问题完全在于我在下面附加的第一个渲染方法:- (编辑:该块现在在 glclear() 上;删除了获取句柄的不必要调用,请参阅 cmets)
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-2 毫秒。我已经尝试禁用第一个 render() 调用,但是第二个之前只需要 1-2 毫秒的调用现在成为延迟的来源,在相同的行下。
有人知道我的代码中有什么问题是 S3 无法处理的吗?似乎 S3 在每个 onDrawFrame() 开始时开始 GL 调用都有问题,但为什么会有这样的行为让我感到困惑。有什么办法可以减少“启动”延迟?
非常感谢您的耐心阅读。
根据 Selvin 的建议编辑了代码。
【问题讨论】:
-
为什么你会在 onDrawFrame 中获取属性位置和制服?而不是在编译
fhGraphicTools.sp_Image着色器之后将其存储在 fxfhGraphicTools.sp_Image_mPositionHandle中 -
如你所说,我在编译后存储了句柄。现在“块”来自 glClear(),它需要 18-50 毫秒。我做了一些搜索,发现了这篇文章stackoverflow.com/questions/12224230/… 阅读后我仍然没有完全理解我的问题......
标签: android opengl-es-2.0