【问题标题】:Blit Queue Optimization AlgorithmBlit 队列优化算法
【发布时间】:2010-12-25 03:19:07
【问题描述】:

我希望实现一个管理 blit 队列的模块。有一个表面,这个表面的一部分(以矩形为界)被复制到表面内的其他地方:

add_blt(rect src, point dst);

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

这当然会因为重叠而变得棘手。 blit 可以重新 blit 先前复制的像素。理想情况下,blit 操作将在优化阶段进行细分,这样每个块都可以通过一次操作到达其最终位置。

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

我在网络上环顾四周,唯一发现的是SDL_BlitPool Library,它假定源表面与目标表面不同。它还做了很多繁重的工作,看似不必要:区域和类似的构建块是给定的。我正在寻找更高层次的东西。当然,我不会看在嘴里的礼物马,我也不介意做实际的工作......如果有人能提出一个基本的想法,让这个问题看起来没有那么复杂吗?现在,那也太棒了。

编辑:

想想 aaronasterling 的回答……这行得通吗?

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

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

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

    • srcrect 成为blt beng 检查的源矩形

    • srcrectmaster region的交集变成temp region

    • master region 中删除temp region,所以master region 不再覆盖temp region

    • srcrect提升为区域(srcrgn)并从中减去temp region

    • temp regionsrcrgn与当前blt的向量偏移:它们的联合将覆盖当前blt的目标区域

    • 添加到master regiontemp region中的所有矩形,保留原始源元数据(将当前blt添加到master region的第一步)

    • 添加到master regionsrcrgn中的所有rects,添加当前blt的源信息(将当前blt添加到master region的第二步)

      李>
  • 通过检查作为合并候选者的相邻子矩形是否具有相同的元数据来优化master region。如果(r1.x1 == r2.x1 && r1.x2 == r2.x2) | (r1.y1 == r2.y1 && r1.y2 == r2.y2),则两个子矩形是合并候选者。如果是,请将它们组合起来。

  • 枚举master region 的子矩形。返回的每个矩形都是一个优化的 blt 操作目标。关联的元数据是 blt 操作的源。

【问题讨论】:

    标签: c++ c algorithm graphics


    【解决方案1】:

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

    例如,开头为:

    并添加一个矩形:

    将解析为:

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

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

    【讨论】:

    • 感谢您对此感兴趣。但是,我认为您可能没有足够仔细地阅读该问题。 (或者也许我不够清楚,你认为我应该澄清吗?)你所描述的本质上是一个高效的区域处理库/API 所做的。我实际上打算依靠一个。真正的问题是所有这些矩形都移动到屏幕上的某个位置。 Rect1 将移动到 X1、Y1 和 Rect2 将移动到 X2、Y2 等。我要做的是检测有序移动操作本身中的任何重叠,并且只移动重叠块一次。
    • 问题是 Rect1 先移动,然后 Rect2 移动,等等。它们不会同时移动。如果 Rect2 的源与 Rect1 的目标重叠,它将复制它的一些位。同样,Rect3 的源可能与 Rect1 和 Rect2 的目标重叠,等等。
    • @martona 我看到了问题。我不是一个真正的图形专家,所以我误解了。我想我看到了解决方案,但我必须等到今晚晚些时候才能更新。
    • 您的回答尝试仍然启发了我。查看我对问题的编辑。
    【解决方案2】:

    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

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

    前 2bit 为 Y 轴,后 2bit 为 X 轴(在 SDL_BlitPool 中)。

    每个1bit的值就是MSB值。

    它看起来像......

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

    在这张图片中:MSB == 箭头方向。

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

    对不起我的英语水平。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-23
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多