如何使用 Open GL ES 在 Android 中加载巨大的位图?

How to load huge bitmap in Android using Open GL ES?

我的应用程序中有一个图像视图,我想在上面加载大位图,但是当我设置 "android:hardwareAccelerated="true" 时,出现错误

(Bitmap too large to be uploaded into a texture (2368x4208, max=4096x4096))

我通过将 flag 设置为 false 来解决这个问题。这导致了另一个问题,而 scrolling/zooming ImageView 中的图像,性能非常糟糕。

问题:

  1. 我可以有很多纹理吗?
  2. 纹理总大小是否可以超过 4096x4096?

您遇到的纹理限制是由您的 GPU 驱动程序强加的,并且可能因设备而异。使用硬件加速,ImageView会使用OpenGL ES驱动,推测是使用glTexImage2D函数将图像上传到GPU。来自其文档:

GL_INVALID_VALUE may be generated if level is greater than log 2 ⁡ max , where max is the returned value of GL_MAX_TEXTURE_SIZE when target is GL_TEXTURE_2D or GL_MAX_CUBE_MAP_TEXTURE_SIZE when target is not GL_TEXTURE_2D.

如果您使用 GL_MAX_TEXTURE_SIZE 查看 glGet 的文档:

GL_MAX_TEXTURE_SIZE params returns one value. The value gives a rough estimate of the largest texture that the GL can handle. The value must be at least 64. See glTexImage2D.

因此,您只能保证可以在每个支持 ES 2.0 的设备上上传 64x64 纹理。在实践中,对于许多当前设备而言,这个数字是 2048x2048,但是在尝试上传大图像之前,您应该始终知道可以通过查询该值来容纳图像大小。一般来说,这里的小数字意味着 GPU 功能较弱,因此屏幕分辨率较低,需要的纹理细节较少。您可以根据此值区分您的资产 - 例如。为低分辨率屏幕提供低分辨率纹理。

为了回答您的其他问题,GL 对您创建的纹理数量没有限制,例如。 glGenTextures。但是,从技术上讲,您在 OpenGL ES 中调用的任何命令都可能生成 GL_OUT_OF_MEMORY 错误。不幸的是,没有标准的方法来查询驱动程序是否能够处理给定命令的任何所需分配。处理此问题的唯一实用方法是在具有不同 GPU 功能的许多设备上测试您的应用程序。