gpt4 book ai didi

c - 在 OS X 上加载表面时 SDL2 预乘 alpha channel ?

转载 作者:行者123 更新时间:2023-12-01 13:28:59 30 4
gpt4 key购买 nike

我正在通过 OS X Sierra 上的 SDL2 2.0.7 和 SDL2_image 2.0.2 加载 32 位 RGBA 法线贴图纹理,以及在 alpha channel 中编码的高度图。

这些纹理中的每个像素都有一个非零的 RGB 值,编码一个方向法 vector 。 (0, 0, 0) 的方向 vector (即 black)无效。

然而,当我通过 SDL2_image 加载这样的纹理时,纹理的 alpha 值为 0 的区域产生 RGB 值 0。我认为 SDL 可能预乘 alpha这些像素的值?

附件是这些法线贴图纹理之一。您可以通过打开纹理来确认它是有效的,例如GIMP 并在其中一个透明区域上使用颜色选择器。您会看到,实际上,透明区域仍然具有偏蓝的 RGB 颜色(编码的法 vector )。

32 bit RGBA normalmap with alpha-encoded heightmap for parallax mapping

下面是一个最小的测试用例,说明了附加的 PNG 文件的问题:

#include <SDL_image.h>
#include <assert.h>

int main(int argc, char **argv) {

SDL_Surface *s = IMG_Load("green3_2_nm.png");
assert(s);

for (int i = 0; i < s->w * s->h; i++) {
const Uint32 *in = (Uint32 *) (s->pixels + i * s->format->BytesPerPixel);

SDL_Color color;
SDL_GetRGBA(*in, s->format, &color.r, &color.g, &color.b, &color.a);

assert(color.r || color.g || color.b);
}

SDL_FreeSurface(s);

return 0;
}

我正在使用 gcc $(pkg-config --cflags --libs sdl2_image) test.c

编译这个测试用例

第 15 行的断言将使图像中的几行失败——即 alpha 值恰好下降到 0 的地方。

我已经尝试过 TGA 和 PNG 图像格式,但 SDL 对这两种图像格式都做同样的事情。

这是 SDL 中的错误,还是我遗漏了什么?我很好奇人们是否也在其他平台上看到了同样的问题。

===

答案:Core Graphics,Apple OS X 上 SDL2_image 的默认图像加载后端,确实预乘 alpha -- 总是。解决方案是在没有 Core Graphics 支持的情况下重新编译 SDL2_image,而是启用 libpng、libjpeg 和您需要的任何其他图像编解码器:

./configure \
--disable-imageio \
--disable-png-shared \
--disable-tif-shared \
--disable-jpg-shared \
--disable-webp-shared

在我的系统上,我必须禁用 Core Graphics (imageio)以及其他编解码器的共享库加载,如您所见。这产生了一个胖的 SDL2_image.so,它静态链接到 libpng、libjpg 等。但按预期工作。

最佳答案

SDL_image 是特定于平台的图像加载代码的包装器,而不是在所有平台上使用相同的图像加载器。

  • Linux:LibPNG、LibJPEG
  • macOS、iOS:核心图形
  • window :WinCodec

这具有减少 SDL_image 大小的优势,因为它不必附带任何图像解码代码,而是可以动态链接到可能已经安装在您的系统上的东西。但是,在 macOS 和 iOS 上,Core Graphics 不支持非预乘 alpha,因此 SDL_image 必须将其反转。

参见:mac-opengl - Re: kCGImageAlphaFirst not implemented (Was: (no subject))从 2007 年 5 月开始(来自 Wayback 机器):

Honestly, I wouldn't expect CGBitmapContextCreate() to support non- premultiplied alpha any time soon.

...

I'm not sure if using ImageIO + CoreGraphics was ever really targetted at being used for an image loading scheme for OpenGL applications.

此行为是在 LibSDL bug #838 - OSX SDL darkens colours proportional to increase in alpha 中发现的并且在 SDL_image changeset 240 中引入了解决方法.

您可以看到解决方法只是取消预乘 alpha,这是一个非常有损的过程。

为了解决这个问题,您可以在使用 LibPNG 的 macOS 上构建您自己的 SDL_image 版本。这应该可以通过配置来实现,您不必对 SDL_image 代码本身进行任何更改。为此,请使用 --disable-imageio 选项。 SDL_image 附带了自己的 LibPNG 代码副本,因此您无需安装 LibPNG 即可使其正常工作。

关于c - 在 OS X 上加载表面时 SDL2 预乘 alpha channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46975125/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com