1

我在 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 方法。这可能是不规则的原因吗?我能做些什么呢?

4

1 回答 1

0

我不知道您是否还在这样做,但请尝试就此事咨询 Google。您不会从网络上的其他任何地方得到合理的答案。20ms 基本上是 50FPS。执行您要求的那些简单任务时,您通常会获得 250FPS。万一,万一,它是故意放慢的呢?

我们曾经在简单的拦截调用中编写代码并使用整个 VGA 卡。但如今,即使在智能手机中,它也以虚拟模式运行。您需要在汇编或 c 级别获得对视频芯片的直接访问权限。询问并咨询谷歌。

于 2014-04-08T00:22:02.630 回答