1

我在 Fedora 10 上使用最新的 SDL/GFX 库,并尝试将 PNG 或 GIF 图像渲染到屏幕表面。我根本无法显示透明的 PNG,所以我用全白色替换了透明部分或我的精灵(并尝试了洋红色 255,0,255)。使用以下代码可以很好地显示白色透明 PNG:

SDL_Surface *image = load_image("sprite-white.png");
SDL_Surface *roto = SDL_DisplayFormat(image);
SDL_SetColorKey(roto, SDL_SRCCOLORKEY, SDL_MapRGB( roto->format, 255,255,255 ));
SDL_BlitSurface( roto, NULL, surface, &offset );

但是当我尝试旋转精灵时,它不会丢弃所有的白色像素。我用这个替换上面的代码来旋转:

SDL_Surface *image = load_image("sprite-white.png");
SDL_Surface *roto = rotozoomSurface(image,  rotation_degrees, 1, 1);
SDL_Surface *roto2 = SDL_DisplayFormat(roto);
SDL_SetColorKey(roto2, SDL_SRCCOLORKEY, SDL_MapRGB( roto2->format, 255,255,255 ));
SDL_BlitSurface( roto2, NULL, surface, &offset );

我最终在一些好的像素周围出现了一个白色轮廓。GIF 图像给出相同的结果。

尝试使用透明 PNG/GIF 文件时,代码是相同的,只是我没有调用 SDL_SetColorKey。然后PNG根本没有正确显示。我发现的一件奇怪的事情是透明 PNG 在 MS Paint 中看起来与在 SDL 中相同,但 GIMP/Photoshop 程序正确打开了它。

我在设置目标表面时缺少什么吗?

谷歌没有出现太多,一个可行的例子会很棒。

4

2 回答 2

2

我假设当您说“Fedora 10 上的最新 SDL/GFX 库”时,您指的是 SDL 和 SDL_gfx 库。要正确显示具有透明度的 PNG 图像,请确保您还安装了SDL_image;您将需要它,除非您有一个不同的库可以将 PNG 图像加载到 SDL_Surface 中。

您不需要为透明度使用颜色键(当然,除非您使用一个)。至于您使用颜色键的问题,请注意 SDL 文档建议在调用 SDL_DisplayFormat() 之前设置颜色键:

“如果你想利用硬件 colorkey 或 alpha blit 加速,你应该在调用这个函数之前设置 colorkey 和 alpha 值。”

您可能还想尝试使用 SDL_DisplayFormatAlpha() 而不是 SDL_DisplayFormat(),如下所示:

SDL_Rect imagePosition = { 50, 50, 0, 0 };
SDL_Surface *image = IMG_Load("example.png");
if (image != NULL) {
  image = SDL_DisplayFormatAlpha(image);
}

稍后,在您的渲染循环中,您可以将源图像旋转某个浮点数angle到某个 SDL_Surface screen

if (image != NULL) {
  SDL_Surface *rotation = rotozoomSurface(image, angle, 1, 1);
  SDL_BlitSurface(rotation, NULL, screen, &imagePosition);
  SDL_FreeSurface(rotation);
}

假设您的 PNG 具有适当的透明度,上面的代码将正确地用透明度对 PNG 进行 blit。

确保链接-lSDL_image到 SDL_image 库和-lSDL_gfxSDL_gfx 库,假设您在 Fedora 10 安装中使用 g++。您还可以使用sdl-config --libsSDL 本身所需的 g++ 参数。

于 2009-12-02T06:56:59.763 回答
0

只需关闭 Rotozoomsurface 的抗锯齿功能,您就不会再遇到“外线问题”的问题了。

你用这个:SDL_Surface *roto = rotozoomSurface(image, rotation_degrees, 1, 1);

而是使用这个:SDL_Surface *roto = rotozoomSurface(image, rotation_degrees, 1, 0);

0 关闭抗锯齿。

于 2012-08-06T10:41:21.180 回答