如何使用索引 PNG 图像作为 SDL2/OpenGL 的纹理

How do I use an indexed PNG image as a texture for SDL2/OpenGL

我的加载图像代码似乎适用于 24 位和 32 位图像。我使用 SDL2_image:

加载图像
// Snip cruft above
if((surface = IMG_Load(filename.c_str())) == NULL) {
    error = "Unable to load file: " + filename;
    throw error.c_str();
}


// get the number of channels in the SDL surface
nOfColors = surface->format->BytesPerPixel;

if (nOfColors == 4) {    // contains an alpha channel
    if (surface->format->Rmask == 0x000000ff)
        texture_format = GL_RGBA;
    else
        texture_format = GL_BGRA;
} else if (nOfColors == 3) {    // no alpha channel
    if (surface->format->Rmask == 0x000000ff)
        texture_format = GL_RGB;
    else
        texture_format = GL_BGR;
} else {
    error = "error: the image is not truecolor..  this will probably break (" + filename + " contains " + std::to_string(nOfColors) + " bytes per pixel)";
    throw error.c_str();
}
// snip OpenGL stuff below

nOfColors 仅包含值 1,因为 PNG 被保存为索引颜色 space。 GIMP 可以很好地打开文件,包括一个 alpha 通道。

如何将表面转换为真彩色纹理以便在 OpenGL 四边形上使用它进行渲染?

如果这不可能(或不切实际),我该如何将 PNG 保存为带有 alpha 通道的真彩色图像。我试过 ImageMagick:

convert image.png -depth 32 image.png

但图像似乎仍保存为索引彩色图像

作为一些额外的背景信息 - 该程序与 SDL1.2 一起工作,但在移植到 SDL2 后停止工作。我已将其他所有内容更新为 SDL2,但 SDL2_image 工作方式可能发生了我不知道的变化。

在 ImageMagick 奇怪的语言下,索引图像只是 "color type" 数字 3(调色板)。

因此,要使用转换命令生成不带调色板的 png,您必须:

convert -type TrueColorAlpha image_in.png image_out.png

您可以强制 ImageMagick 创建 32 位图像(即每个通道 8 位加上 alpha),如下所示:

convert image.png PNG32:image.png

只需使用 SDL_ConvertSurfaceFormat()...

将其转换为正确的格式
SDL_Surface *image = ...;
SDL_Surface *converted = SDL_ConvertSurfaceFormat(
    image, SDL_PIXELFORMAT_ARGB8888, 0);