【问题标题】:working with Cairo and Allegro 5使用 Cairo 和 Allegro 5
【发布时间】:2012-07-20 08:30:46
【问题描述】:

这里是新手程序员,

我正在使用 Allegro 5 设计一个 2d 游戏,我注意到在使用 allegro 中的位图(实际上是从 photoshop 导出的 png 文件...)时,旋转的图像看起来不太好:rotated meteor

左边的是原方向,右边的是旋转了10度。它们有点小,但边缘质量的差异很明显。

首先,我真的希望避免创建包含所有不同旋转位置的精灵表,原因如下:

我对流星和我正在创建的所有其他对象有不同的“效果”,这需要在对象周围发光。我将在每个对象周围应用至少 6 种不同的发光颜色。现在,这些流星中的每一个都需要旋转 30 帧才能显得平滑。假设我想要在游戏中像这样工作的区区 10 个不同的对象;仅针对这些对象就有 1800 个文件!

我宁愿专注于寻找一种更好的方式来显示旋转图像,而不是花时间去做。

我尝试过研究各种 Photoshop 技术,但我能想到的最好方法是让 Photoshop 中的圆圈稍微小一点,然后让它“发光”相同的灰色阴影,这可以解决旋转问题,但它会使流星看起来很模糊。

然后我进行了更多研究,发现 Allegro 5 中提供了各种混合选项。我尝试了 al_set_blender 中所有可能的选项 - 它们都没有解决锯齿状边缘的问题。

最后,我再次搜索如何处理这个问题并发现this post 关于 Allegro 5 中的抗锯齿功能。正如答案中指出的那样,有一个抗锯齿选项可用,但主要限制只有在将基元绘制到后台缓冲区时工作。实际上实现这将是大量的工作,而且每次都绘制所有必需的图元似乎效率很低。

然而,在另一篇文章中引起我注意的是这条评论:

顺便说一句,如果您不需要游戏的实时性能,您也可以连接到 libcairo 以绘制漂亮的矢量图形。 连接到 Allegro 非常简单,但仅此而已不同的主题。

所以我再次研究了图形库以及它们如何解决我的问题。我查看了 Cairo、SDL、Qt、ImageMagic 等,但最后我同意 Cairo 似乎是适合这项工作的工具。

最后我们得出这篇文章的原因:

我的问题是:如何将 Cairo 与 Allegro 5 “挂钩”?

现在,我还没有在 Cairo 上做过任何工作,所以我并没有被它束缚,但我想继续使用 Allegro,除非真的有充分的理由切换到其他东西。

Allegro 有一种简单直接的方式来创建显示并使用 allegro 命令对其进行绘图。但开罗有自己的处事方式,而且开罗似乎根本不管显示器。我可以想象两者一起工作的唯一方法是 Cairo 接收绘图命令,绘制图像,将图像保存为 png 文件,然后打开 allegro 函数并在该文件中读取 1 帧。这不可能是评论者的意思。

无论如何,请随意批评我的思维过程。我不会被冒犯的。如果有什么简单的你觉得我没看懂,请赐教。

【问题讨论】:

  • "只有在将基元绘制到后台缓冲区时才工作的主要限制" 嗯,你还要在哪里绘制它?您是否对位图进行了很多位图传输,然后再对其他位图进行位图传输?如果是这样,你不应该这样做。
  • 您需要询问如何解决您的原始问题(在单独的问题中)。为此,我们需要查看您用于渲染的实际代码是什么。你是本末倒置。
  • 对不起,我想我不应该对直接绘制图元如此挑剔。我只是觉得没有人这样做,因为它效率低下。我想我只是假设你有 A)每个可能的旋转度的大量精灵表 B)有边缘混合方法来平滑我仍然不知道的粗糙边缘。
  • 现在我只有 ALLEGRO_BITMAPs 是我的各个班级的成员。每一帧我都会循环遍历对象并绘制它们。就这么简单。
  • @NicolBolas 现在我只是尽可能地积极主动,在问题出现之前发现问题。如果你愿意回复它,我将给出一个详细的帖子,展示我目前如何使用代码示例绘制图形。请发表评论并告诉我。同样,清晰的图形对我来说很有价值,所以我想尽早适当考虑这个问题。

标签: c++ cairo allegro5


【解决方案1】:

Cairo 可以渲染到一块内存,可以将其转换为 Allegro 位图。然而,性能对于实时游戏来说是不可接受的。它对于绘制图表、将 SVG 图像加载到静态位图中等会更有用。抛开性能不谈,我看不出它对旋转位图有何帮助。

您所说的“抗锯齿”仅适用于原语。所以你链接到的那个问题是不相关的。如果在创建/加载旋转位图之前使用这些选项可能会有所帮助:

al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR | ALLEGRO_MIPMAP);

它们通常适用于缩放位图,但您的旋转可能符合条件。

最后,使用预乘 alpha(默认混合器)会给您带来更好的结果。

我刚刚用你的图片测试了这个:

#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>

int main()
{
  ALLEGRO_BITMAP *circle;

  al_init();
  al_init_image_addon();

  al_create_display(640, 480);

  al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR);

  circle = al_load_bitmap("circle.png");
  if (!circle) return 0;

  al_clear_to_color(al_map_rgb(0,0,0));
  al_draw_bitmap(circle, 100, 100, 0);

  al_draw_rotated_bitmap(circle, 25, 25, 200, 200, 0.174, 0);

  al_flip_display();

  al_rest(5);

  return 0;
}

我相信它会给你想要的外观。

【讨论】:

  • 感谢您的回复。尽管我没有看到改进,但我实现了此代码。也许我不清楚:我为帖子上传的图片只是我截取的截图的一部分。我使用的实际图像只有 50X50 像素,形状(角)之外的区域是透明的。
  • 看来我可能对如何获得我正在寻找的东西有错误的想法(请参阅上面的 cmets),但感谢您的帮助
  • 是的,我使用了 50x50 的圆形 PNG 图片。您可能还想添加ALLEGRO_MAG_LINEARALLEGRO_MIPMAP。上面的代码在 OpenGL (Ubuntu) 上进行了测试,并提供了非常显着的质量改进。如果您在 Windows 上,您将默认使用 D3D,这可能会有所不同。
  • 有效!!!我没有意识到也可以添加位图标志,现在我的边缘更平滑了。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2013-08-13
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
相关资源
最近更新 更多