我正在开发一个十多年前的跨平台应用程序。UI使用Qt,后端渲染使用OpenGL完成。OpenGL上下文在后端管理,而不是由Qt管理。
我最近在我们的应用程序中添加了所有OpenGL代码的错误检查和报告。偶尔会出现这样的情况,即Qt启动的第一次渲染在终端中导致"无效绘制"错误消息,并且所有随后的OpenGL调用都失败并报告"无效framebuffer"错误。这些无效的可绘制错误信息在过去被认为是无害的,因为在用户看到它之前,可绘制最终变得有效并且场景被正确渲染。然而,使用新的OpenGL错误检查/报告,这是不可能的,因为有大量的错误报告。
我想测试drawable是否有效。如果不是,它应该在渲染开始之前返回。我如何验证绘制是有效的?
MacBook Pro, OS X Mountain Lion (10.8.3), ati显卡
我不知道你在什么API级别工作。我不确定是否有可能在事后发现问题。也就是说,如果你只有一个上下文(可能隐式为线程的当前上下文),无法连接到它的可绘制的。
我假定Qt在底层使用Cocoa。我进一步假设它已经创建了一个NSOpenGLContext
,并在其上调用-setView:
。如果在调用时,视图的窗口没有窗口设备,你会得到"invalid drawable"错误。
一个常见的技术是推迟设置上下文的视图,直到视图有-drawRect:
调用,因为在那一点上你确定视图有一个窗口,窗口有一个设备。(尽管这忽略了在正常窗口显示机制之外强制绘图的可能性。例如:-cacheDisplayInRect:toBitmapImageRep:
.)
如果你只是想知道在调用-setView:
时它是否安全,我认为你可以依靠检查[[view window] windowNumber]
的值。-windowNumber
的文档说:
如果窗口没有窗口设备,返回的值将等于或小于0。
另一种方法是预防问题而不是发现问题。这样做的策略基本上是确保在调用-setView:
之前窗口已经显示和绘制。您可以通过在屏幕上对其排序并调用-display
来强制执行。
Ken thomas的帖子给了我找到可行解决方案所需的基本信息。需要附加一个条件。下面是有效的
//----------------------------------------------------------------------------
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;
}