我正在尝试在Android上使用OpenGL ES实现屏幕外渲染。我的最终目标是提高纹理映射的性能,我在普通的java和Bitmap / int [] API中做。我尝试了pbuffer方法,类似于relevant forum thread的示例代码。它显示相当低的性能,glReadPixels
调用在一台设备上最多需要50毫秒,在另一台设备上最多需要15毫秒。
使用Frame Buffers有更多现代方法。代码示例相当复杂,我不希望从帧缓冲区到Android的位图传输速度比使用pbuffers更快。我估计是对的吗?
第三种方法是使用pixmaps。如果我理解正确的文档,他们应该在OpenGL和Dalvik的内存之间使用比普通副本更复杂的内存共享。问题是Android SDK中没有相关的API。
Java中没有公开eglCreateImageKHR
和EGLImageKHR
结构。我能找到的所有C ++示例都依赖于它们。
有eglCreatePixmapSurface
,但我无法弄清楚如何在文档中使用它。可能它在native_pixmap
参数中接收某种位图句柄,但我找不到任何方法来创建这样的句柄。搜索“eglCreatePixmapSurface android”只会导致问题报告。
我的主要问题是:我可以在Java上使用pixmaps而无需编写本机代码吗?如果我需要本地化,那么我可以使用工作代码来评估性能,然后深入了解OpenGL?
答案 0 :(得分:6)
在Android上改善纹理加载性能的最佳方法是使用您选择的EGL图像扩展和使用本机代码的EGL_NATIVE_BUFFER_ANDROID。我在这个article中有一个代码示例。我用这种方法测量了主要的性能改进。
Android不支持Pixmaps,pbuffers不支持Nvidia Tegra设备。您应该使用FBO附加的纹理。这就是Android SurfaceTexture类的实现方式。
如果你需要alpha纹理,这是使用本机代码的另一个原因。 Bitmap和OpenGL ES与alpha纹理之间存在兼容性问题。
使用硬件纹理压缩格式(ETC / PVR而不是PNG)和mipmap可以提高纹理渲染的加载性能和质量,如本article.
中所述最大的问题是glReadPixels()。 EGL_NATIVE_BUFFER_ANDROID仅适用于编写纹理,而不适用于将其读回Bitmap。 Android的平台代码使用glReadPixels()来实现TextureView.getBitmap(),它非常慢。最好的解决方案是不将纹理复制到Bitmap,而是直接显示渲染的TextureView,这样可以避免使用glReadPixels()。
我一直在使用OpenGL ES 2.0,情况可能已经通过3.0进行了改进。