【发布时间】:2018-04-09 01:32:25
【问题描述】:
我正在通过 OS X Sierra 上的 SDL2 2.0.7 和 SDL2_image 2.0.2 加载 32 位 RGBA 法线贴图纹理,高度图在 alpha 通道中编码。
这些纹理中的每个像素都有一个非零的 RGB 值,编码一个方向法向量。 (0, 0, 0) 的方向向量(即 black)无效。
然而,当我通过 SDL2_image 加载这样的纹理时,alpha 值为 0 的纹理区域也产生 0 的 RGB 值。我认为 SDL 可能是预乘 alpha这些像素的值?
附加的是这些法线贴图纹理之一。您可以通过打开纹理来确认它是有效的,例如GIMP 并在其中一个透明区域上使用颜色选择器。您会看到,实际上,透明区域仍然具有蓝色的 RGB 颜色(编码的法线向量)。
以下是说明附加 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 等静态链接。但按预期工作。
【问题讨论】: