Blit队列优化算法

时间:2010-12-25 03:19:08

标签: c++ c algorithm graphics

我正在寻找一个管理blit队列的模块。有一个表面,这个表面的一部分(由矩形界定)被复制到表面的其他地方:

add_blt(rect src, point dst);

可以按顺序将任意数量的操作发布到队列中。最终,队列的用户将停止发布blits,并要求在表面上实际执行一组最佳操作。该模块的任务是确保不会不必要地复制像素。

由于当然重叠,这很棘手。一个blit可以重新闪现之前复制的像素。理想情况下,blit操作将在优化阶段进行细分,使每个块通过单个操作进入最终位置。

把它放在一起很棘手但并非不可能。我只是想重新发明轮子。

我在'网上看了看,我发现的唯一的东西是SDL_BlitPool Library,它假设源表面与目的地不同。它也做了很多繁重的工作,似乎是不必要的:区域和类似的构建块是给定的。我正在寻找更高级别的东西。当然,我不会在口中看到礼物马,我也不介意做实际的工作......如果有人能提出一个基本的想法,使这个问题看起来不那么复杂吧现在,那也很棒。

编辑:

考虑aaronasterling的答案......这可行吗?

  • 实现自定义区域处理程序代码,该代码可以维护其包含的每个矩形的元数据。当区域处理程序拆分矩形时,它会自动将此矩形的元数据与生成的子矩形相关联。

  • 优化运行开始时,创建一个由上述自定义代码处理的空白区域,将其称为master region

  • 遍历blt队列,并为每个条目:

    • srcrect成为blt审核的源矩形

    • 获取srcrectmaster regiontemp region的交集

    • temp region移除master region,因此master region不再涵盖temp region

    • srcrect推广到某个地区(srcrgn)并从中减去temp region

    • 使用当前temp region的向量抵消srcrgnblt:他们的联盟将覆盖当前blt的目标区域

      < / LI>
    • master region中添加temp region所有内容,保留原始来源元数据(将当前blt添加到master region)的第一步

    • master region添加srcrgn所有内容,添加当前blt的源信息(将当前blt添加到{{}的第二步1}})

  • 通过检查作为合并候选的相邻子矩形是否具有相同的元数据来优化master region。如果master region,则两个子矩形是合并候选者。如果是,请将它们合并。

  • 枚举(r1.x1 == r2.x1 && r1.x2 == r2.x2) | (r1.y1 == r2.y1 && r1.y2 == r2.y2)的子矩形。返回的每个矩形都是优化的blt操作目标。关联的元数据是blt操作的源。

2 个答案:

答案 0 :(得分:2)

我想到的一个想法是存储正在添加到四叉树中的矩形的定义点(或者在其他一些能够实现有效碰撞检测的结构中)。所以现在当你添加一个新的矩形时,你可以测试它是否有碰撞。这个想法是当一个新的矩形与一个旧的矩形碰撞时,你可以通过将旧的矩形分成4个,3个或2个新的矩形来解决碰撞,这些矩形不包括与新添加的矩形相交的部分。我们知道旧矩形没有与任何其他旧矩形相交,因此,因为新创建的矩形包含在其中,我们知道它们不会相互交叉,因此您不必对它们执行碰撞检测。

例如,从:

开始

alt text

并添加一个矩形:

alt text

将解决:

alt text

在这里,其中一个旧矩形被分成两个新的矩形,另一个被分成三个。

这保证了在添加新矩形后,队列始终处于没有交叉的状态,这意味着复制这些矩形不会复制像素两次。

答案 1 :(得分:1)

SDL_BlitPool ..啊,我早期的工作。

BlitPool的方式是

for_each(down to up) {
 if (overlapped) {
  1 split back-surface
   1-1 calculate overlap code
   1-2 add sub-rectangle (use overlap code)
   1-3 delete divided-surface
 }
}

基本上就是这样。

“重叠代码”是0-15整数。

你知道,重叠模式只有16种模式。

http://bitbucket.org/sharow/sdl_blitpool/src/ea6c02fef26f/resource/SDL_BlitPool_02.png

重叠代码为4位(0-15)值。

前2bit是Y轴,尾2bit是X轴(在SDL_BlitPool中)。

每个1位值只是MSB值。

它可视化......

http://bitbucket.org/sharow/sdl_blitpool/src/ea6c02fef26f/resource/SDL_BlitPool_01.png

此图片中的

:MSB ==箭头方向。

我认为有另一个更好的图书馆。 嗯我想改写它......

抱歉我的英语水平。