草庐IT

c++ - OpenGL 闪烁/损坏,窗口调整大小和 DWM 处于事件状态

coder 2023-05-03 原文

我有一个 wxWidgets 应用程序,它有许多子 opengl 窗口。我正在使用我自己的 GL Canvas 类,而不是 wx 类。窗口共享它们的 OpenGL 上下文。 我不认为它是 wxwidgets 的事实在这里真的很重要。

opengl 窗口是一个窗口的子窗口,它们是彼此的兄弟窗口,包含在选项卡控件中。一种 MDI 风格的界面,但它不是 MDI 窗口。每个都可以单独调整大小。除非启用 Aero 并且 DWM 处于事件状态,否则一切正常。

调整任何窗口(甚至是 opengl 窗口)的大小会导致所有 opengl 窗口偶尔闪烁,并出现陈旧的后备存储 View ,其中包含当时屏幕上出现的任何非 opengl 垃圾。这只发生在启用 Aero 的情况下。

我很确定这是 DWM 实际上在其绘图表面后备存储中没有 opengl 内容,并且窗口没有在正确的时刻重新绘制。

我已经尝试了很多方法来解决这个问题,我确实有一个解决方案,但它不是很好,它涉及将带有 glReadPixels 的帧缓冲区读取到 DIB 中,然后在我的 onPaint 例程中将其传送到绘图 DC。仅当 DWM 处于事件状态时才启用此解决方法,但我宁愿根本不必这样做,因为它会稍微损害性能(但在功能强大的系统上并不算太糟糕 - 场景是相对简单的 3d 图)。也不建议将 GDI 和 opengl 混合使用,但令人惊讶的是,这种方法很有效。我现在可以忍受它,但我宁愿不必。无论如何,如果我想截取子窗口的屏幕截图,我仍然必须在 WM_PRINT 中执行此操作,我看不到解决方法。

有人知道更好的解决方案吗?

在有人问之前,我肯定会做到以下几点:

  • 窗口类有 CS_OWNDC
  • WM_ERASEBACKGROUND 什么都不做并返回 TRUE。
  • 双缓冲已启用。
  • Windows 具有 WS_CLIPSIBLINGS 和 WS_CLIPCHILDREN 窗口样式。
  • 在我的 resize 事件处理程序中,我立即重新绘制窗口。

我试过了:

  • 在像素格式描述符中设置 PFD_SUPPORT_COMPOSITION。
  • 不在绘图处理程序中使用 wxPaintDC 并调用 ::ValidateRect(hwnd, NULL) 代替。
  • 处理 WM_NCPAINT 并排除客户区
  • 通过 DWM API 禁用 NC 绘制
  • 在绘制事件中排除客户区
  • 在缓冲区交换前后调用 glFlush 和/或 glFinish。
  • 在每次绘制事件时使窗口无效(作为测试!) - 仍然 闪烁!
  • 不使用共享的 GL 上下文。
  • 禁用双缓冲。
  • 写入 GL_FRONT_AND_BACK

禁用 DWM 不是一种选择。

据我所知,如果您在 OpenGL 上使用 Direct3D,这甚至是一个问题,尽管我没有对此进行测试,因为它代表了很多工作。

最佳答案

这是一个远射,但我刚刚自己解决了同样的问题。

出现长镜头部分是因为我们正在对围绕我们的 OpenGL 窗口的无标题组框的轮廓进行所有者绘制(即,制作一个漂亮的小边框),这可能无法描述您的情况。

我们发现问题是这样的:

我们一直在使用 RoundRect() 调用(带有 HOLLOW_BRUSH)来绘制组框的轮廓。将其更改为 MoveToEx() 和 LineTo() 调用以确保仅绘制线条并且在组框内没有任何操作可以防止 GDI 尝试意外地重绘控件的全部内容。无效逻辑可能存在差异(或者我们在加载预期的空心画笔时遇到了错误)。我们仍在调查中。

-诺埃尔

关于c++ - OpenGL 闪烁/损坏,窗口调整大小和 DWM 处于事件状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10615272/

有关c++ - OpenGL 闪烁/损坏,窗口调整大小和 DWM 处于事件状态的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

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

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

  3. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  4. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  5. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  6. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  7. 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.你能做的最好的事情是:

  8. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

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

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

  10. ruby-on-rails - 为模型创建状态属性 - 2

    我想为我的Task模型创建一个status属性,该属性将按以下顺序指示它在三部分进度中的位置:打开=>进行中=>完成。它的工作方式类似于亚马逊包裹的交付方式:已订购=>已发货=>已交付。我想知道设置此属性的最佳方法是什么。我可能是错的,但创建三个独立的bool属性似乎有点多余。实现此目标的最佳方法是什么? 最佳答案 Rails4有一个内置的enummacro.它使用单个整数列并映射到键列表。classOrderenumstatus:[:ordered,:shipped,:delivered]end状态映射如下:{ordered:0,

随机推荐