C++ 与Cairo和Allegro 5合作

C++ 与Cairo和Allegro 5合作,c++,cairo,allegro5,C++,Cairo,Allegro5,这里是新手程序员 我正在使用Allegro 5设计一个2d游戏,我注意到在Allegro中使用位图(实际上是从photoshop导出的png文件…)时,旋转的图像看起来不像恒星: 左侧的一个处于原始方向,右侧的一个旋转10度。它们有点小,但边缘质量的差异很明显 首先,我真的希望避免创建包含所有不同旋转位置的精灵图纸,原因如下: 我有不同的“效果”发生在流星和我正在创建的所有其他物体上,这些物体周围需要发光。我将在每个对象周围应用至少6种不同的发光颜色。现在,这些流星中的每一颗都需要30帧的旋转才

这里是新手程序员

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

左侧的一个处于原始方向,右侧的一个旋转10度。它们有点小,但边缘质量的差异很明显

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

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

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

我曾尝试研究过各种photoshop技术,但我能想到的最好办法是在photoshop中使圆圈稍微变小,然后使其“发光”相同的灰色阴影,这在某种程度上解决了旋转问题,但它使流星看起来模糊

然后我做了更多的研究,发现Allegro 5中有各种混合选项。我已经在al_set_blender中尝试了所有可能的选项-没有一个解决锯齿边缘的问题


最后,我再次搜索了如何处理这个问题,并发现了Allegro 5中的抗锯齿功能。正如回答中所指出的,有一个抗锯齿选项可用,但主要限制是仅在将基本体绘制到后缓冲区时工作。实际上,实现这一点需要大量的工作,而且每次绘制所有必需的原语似乎效率很低

然而,在另一篇帖子中引起我注意的是以下评论:

另外,如果你不需要游戏的实时性能,你也可以连接到libcairo来绘制好看的矢量图形。连接到Allegro非常简单,但这是另一个主题

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

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

我的问题是:我怎样才能把开罗“勾入”到快板5中去?

现在,我还没有在Cairo上做过任何工作,所以我不受它的束缚,但我想继续使用Allegro,除非有很好的理由切换到其他东西

Allegro有一种简单而直接的方法,可以使用Allegro命令创建显示和绘图。但是Cairo有自己的做事方式,而且看起来Cairo根本不管理展示。我能想象的唯一方法是,Cairo接收绘图命令,绘制图像,将图像保存为png文件,然后打开allegro函数并在该文件中读取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;
}
#包括
#包括
int main()
{
快板位图*圆圈;
al_init();
al_init_image_addon();
al_创建_显示(640480);
设置新位图标志(快板线性);
圆圈=加载位图(“circle.png”);
如果(!circle)返回0;
al_clear_to_color(al_map_rgb(0,0,0));
绘制位图(圆形,100,100,0);
al_绘制旋转位图(圆形,25,25,200,200,0.174,0);
al_flip_display();
al_rest(5);
返回0;
}

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

“主要限制是只在将原语绘制到后缓冲区时工作”嗯,你还打算在哪里绘制它?您是否对位图进行了大量的blit,然后将其blit到其他位图?如果是这样,你就不应该这样。你需要问如何解决你原来的问题(在一个单独的问题中)。要做到这一点,我们需要了解您用于渲染的实际代码是什么。你是本末倒置。对不起,我想我不应该对直接绘制原语如此挑剔。我的印象是,没有人这样做,因为它效率低下。我猜我只是假设你有A)对于每一个可能的旋转度都有巨大的精灵片B)有一些边缘混合方法来平滑粗糙的边缘,但我还不知道。现在我只有ALLEGRO_位图,它们是我的各个类的成员。每一帧我都在对象中循环并绘制它们。这一点很简单。@Nicolas Bolas现在我只是尽量主动,在问题出现之前找出问题。如果你愿意回应,我将给出一个详细的帖子,展示我目前如何用代码示例绘制图形。请评论并让我知道。再说一遍,沙尔