我在 NDK 和 SDL 的帮助下将 C++ 2D 游戏移植到 Android;我使用 OpenGL 来渲染精灵。表演相当令人失望。
经过一番调查,我发现瓶颈在于渲染过程中的 OpenGL 调用。等一等!在粘贴经典答案之前,告诉不要更改 GL 状态,不要绑定已绑定的纹理等,请阅读以下内容。
实际上,即使我在黑屏中间显示单个 364x353 rgba 纹理,渲染也需要将近 20 毫秒。该过程可以总结如下:
编辑下面的代码用于调用glFlush()
. 正如 thokra 在评论中指出的那样,这不是必需的。然而,删除它并没有提高性能。
glClear( GL_COLOR_BUFFER_BIT );
glBindTexture( the_texture );
glEnable(GL_BLEND);
glEnableClientState( GL_COLOR_ARRAY );
glColorPointer( 4, GL_FLOAT, 0, colors );
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 2, GL_FLOAT, 0, positions );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, 0, texture_positions );
glDrawArrays( GL_TRIANGLE_FAN, 0, vertex_count );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
glDisable(GL_BLEND);
//glFlush();
SDL_GL_SwapWindow( window );
此函数的最后两行(刷新和交换)的执行时间非常不规则。它可能需要 4 到 12 毫秒!
我在网上能找到的最好的提示是StackOverflow 上的这个问题和Google Groups 上的这个线程。
StackOverflow 上的问题的答案没有任何帮助。根据问题的作者:
使用 glClear 清除与不清除帧对我来说不会影响 fps。启用/禁用混合也没有。
和
[...] 只是想看看使用压缩纹理是否会提高填充率。似乎没有 […]
Google Groups 线程与我的问题非常相似,但在作者放弃时结束:
所以基本上,由于纹素读取瓶颈,无法使用 OpenGL 以 60fps 在屏幕上绘制 480x854 图像。
认真的不行吗?为什么打电话给两者都glFlush()
需要SDL_GL_SwapWindow()
这么长时间?为什么它如此不规则?我对此无能为力吗?
我在 SDL2 的源代码中进行了快速搜索,发现它SDL_GL_SwapWindow()
使用 Java 本机接口来调用可以完成工作的 Java 方法。这可能是不规则的原因吗?我能做些什么呢?