4

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

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

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

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

4

2 回答 2

4

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

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

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

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

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

另一种方法是防止问题而不是检测问题。这样做的策略基本上是确保在调用-setView:. 您可以通过在屏幕上订购并调用-display它来强制执行此操作。

于 2013-04-10T21:24:44.937 回答
1

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;
}
于 2013-11-01T20:37:15.310 回答