草庐IT

c++ - Blit 队列优化算法

coder 2024-02-23 原文

我正在寻求实现一个管理 blit 队列的模块。有一个表面,该表面的部分(由矩形包围)被复制到表面内的其他地方:

add_blt(rect src, point dst);

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

当然,由于重叠,这变得棘手。 blit 可以重新 blit 先前复制的像素。理想情况下,blit 操作将在优化阶段进行 segmentation ,这样每个 block 都可以通过单个操作到达其最终位置。

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

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

编辑:

考虑 aaronasterling 的回答……这行得通吗?

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

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

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

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

    • 获取srcrectmaster region的交集到temp region

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

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

    • 用当前blt的 vector 偏移temp regionsrcrgn:它们的并集将覆盖当前的目标区域blt

    • 添加到 master region temp region 中的所有 rect,保留原始源元数据(第一步添加当前 bltmaster 区域)

    • Add to master region all rects in srcrgn,添加当前blt的源信息(第二步添加当前 bltmaster 区域)

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

  • 枚举主区域的子矩形。返回的每个矩形都是优化的 blt 操作目标。关联的元数据是 blt 操作的来源。

最佳答案

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

例如,开始于:

并添加一个矩形:

将解决:

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

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

关于c++ - Blit 队列优化算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4529170/

有关c++ - Blit 队列优化算法的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 分布式事务和队列,ruby,erlang,scala - 2

    我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和

  3. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  6. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  7. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  8. ruby-on-rails - Ruby 长时间运行的进程对队列事件使用react - 2

    我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby​​脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几

  9. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  10. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

    我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

随机推荐