使用 GFX rotozoomSurface 和 SDL 绘制透明精灵的正确方法是什么?

发布于 2024-08-10 02:17:50 字数 1032 浏览 4 评论 0原文

我在 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 程序可以正确打开它。

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

谷歌并没有出现太多,如果有一个可行的例子就太好了。

I'm using the latest SDL/GFX libs on Fedora 10 and I'm trying to render a PNG or GIF
image onto the screen surface. I could not get transparent PNG's to display at all
so I replaced the transparent parts or my sprite with all white (and tried Magenta
255,0,255). The white-transparent PNG displays fine using this code:

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 );

But when I try to rotate the sprite it does not drop all the white pixels. I replace the
above code with this to rotate:

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 );

I end up with a white outline around some of the good pixels. GIF images give the same results.

When trying with transparent PNG/GIF files the code was the same except I did not call SDL_SetColorKey. Then the PNG did not display properly at all. One strange thing I found was the transparent PNG looked the same in MS Paint as it did in SDL, but GIMP/Photoshop programs opened it correctly.

Is there something I'm missing setting up the destination surface?

Google did not turn up much, a working example would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

习惯成性 2024-08-17 02:17:50

我假设当您说“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);
}

稍后,在渲染循环中,您可以将源图像旋转某个浮点角度到某个 SDL_Surface < code>screen:

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

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

假设您在 Fedora 10 安装上使用 g++,请确保链接到 SDL_image 库的 -lSDL_image 和 SDL_gfx 库的 -lSDL_gfx 。您还可以使用 sdl-config --libs 作为 SDL 本身所需的 g++ 参数。

I am assuming that when you say "the latest SDL/GFX libs on Fedora 10," you mean the SDL and SDL_gfx libraries. To properly display PNG images with transparency, ensure that you also have SDL_image installed; you will need it, unless you have a different library that can load a PNG image into a SDL_Surface.

You should not need to use a color key for transparency (unless, of course, you want to use one). As for your problem with using a color key, note that the SDL documentation recommends setting the color key before calling SDL_DisplayFormat():

"If you want to take advantage of hardware colorkey or alpha blit acceleration, you should set the colorkey and alpha value before calling this function."

You might also want to try using SDL_DisplayFormatAlpha() instead of SDL_DisplayFormat(), like so:

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

Later, in your rendering loop, you can then rotate the source image by some floating point angle on to some SDL_Surface screen:

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

The above code will properly blit a PNG with transparency, assuming your PNG has proper transparency.

Make sure to link with -lSDL_image for the SDL_image library and -lSDL_gfx for the SDL_gfx library, assuming you are using g++ on your Fedora 10 installation. You can also use sdl-config --libs for the required g++ arguments for SDL itself.

铁憨憨 2024-08-17 02:17:50

只需关闭 Rotozoom 表面的抗锯齿功能,您就不会再遇到“轮廓问题”的麻烦了。

您使用了这个:SDL_Surface *roto = rotozoomSurface(image,rotation_ Degrees, 1, 1);

改为使用这个:SDL_Surface *roto = rotozoomSurface(image,rotation_ Degrees, 1, 0); code>

0 设置抗锯齿关闭。

Just turn off the anti-aliasing of the Rotozoomsurface, and you should no more have trouble with the 'out line issue'.

You used this : SDL_Surface *roto = rotozoomSurface(image, rotation_degrees, 1, 1);

Instead Use this: SDL_Surface *roto = rotozoomSurface(image, rotation_degrees, 1, 0);

0 sets the anti-aliasing off.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文