【问题标题】:OpenGL Textures (from .png files) not displaying correctly on low-end phoneOpenGL 纹理(来自 .png 文件)在低端手机上无法正确显示
【发布时间】:2014-07-28 15:49:46
【问题描述】:

问题

我有一张各种背景的图集(在 HDPI 文件夹中)大小为 5760 x 459。最初,文件大小为 1.5MB。

我已经在一些设备上进行了测试,包括 Nexus 10 平板电脑(从 XHDPI 文件夹中获取更大版本的文件)、通用平板电脑(使用 MDPI)、Galaxy Ace 手机(再次使用 MDPI)等等工作正常。

不过,我最近拿到了一部运行 KitKat 的新手机。但是,看起来这款手机的规格非常低。 (1GB 存储空间,249MB RAM)。

现在,当我在这款手机上运行我的应用程序时,它使用 HDPI 版本的资源(如上所述)。没有错误,应用程序运行,但此特定资源仅显示为纯黑色。

我尝试了什么?

虽然可能是内存问题,所以我使用各种工具等将文件大小减小到 182kb。但是,当我运行该应用程序时,我遇到了同样的问题。

所以,我将 LDPI 图像复制到 HDPI 文件夹中(显然像素数较低),然后它运行了……它显示 OK(文件大小大于 182kb )。

这里发生了什么?手机的物理分辨率为 900 x 540。图集中的每个单独图像都是 960 x 459,因此,稍加缩放后,它应该与其他设备一样适合。

让我感到困惑的另一件事是,我的 XHDPI 文件夹包含一个图集,其中每个单独的背景大约是 Nexus 10 屏幕宽度和高度的 1/2,因此会按比例放大。但是,使用 Google 的缩放法则 (Android: Supporting Multiple Screens),在缩放之后,HDPI 图集中包含的每个单独的背景图像大约是我正在使用的手机屏幕的大小,因此不需要太多缩放(而我会再次喜欢使用屏幕大小的 1/2 的图像)。

为什么这款手机无法使用当前大小的文件(物理大小,而不是文件大小),有什么方法可以更好地管理或提供更多替代资源(仅 LDPI、MDPI、HDPI 和 XHDPI)?

【问题讨论】:

  • 您的图集纹理非常宽,大多数(据我所知)设备支持最大 4096 或 2048 大小的纹理。
  • 有趣的@harism,我以前没听过这个!因此,该图集是(近)全屏背景图像的图集。现在,在我的高分辨率 (2560 x 1600) 的 Nexus 10 上,我在图集中的单个图像是 1310 * 612,所以它可以放大以适应屏幕,现在在我的 hdpi 资源上,这个手机拾取的资源与此屏幕大小大致相同 - 无需调整大小(因为我遵循 Google 对此的建议)如何确保此手机拾取的资源也约为物理屏幕的 1/2 大小?

标签: android graphics resources png scaling


【解决方案1】:

您可能超出了设备支持的最大纹理大小。您的纹理(5760)的宽度非常大。移动设备的每个维度的纹理大小限制为 4096 甚至 2048 是很常见的。

您可以通过以下方式查询纹理大小限制:

GLint maxSize = 0;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);

【讨论】:

  • 是的,我认为这比 2 的幂 理论更有可能。我只是减小了位图的大小并给了它一个随机大小(3339 x 329),它就起作用了。所以你可能是对的。我不知道某些设备的大小上限。所以问题是,我该如何减轻这种情况?如果我减少所有纹理(XHDPI、HDPI、MDPI 和 LDPI),那么在某些设备上,它会放大很多(损失质量),任何建议都会非常受欢迎!谢谢@RetoKoradi
  • 不确定您的最佳策略是什么。您可以像我在回答中显示的那样在运行时检查最大纹理大小,如果位图大于纹理大小限制,则缩小位图。加载大型位图以立即缩小它当然效率不高。或者您的资源/资产中可以有多个版本,并根据纹理大小限制选择要加载的版本。
  • 感谢@RetoKoradi,我喜欢那里的第二个选项(提供多种资源),但我已经看了一遍,找不到如何做到这一点(除了 X/H/M 和 LDPI - 是否有任何文章可以告诉我如何实现这一目标?谢谢
  • 好的,所以我基本上在一个方向上减小了图集的大小并在另一个方向上增加了它,所以现在不是 1 行 6 个背景,而是 3 行 2 以保持较低的宽度。
【解决方案2】:

似乎有些设备只能加载 2 的幂次(128 x 64、512 x 512、1024 x 512 等)纹理。将图像放在 hdpi、mdpi 等文件夹中会自动缩小图像,因此不能保证图像始终是 2 的幂。更好的方法是将图像放在 nodpi 文件夹中。或者你可以将单独的图像放在所有 dp 文件夹中,但要确保它们都是 2 的幂。

【讨论】:

  • 有趣的是,有人告诉我“2 的幂”openGL 限制实际上不再存在。我的 MDPI 文件夹中的那些 3840 x 306 do 确实有效!我也不认为 no-dpi 选项可行,我的应用程序需要在从最低规格手机到最新平板电脑的所有设备上看起来尽可能好(如果我理解正确,使用 nodpi 意味着只提供一组资源?) - 2 事物设备的功能是特定的吗?我虽然这是一个通用的 OpenGL 的东西?干杯!
  • 是的..它是特定于设备的,并且在某些设备中仍然存在该问题。我经历过很多次。例如 nexus 7 第一代 2012 型号。
  • 我认为 mdpi、hdpi 等文件夹会很方便,但你应该在解码图像时禁用 inScaled 标志:developer.android.com/reference/android/graphics/…
  • 哇@AbhishekV,我不知道!认为问题仍然存在真是太疯狂了!我不明白的是,我的纹理都不是 2 的幂,但只有这个才是我的问题:-(
  • @AbhishekV:无法加载 NPOT 纹理的设备不符合 ES 2.0。 ES 2.0 中对 NPOT 纹理有一些限制,主要是它们不能被 mipmapped,并且不是所有的 wrapping 模式都可用,除非支持 GL_OES_texture_npot
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
相关资源
最近更新 更多