【问题标题】:How do I detect "invalid drawable" in Mac OS X?如何在 Mac OS X 中检测“无效的可绘制对象”?
【发布时间】:2013-04-10 20:47:23
【问题描述】:

我正在开发一个已有十多年历史的跨平台应用程序。 UI 由 Qt 完成,后端渲染由 OpenGL 完成。 OpenGL 上下文在后端管理,而不是由 Qt。

我最近为我们应用中的所有 OpenGL 代码添加了错误检查和报告功能。偶尔会出现这样的情况,即由 Qt 启动的第一次渲染会在终端中导致“无效的可绘制”错误消息,并且所有后续的 OpenGl 调用都会失败并报告“无效的帧缓冲区”错误。这些无效的可绘制错误消息在过去被视为无害的,因为在用户看到它之前,可绘制最终变得有效并且场景被正确渲染。但是,使用新的 OpenGL 错误检查/报告是不可能的,因为报告的错误数量很大。

我想测试drawable是否有效。如果不是,它应该在渲染开始之前返回。如何验证可绘制对象是否有效?

MacBook Pro、OS X Mountain Lion (10.8.3)、ati 显卡

【问题讨论】:

    标签: macos opengl ati


    【解决方案1】:

    我不知道您在哪个 API 级别工作。我不确定是否有可能在事后发现问题。也就是说,如果您只有一个无法连接到其可绘制对象的上下文(可能隐含为线程的当前上下文)。

    我认为 Qt 在后台使用 Cocoa。我进一步假设它已经创建了一个NSOpenGLContext 并在其上调用-setView:。如果在调用时视图的窗口没有窗口设备,则会出现“无效的可绘制”错误。

    一种常见的技术是推迟设置上下文的视图,直到视图调用了-drawRect:,因为此时您确定视图有一个窗口并且窗口有一个设备。 (尽管这忽略了在正常窗口显示机制之外强制绘制的可能性。例如,-cacheDisplayInRect:toBitmapImageRep:。)

    如果您只想在调用-setView: 时知道它是否安全,我认为您可以依靠检查[[view window] windowNumber] 的值。 -windowNumber 的文档说:

    如果窗口没有窗口设备,则返回值等于或小于0。

    另一种方法是预防而不是检测问题。其策略基本上是确保在调用-setView: 之前已显示并绘制了窗口。您可以通过在屏幕上订购并在其上调用 -display 来强制执行此操作。

    【讨论】:

    • 我们在底层使用 Cocoa 而不是 qt 使用它。是的,我想找到一种方法来测试无效的上下文。 [[view window] windowNumber] 有时有效,但并非所有时间。
    • 以哪种方式失败,误报还是误报?
    【解决方案2】:

    Ken Thomases 的帖子为我提供了找到可行解决方案所需的基本信息。需要一个额外的条件。这就是有效的方法

    //----------------------------------------------------------------------------
    bool vtkCocoaRenderWindow::IsDrawable()                                                                                                                                                                                                                                                                                                                   
    {
      // you must initialize it first
      // else it always evaluates false
      this->Initialize();
    
      // first check that window is valid
      NSView *theView = (NSView*)this->GetWindowId();
      bool win =[[theView window] windowNumber]>0;
    
      // then check that the drawable is valid
      NSOpenGLContext *context = (NSOpenGLContext *)this->GetContextId();
      bool ok  = [context view] != nil; 
      return win && ok;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-09
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 2011-08-20
      • 2011-01-13
      • 1970-01-01
      • 2010-10-07
      相关资源
      最近更新 更多