【问题标题】:Android EGL overlay transparency issues, difference between screenshot and displayAndroid EGL覆盖透明度问题,截图和显示的区别
【发布时间】:2014-04-06 12:22:50
【问题描述】:

我的应用使用 8888 格式的全屏 glSurface 覆盖。对于大多数设备,这可以正常工作 - 我可以使用 OpenGL ES 绘制半透明图像,这确实会在我的其他原生视图之上覆盖透明。

但是,在 Nexus 10 和 Note 2(很可能还有其他一些设备)上,半透明像素在物理显示器上看起来并不正确,即使通过 DDMS 截取的屏幕截图看起来绝对正确!这让我很困惑 - 视觉显示与屏幕截图有何不同?

对于帧缓冲区中 alpha 值不是 1 (0xff) 或 0 (0x00) 的任何像素,似乎都会出现这种奇怪现象。

我附上了来自 Nexus 10 的 DDMS 屏幕截图,其中显示了应有的测试卡图像。我还附上了显示器上的一张照片,显示了一张非常不同的图像……如上所述,EGL 覆盖 alpha 值不是 0x00 或 0xff 的像素似乎显示不正确。注2是一样的。

有谁知道如何解决这个问题?这对我们来说是一个主要障碍,因为我们甚至不知道以编程方式确定设备显示屏是否存在问题的方法。

【问题讨论】:

    标签: android opengl-es ddms egl


    【解决方案1】:

    Android 上的半透明窗口应包含预乘 alpha 的颜色。窗口合成器使用的混合方程为:

    dest.rgb = src.rgb + dest.rgb*(1 - src.a)
    

    有效的预乘颜色总是有 color.rgb

    但 Android 不要求具有专用合成硬件的设备(如今几乎所有 Android 设备)在混合溢出时钳制到 1.0。大多数设备都有钳位功能,但 Nexus 10 中的 Exynos 5250 没有;它以 8 位定点进行混合数学运算,并在溢出时换行 (0xFF + 0x2 == 0x01)。如果 Note 2 中的 Exynos 4412 的行为方式相同,我不会感到惊讶。

    要解决此问题,您需要在帧末尾的帧缓冲区中包含有效的预乘颜色。许多应用程序,包括 Android UI 框架,通过确保预乘任何非透明输入(纹理、顶点颜色等)来做到这一点——之后大部分数学运算都会自动计算出来。如果你不能确保预乘输入,你可以添加

    gl_FragColor.rgb *= gl_FragColor.a;
    

    到片段着色器的末尾。如果您进行任何混合,则需要调整您使用的混合方程/因子。

    【讨论】:

      猜你喜欢
      • 2011-04-11
      • 1970-01-01
      • 2011-07-09
      • 2011-08-27
      • 2017-11-18
      • 2011-09-27
      • 2012-02-29
      • 1970-01-01
      • 2012-09-06
      相关资源
      最近更新 更多